co.cask.cdap.data2.metadata.system.AbstractSystemMetadataWriter.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.cdap.data2.metadata.system.AbstractSystemMetadataWriter.java

Source

/*
 * Copyright  2016 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.data2.metadata.system;

import co.cask.cdap.api.plugin.PluginClass;
import co.cask.cdap.data2.metadata.dataset.MetadataDataset;
import co.cask.cdap.data2.metadata.indexer.SchemaIndexer;
import co.cask.cdap.data2.metadata.store.MetadataStore;
import co.cask.cdap.proto.Id;
import co.cask.cdap.proto.metadata.MetadataScope;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * A class to write {@link MetadataScope#SYSTEM} metadata for an {@link Id.NamespacedId entity}.
 */
public abstract class AbstractSystemMetadataWriter implements SystemMetadataWriter {

    protected static final String SCHEMA_FIELD_PROPERTY_PREFIX = "schema";
    protected static final String PLUGIN_KEY_PREFIX = "plugin";
    protected static final String PLUGIN_VERSION_KEY_PREFIX = "plugin-version";
    protected static final String TTL_KEY = "ttl";
    protected static final String DESCRIPTION = "description";
    protected static final String CREATION_TIME = "creation-time";

    // The following system properties should not get removed on metadata update
    // since they are not part of entity properties
    protected static final Set<String> PRESERVE_PROPERTIES = ImmutableSet.of(CREATION_TIME, DESCRIPTION);

    private final MetadataStore metadataStore;
    private final Id.NamespacedId entityId;

    public AbstractSystemMetadataWriter(MetadataStore metadataStore, Id.NamespacedId entityId) {
        this.metadataStore = metadataStore;
        this.entityId = entityId;
    }

    /**
     * Define the {@link MetadataScope#SYSTEM system} metadata properties to add for this entity.
     *
     * @return A {@link Map} of properties to add to this {@link Id.NamespacedId entity} in {@link MetadataScope#SYSTEM}
     */
    protected abstract Map<String, String> getSystemPropertiesToAdd();

    /**
     * Define the {@link MetadataScope#SYSTEM system} tags to add for this entity.
     *
     * @return an array of tags to add to this {@link Id.NamespacedId entity} in {@link MetadataScope#SYSTEM}
     */
    protected abstract String[] getSystemTagsToAdd();

    /**
     * Define the {@link MetadataScope#SYSTEM system} schema to add for this entity.
     *
     * @return the schema as a {@link String}
     */
    @Nullable
    protected String getSchemaToAdd() {
        return null;
    }

    /**
     * Updates the {@link MetadataScope#SYSTEM} metadata for this {@link Id.NamespacedId entity}.
     */
    @Override
    public void write() {
        // Delete existing system metadata before writing new metadata
        Set<String> existingProperties = metadataStore.getProperties(MetadataScope.SYSTEM, entityId).keySet();
        Sets.SetView<String> removeProperties = Sets.difference(existingProperties, PRESERVE_PROPERTIES);
        if (!removeProperties.isEmpty()) {
            String[] propertiesArray = removeProperties.toArray(new String[removeProperties.size()]);
            metadataStore.removeProperties(MetadataScope.SYSTEM, entityId, propertiesArray);
        }
        metadataStore.removeTags(MetadataScope.SYSTEM, entityId);

        // Now add the new metadata
        Map<String, String> properties = getSystemPropertiesToAdd();
        if (properties.size() > 0) {
            metadataStore.setProperties(MetadataScope.SYSTEM, entityId, properties);
        }
        String[] tags = getSystemTagsToAdd();
        if (tags.length > 0) {
            metadataStore.addTags(MetadataScope.SYSTEM, entityId, tags);
        }
        // if there is schema property then set that while providing schema indexer
        if (!Strings.isNullOrEmpty(getSchemaToAdd())) {
            metadataStore.setProperties(MetadataScope.SYSTEM, entityId,
                    ImmutableMap.of(SCHEMA_FIELD_PROPERTY_PREFIX, getSchemaToAdd()), new SchemaIndexer());
        }
    }

    protected void addPlugin(PluginClass pluginClass, @Nullable String version,
            ImmutableMap.Builder<String, String> properties) {
        String name = pluginClass.getName();
        String type = pluginClass.getType();
        // Need both name and type in the key because two plugins of different types could have the same name.
        // However, the composite of name + type is guaranteed to be unique
        properties.put(PLUGIN_KEY_PREFIX + MetadataDataset.KEYVALUE_SEPARATOR + name
                + MetadataDataset.KEYVALUE_SEPARATOR + type, name + MetadataDataset.KEYVALUE_SEPARATOR + type);
        if (version != null) {
            properties.put(
                    PLUGIN_VERSION_KEY_PREFIX + MetadataDataset.KEYVALUE_SEPARATOR + name
                            + MetadataDataset.KEYVALUE_SEPARATOR + type,
                    name + MetadataDataset.KEYVALUE_SEPARATOR + version);
        }
    }
}