/* * 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.internal.api; import co.cask.cdap.api.DatasetConfigurer; import co.cask.cdap.api.data.stream.Stream; import co.cask.cdap.api.data.stream.StreamSpecification; import co.cask.cdap.api.dataset.Dataset; import co.cask.cdap.api.dataset.DatasetProperties; import co.cask.cdap.api.dataset.module.DatasetModule; import co.cask.cdap.internal.dataset.DatasetCreationSpec; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * Implementation of {@link DatasetConfigurer} for adding datasets and streams in Configurers. */ // TODO: Move this class to cdap-app-fabric once CDAP_2943 is fixed public class DefaultDatasetConfigurer implements DatasetConfigurer { private final Map<String, StreamSpecification> streams = new HashMap<>(); private final Map<String, DatasetCreationSpec> datasetSpecs = new HashMap<>(); private final Map<String, String> datasetModules = new HashMap<>(); public Map<String, StreamSpecification> getStreams() { return streams; } public Map<String, DatasetCreationSpec> getDatasetSpecs() { return datasetSpecs; } public Map<String, String> getDatasetModules() { return datasetModules; } public void addStreams(Map<String, StreamSpecification> streams) { Set<String> duplicateStreams = findDuplicates(streams.keySet(), this.streams.keySet()); checkArgument(duplicateStreams.isEmpty(), "Streams %s have been added already. Remove the duplicates.", duplicateStreams); this.streams.putAll(streams); } public void addDatasetSpecs(Map<String, DatasetCreationSpec> datasetSpecs) { Set<String> duplicateDatasetSpecs = findDuplicates(datasetSpecs.keySet(), this.datasetSpecs.keySet()); checkArgument(duplicateDatasetSpecs.isEmpty(), "Dataset Instances %s have already been added. Remove the duplicates.", duplicateDatasetSpecs); this.datasetSpecs.putAll(datasetSpecs); } public void addDatasetModules(Map<String, String> datasetModules) { for (Map.Entry<String, String> newEntry : datasetModules.entrySet()) { if (this.datasetModules.containsKey(newEntry.getKey())) { checkArgument(this.datasetModules.get(newEntry.getKey()).equals(newEntry.getValue()), String.format( "DatasetModule %s has been already added with different class %s", newEntry.getKey(), this.datasetModules.get(newEntry.getKey()))); } } this.datasetModules.putAll(datasetModules); } private Set<String> findDuplicates(Set<String> setOne, Set<String> setTwo) { Set<String> duplicates = new HashSet<>(setOne); duplicates.retainAll(setTwo); return duplicates; } @Override public void addStream(Stream stream) { checkArgument(stream != null, "Stream cannot be null."); StreamSpecification spec = stream.configure(); StreamSpecification existingSpec = streams.get(spec.getName()); if (existingSpec != null && !existingSpec.equals(spec)) { throw new IllegalArgumentException(String.format("Stream '%s' was added multiple times with different specs. " + "Please resolve the conflict so that there is only one spec for the stream.", spec.getName())); } streams.put(spec.getName(), spec); } @Override public void addStream(String streamName) { checkArgument(streamName != null && !streamName.isEmpty(), "Stream Name cannot be null or empty"); addStream(new Stream(streamName)); } @Override public void addDatasetModule(String moduleName, Class<? extends DatasetModule> moduleClass) { checkArgument(moduleName != null, "Dataset module name cannot be null."); checkArgument(moduleClass != null, "Dataset module class cannot be null."); String moduleClassName = moduleClass.getName(); String existingModuleClass = datasetModules.get(moduleName); if (existingModuleClass != null && !existingModuleClass.equals(moduleClass.getName())) { throw new IllegalArgumentException(String.format("Module '%s' added multiple times with different classes " + "'%s' and '%s'. Please resolve the conflict.", moduleName, existingModuleClass, moduleClassName)); } datasetModules.put(moduleName, moduleClassName); } @Override public void addDatasetType(Class<? extends Dataset> datasetClass) { checkArgument(datasetClass != null, "Dataset class cannot be null."); String className = datasetClass.getName(); String existingClassName = datasetModules.get(datasetClass.getName()); if (existingClassName != null && !existingClassName.equals(className)) { throw new IllegalArgumentException(String.format("Dataset class '%s' was added already as a module with class " + "'%s'. Please resolve the conflict so there is only one class.", className, existingClassName)); } datasetModules.put(datasetClass.getName(), className); } @Override public void createDataset(String datasetInstanceName, String typeName, DatasetProperties properties) { checkArgument(datasetInstanceName != null, "Dataset instance name cannot be null."); checkArgument(typeName != null, "Dataset type name cannot be null."); checkArgument(properties != null, "Instance properties name cannot be null."); DatasetCreationSpec spec = new DatasetCreationSpec(datasetInstanceName, typeName, properties); DatasetCreationSpec existingSpec = datasetSpecs.get(datasetInstanceName); if (existingSpec != null && !existingSpec.equals(spec)) { throw new IllegalArgumentException(String.format("DatasetInstance '%s' was added multiple times with " + "different specifications. Please resolve the conlict so that there is only one specification for " + "the dataset instance.", datasetInstanceName)); } datasetSpecs.put(datasetInstanceName, spec); } @Override public void createDataset(String datasetName, String typeName) { createDataset(datasetName, typeName, DatasetProperties.EMPTY); } @Override public void createDataset(String datasetInstanceName, Class<? extends Dataset> datasetClass, DatasetProperties properties) { createDataset(datasetInstanceName, datasetClass.getName(), properties); addDatasetType(datasetClass); } @Override public void createDataset(String datasetName, Class<? extends Dataset> datasetClass) { createDataset(datasetName, datasetClass, DatasetProperties.EMPTY); } private void checkArgument(boolean condition, String template, Object...args) { if (!condition) { throw new IllegalArgumentException(String.format(template, args)); } } }