co.cask.cdap.data.view.MDSViewStore.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.cdap.data.view.MDSViewStore.java

Source

/*
 * Copyright  2015 Cask Data, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package co.cask.cdap.data.view;

import co.cask.cdap.api.dataset.DatasetDefinition;
import co.cask.cdap.api.dataset.DatasetProperties;
import co.cask.cdap.api.dataset.table.Table;
import co.cask.cdap.common.NotFoundException;
import co.cask.cdap.common.conf.Constants;
import co.cask.cdap.data2.datafabric.dataset.DatasetsUtil;
import co.cask.cdap.data2.dataset2.DatasetFramework;
import co.cask.cdap.data2.dataset2.lib.table.MDSKey;
import co.cask.cdap.data2.transaction.Transactions;
import co.cask.cdap.proto.Id;
import co.cask.cdap.proto.ViewDetail;
import co.cask.cdap.proto.ViewSpecification;
import co.cask.tephra.TransactionExecutor;
import co.cask.tephra.TransactionExecutorFactory;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;

import java.util.List;

/**
 * Default implementation of {@link ViewStore}.
 */
public final class MDSViewStore implements ViewStore {

    private static final Id.DatasetInstance STORE_DATASET_ID = Id.DatasetInstance.from(Id.Namespace.SYSTEM,
            Constants.AppMetaStore.TABLE);
    private static final String TYPE_STREAM_VIEW = "stream.view";

    private final TransactionExecutorFactory executorFactory;
    private final DatasetFramework datasetFramework;

    @Inject
    public MDSViewStore(final DatasetFramework datasetFramework, TransactionExecutorFactory executorFactory) {
        this.datasetFramework = datasetFramework;
        this.executorFactory = executorFactory;
    }

    private <T> T execute(TransactionExecutor.Function<ViewMetadataStoreDataset, T> func) {
        try {
            Table table = DatasetsUtil.getOrCreateDataset(datasetFramework, STORE_DATASET_ID, "table",
                    DatasetProperties.EMPTY, DatasetDefinition.NO_ARGUMENTS, null);
            ViewMetadataStoreDataset viewDataset = new ViewMetadataStoreDataset(table);
            TransactionExecutor txExecutor = Transactions.createTransactionExecutor(executorFactory, viewDataset);
            return txExecutor.execute(func, viewDataset);
        } catch (Exception e) {
            throw new RuntimeException(String.format("Error accessing %s table", Constants.Stream.View.STORE_TABLE),
                    e);
        }
    }

    @Override
    public boolean createOrUpdate(final Id.Stream.View viewId, final ViewSpecification spec) {
        return execute(new TransactionExecutor.Function<ViewMetadataStoreDataset, Boolean>() {
            @Override
            public Boolean apply(ViewMetadataStoreDataset mds) throws Exception {
                boolean created = !mds.exists(getKey(viewId));
                mds.write(getKey(viewId), new StreamViewEntry(viewId, spec));
                return created;
            }
        });
    }

    @Override
    public boolean exists(final Id.Stream.View viewId) {
        return execute(new TransactionExecutor.Function<ViewMetadataStoreDataset, Boolean>() {
            @Override
            public Boolean apply(ViewMetadataStoreDataset mds) throws Exception {
                return mds.exists(getKey(viewId));
            }
        });
    }

    @Override
    public void delete(final Id.Stream.View viewId) throws NotFoundException {
        boolean notFound = execute(new TransactionExecutor.Function<ViewMetadataStoreDataset, Boolean>() {
            @Override
            public Boolean apply(ViewMetadataStoreDataset mds) throws Exception {
                if (!mds.exists(getKey(viewId))) {
                    return true;
                }
                mds.deleteAll(getKey(viewId));
                return false;
            }
        });

        if (notFound) {
            throw new NotFoundException(viewId);
        }
    }

    @Override
    public List<Id.Stream.View> list(final Id.Stream streamId) {
        List<StreamViewEntry> entries = execute(
                new TransactionExecutor.Function<ViewMetadataStoreDataset, List<StreamViewEntry>>() {
                    @Override
                    public List<StreamViewEntry> apply(ViewMetadataStoreDataset mds) throws Exception {
                        return Objects.firstNonNull(
                                mds.<StreamViewEntry>list(getKey(streamId), StreamViewEntry.class),
                                ImmutableList.<StreamViewEntry>of());
                    }
                });

        ImmutableList.Builder<Id.Stream.View> builder = ImmutableList.builder();
        builder.addAll(Collections2.transform(entries, new Function<StreamViewEntry, Id.Stream.View>() {
            @Override
            public Id.Stream.View apply(StreamViewEntry input) {
                return input.getId();
            }
        }));
        return builder.build();
    }

    @Override
    public ViewDetail get(final Id.Stream.View viewId) throws NotFoundException {
        StreamViewEntry entry = execute(
                new TransactionExecutor.Function<ViewMetadataStoreDataset, StreamViewEntry>() {
                    @Override
                    public StreamViewEntry apply(ViewMetadataStoreDataset mds) throws Exception {
                        if (!mds.exists(getKey(viewId))) {
                            return null;
                        }
                        return mds.get(getKey(viewId), StreamViewEntry.class);
                    }
                });
        if (entry == null) {
            throw new NotFoundException(viewId);
        }
        return new ViewDetail(viewId.getId(), entry.getSpec());
    }

    private MDSKey getKey(Id.Stream id) {
        return new MDSKey.Builder().add(TYPE_STREAM_VIEW, id.getNamespaceId(), id.getId()).build();
    }

    private MDSKey getKey(Id.Stream.View id) {
        return new MDSKey.Builder().add(TYPE_STREAM_VIEW, id.getNamespaceId(), id.getStreamId(), id.getId())
                .build();
    }

    private static final class StreamViewEntry {
        private final Id.Stream.View id;
        private final ViewSpecification spec;

        private StreamViewEntry(Id.Stream.View id, ViewSpecification spec) {
            this.id = id;
            this.spec = spec;
        }

        public Id.Stream.View getId() {
            return id;
        }

        public ViewSpecification getSpec() {
            return spec;
        }
    }
}