use of io.cdap.cdap.api.dataset.DatasetContext in project cdap by caskdata.
the class SearchHelper method createTransactional.
/**
* Create a transactional for metadata datasets.
*
* @param txClient transaction client
* @return transactional for the metadata tables
*/
private Transactional createTransactional(TransactionSystemClient txClient) {
return new Transactional() {
@Override
public void execute(io.cdap.cdap.api.TxRunnable runnable) throws TransactionFailureException {
TransactionContext txContext = new TransactionContext(txClient);
try (MetaOnlyDatasetContext datasetContext = new MetaOnlyDatasetContext(txContext)) {
txContext.start();
finishExecute(txContext, datasetContext, runnable);
} catch (Exception e) {
Throwables.propagateIfPossible(e, TransactionFailureException.class);
}
}
@Override
public void execute(int timeout, io.cdap.cdap.api.TxRunnable runnable) throws TransactionFailureException {
TransactionContext txContext = new TransactionContext(txClient);
try (MetaOnlyDatasetContext datasetContext = new MetaOnlyDatasetContext(txContext)) {
txContext.start(timeout);
finishExecute(txContext, datasetContext, runnable);
} catch (Exception e) {
Throwables.propagateIfPossible(e, TransactionFailureException.class);
}
}
private void finishExecute(TransactionContext txContext, io.cdap.cdap.api.data.DatasetContext dsContext, io.cdap.cdap.api.TxRunnable runnable) throws TransactionFailureException {
try {
runnable.run(dsContext);
} catch (Exception e) {
txContext.abort(new TransactionFailureException("Exception raised from TxRunnable.run() " + runnable, e));
}
// The call the txContext.abort above will always have exception thrown
// Hence we'll only reach here if and only if the runnable.run() returns normally.
txContext.finish();
}
};
}
use of io.cdap.cdap.api.dataset.DatasetContext in project cdap by caskdata.
the class DatasetDefinitionRegistryWithDefaultModules method testCompositeDatasetReconfigure.
// tests that CompositeDatasetDefinition correctly delegates reconfigure() to its embedded types
@Test
public void testCompositeDatasetReconfigure() throws IncompatibleUpdateException {
CompositeDatasetDefinition composite = new CompositeDatasetDefinition("composite", "pedantic", new PedanticDatasetDefinition("pedantic")) {
@Override
public Dataset getDataset(DatasetContext datasetContext, DatasetSpecification spec, Map arguments, ClassLoader classLoader) {
return null;
}
};
DatasetSpecification spec = composite.configure("nn", DatasetProperties.EMPTY);
DatasetSpecification respec = composite.reconfigure("nn", DatasetProperties.EMPTY, spec);
Assert.assertEquals(spec, respec);
try {
composite.reconfigure("nn", DatasetProperties.builder().add("immutable", "x").build(), spec);
Assert.fail("reconfigure should have thrown exception");
} catch (IncompatibleUpdateException e) {
// expected
}
}
use of io.cdap.cdap.api.dataset.DatasetContext in project cdap by caskdata.
the class DatasetAdminService method createOrUpdate.
/**
* Configures and creates a Dataset
*
* @param datasetInstanceId dataset instance to be created
* @param typeMeta type meta for the dataset
* @param props dataset instance properties
* @param existing if dataset already exists (in case of update), the existing properties
* @return dataset specification
*/
public DatasetCreationResponse createOrUpdate(final DatasetId datasetInstanceId, final DatasetTypeMeta typeMeta, final DatasetProperties props, @Nullable final DatasetSpecification existing) throws Exception {
if (existing == null) {
LOG.info("Creating dataset instance {}, type meta: {}", datasetInstanceId, typeMeta);
} else {
LOG.info("Updating dataset instance {}, type meta: {}, existing: {}", datasetInstanceId, typeMeta, existing);
}
try (DatasetClassLoaderProvider classLoaderProvider = new DirectoryClassLoaderProvider(cConf, locationFactory)) {
final DatasetContext context = DatasetContext.from(datasetInstanceId.getNamespace());
UserGroupInformation ugi = getUgiForDataset(impersonator, datasetInstanceId);
final DatasetType type = ImpersonationUtils.doAs(ugi, () -> {
LOG.trace("Getting dataset type {}", typeMeta.getName());
DatasetType type1 = dsFramework.getDatasetType(typeMeta, null, classLoaderProvider);
if (type1 == null) {
throw new BadRequestException(String.format("Cannot instantiate dataset type using provided type meta: %s", typeMeta));
}
LOG.trace("Got dataset type {}", typeMeta.getName());
return type1;
});
DatasetSpecification spec = ImpersonationUtils.doAs(ugi, () -> {
LOG.trace("Configuring dataset {} of type {}", datasetInstanceId.getDataset(), typeMeta.getName());
DatasetSpecification spec1 = existing == null ? type.configure(datasetInstanceId.getEntityName(), props) : type.reconfigure(datasetInstanceId.getEntityName(), props, existing);
LOG.trace("Configured dataset {} of type {}", datasetInstanceId.getDataset(), typeMeta.getName());
DatasetAdmin admin = type.getAdmin(context, spec1);
try {
if (existing != null) {
if (admin instanceof Updatable) {
((Updatable) admin).update(existing);
} else {
admin.upgrade();
}
} else {
LOG.trace("Creating dataset {} of type {}", datasetInstanceId.getDataset(), typeMeta.getName());
admin.create();
LOG.trace("Created dataset {} of type {}", datasetInstanceId.getDataset(), typeMeta.getName());
}
} finally {
Closeables.closeQuietly(admin);
}
return spec1;
});
// Writing system metadata should be done without impersonation since user may not have access to system tables.
LOG.trace("Computing metadata for dataset {}", datasetInstanceId.getDataset());
SystemMetadata metadata = computeSystemMetadata(datasetInstanceId, spec, props, typeMeta, type, context, existing != null, ugi);
LOG.trace("Computed metadata for dataset {}", datasetInstanceId.getDataset());
return new DatasetCreationResponse(spec, metadata);
} catch (Exception e) {
if (e instanceof IncompatibleUpdateException) {
// this is expected to happen if user provides bad update properties, so we log this as debug
LOG.debug("Incompatible update for dataset '{}'", datasetInstanceId, e);
} else {
LOG.error("Error {} dataset '{}': {}", existing == null ? "creating" : "updating", datasetInstanceId, e.getMessage(), e);
}
throw e;
}
}
use of io.cdap.cdap.api.dataset.DatasetContext in project cdap by caskdata.
the class SingleTypeModule method register.
@Override
public void register(DatasetDefinitionRegistry registry) {
final Constructor ctor = findSuitableCtorOrFail(dataSetClass);
DatasetType typeAnn = dataSetClass.getAnnotation(DatasetType.class);
// default type name to dataset class name
String typeName = typeAnn != null ? typeAnn.value() : dataSetClass.getName();
// The ordering is important. It is the same order as the parameters
final Map<String, DatasetDefinition> embeddedDefinitions = Maps.newLinkedHashMap();
final Class<?>[] paramTypes = ctor.getParameterTypes();
Annotation[][] paramAnns = ctor.getParameterAnnotations();
// Gather all dataset name and type information for the @EmbeddedDataset parameters
for (int i = 1; i < paramTypes.length; i++) {
// Must have the EmbeddedDataset as it's the contract of the findSuitableCtorOrFail method
EmbeddedDataset anno = Iterables.filter(Arrays.asList(paramAnns[i]), EmbeddedDataset.class).iterator().next();
String type = anno.type();
// default to dataset class name if dataset type name is not specified through the annotation
if (EmbeddedDataset.DEFAULT_TYPE_NAME.equals(type)) {
type = paramTypes[i].getName();
}
DatasetDefinition embeddedDefinition = registry.get(type);
if (embeddedDefinition == null) {
throw new IllegalStateException(String.format("Unknown Dataset type '%s', specified by parameter number %d of the %s Dataset", type, i, dataSetClass.getName()));
}
embeddedDefinitions.put(anno.value(), embeddedDefinition);
}
registry.add(new CompositeDatasetDefinition<Dataset>(typeName, embeddedDefinitions) {
@Override
public Dataset getDataset(DatasetContext datasetContext, DatasetSpecification spec, Map<String, String> arguments, ClassLoader classLoader) throws IOException {
List<Object> params = new ArrayList<>();
params.add(spec);
for (Map.Entry<String, DatasetDefinition> entry : embeddedDefinitions.entrySet()) {
params.add(entry.getValue().getDataset(datasetContext, spec.getSpecification(entry.getKey()), arguments, classLoader));
}
try {
return (Dataset) ctor.newInstance(params.toArray());
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
});
}
use of io.cdap.cdap.api.dataset.DatasetContext in project cdap by caskdata.
the class MetadataDatasetTest method before.
@SuppressWarnings("unchecked")
@Before
public void before() throws Exception {
DatasetContext datasetContext = DatasetContext.from(NamespaceId.SYSTEM.getNamespace());
if (admin == null) {
DatasetDefinition tableDefinition = dsFrameworkUtil.getInjector().getInstance(Key.get(DatasetDefinition.class, Names.named(Constants.Dataset.TABLE_TYPE)));
definition = new MetadataDatasetDefinition(MetadataDataset.TYPE, new IndexedTableDefinition("indexedTable", tableDefinition));
String scope = MetadataScope.SYSTEM.name();
spec = definition.configure("testMetadata", DatasetProperties.builder().add(MetadataDatasetDefinition.SCOPE_KEY, scope).build());
admin = definition.getAdmin(datasetContext, spec, null);
}
if (!admin.exists()) {
admin.create();
}
dataset = definition.getDataset(datasetContext, spec, Collections.emptyMap(), null);
txnl = dsFrameworkUtil.newInMemoryTransactionExecutor((TransactionAware) dataset);
}
Aggregations