/* * Copyright © 2014-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.data.dataset; import co.cask.cdap.api.data.DatasetInstantiationException; import co.cask.cdap.api.dataset.Dataset; import co.cask.cdap.api.dataset.DatasetAdmin; import co.cask.cdap.api.dataset.DatasetDefinition; import co.cask.cdap.api.dataset.DatasetManagementException; import co.cask.cdap.data2.datafabric.dataset.type.ConstantClassLoaderProvider; import co.cask.cdap.data2.datafabric.dataset.type.DatasetClassLoaderProvider; import co.cask.cdap.data2.datafabric.dataset.type.DirectoryClassLoaderProvider; import co.cask.cdap.data2.dataset2.DatasetFramework; import co.cask.cdap.data2.metadata.lineage.AccessType; import co.cask.cdap.proto.Id; import co.cask.cdap.proto.id.DatasetId; import com.google.common.base.Objects; import java.io.Closeable; import java.io.IOException; import java.util.Map; import javax.annotation.Nullable; /** * The data set instantiator creates instances of data sets at runtime. It is mostly a wrapper around * {@link DatasetFramework}, except it is closeable so that any resources created by dataset classloaders * can be properly cleaned up. For example, a {@link DirectoryClassLoaderProvider} will fetch dataset jars * and unpack them in a local directory, which must be cleaned up after the dataset is no longer needed. */ public class SystemDatasetInstantiator implements Closeable { private final DatasetFramework datasetFramework; // provides classloaders to use for different dataset modules private final DatasetClassLoaderProvider classLoaderProvider; private final Iterable<? extends Id> owners; private final ClassLoader parentClassLoader; public SystemDatasetInstantiator(DatasetFramework datasetFramework, @Nullable ClassLoader classLoader, @Nullable Iterable<? extends Id> owners) { this(datasetFramework, classLoader, new ConstantClassLoaderProvider(classLoader), owners); } SystemDatasetInstantiator(DatasetFramework datasetFramework, @Nullable ClassLoader parentClassLoader, DatasetClassLoaderProvider classLoaderProvider, @Nullable Iterable<? extends Id> owners) { this.owners = owners; this.classLoaderProvider = classLoaderProvider; this.datasetFramework = datasetFramework; this.parentClassLoader = parentClassLoader == null ? Objects.firstNonNull(Thread.currentThread().getContextClassLoader(), getClass().getClassLoader()) : parentClassLoader; } @Nullable public <T extends DatasetAdmin> T getDatasetAdmin(Id.DatasetInstance datasetId) throws DatasetManagementException, IOException { return datasetFramework.getAdmin(datasetId, parentClassLoader, classLoaderProvider); } public <T extends Dataset> T getDataset(Id.DatasetInstance datasetId) throws DatasetInstantiationException { return getDataset(datasetId, DatasetDefinition.NO_ARGUMENTS); } public <T extends Dataset> T getDataset(DatasetId datasetId, Map<String, String> arguments) throws DatasetInstantiationException { return getDataset((Id.DatasetInstance) datasetId.toId(), arguments); } public <T extends Dataset> T getDataset(Id.DatasetInstance datasetId, Map<String, String> arguments) throws DatasetInstantiationException { return getDataset(datasetId, arguments, AccessType.UNKNOWN); } @SuppressWarnings("unchecked") public <T extends Dataset> T getDataset(Id.DatasetInstance datasetId, Map<String, String> arguments, AccessType accessType) throws DatasetInstantiationException { try { T dataset = datasetFramework.getDataset(datasetId, arguments, parentClassLoader, classLoaderProvider, owners, accessType); if (dataset == null) { throw new DatasetInstantiationException("Trying to access dataset that does not exist: " + datasetId); } return dataset; } catch (Exception e) { throw new DatasetInstantiationException("Failed to access dataset: " + datasetId, e); } } public void writeLineage(Id.DatasetInstance datasetId, AccessType accessType) { datasetFramework.writeLineage(datasetId, accessType); } @Override public void close() throws IOException { classLoaderProvider.close(); } }