Search in sources :

Example 6 with IncompatibleUpdateException

use of io.cdap.cdap.api.dataset.IncompatibleUpdateException 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;
    }
}
Also used : DatasetSpecification(io.cdap.cdap.api.dataset.DatasetSpecification) DatasetAdmin(io.cdap.cdap.api.dataset.DatasetAdmin) DatasetType(io.cdap.cdap.data2.datafabric.dataset.DatasetType) IncompatibleUpdateException(io.cdap.cdap.api.dataset.IncompatibleUpdateException) AccessException(io.cdap.cdap.api.security.AccessException) IOException(java.io.IOException) BadRequestException(io.cdap.cdap.common.BadRequestException) NotFoundException(io.cdap.cdap.common.NotFoundException) DirectoryClassLoaderProvider(io.cdap.cdap.data2.datafabric.dataset.type.DirectoryClassLoaderProvider) Updatable(io.cdap.cdap.api.dataset.Updatable) SystemMetadata(io.cdap.cdap.data2.metadata.system.SystemMetadata) BadRequestException(io.cdap.cdap.common.BadRequestException) DatasetClassLoaderProvider(io.cdap.cdap.data2.datafabric.dataset.type.DatasetClassLoaderProvider) DatasetContext(io.cdap.cdap.api.dataset.DatasetContext) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) IncompatibleUpdateException(io.cdap.cdap.api.dataset.IncompatibleUpdateException)

Example 7 with IncompatibleUpdateException

use of io.cdap.cdap.api.dataset.IncompatibleUpdateException in project cdap by caskdata.

the class PartitionedFileSetDefinition method reconfigure.

@Override
public DatasetSpecification reconfigure(String instanceName, DatasetProperties properties, DatasetSpecification currentSpec) throws IncompatibleUpdateException {
    // validate that the partitioning is not changing
    Partitioning oldPartitioning = PartitionedFileSetProperties.getPartitioning(currentSpec.getProperties());
    Partitioning newPartitioning = PartitionedFileSetProperties.getPartitioning(properties.getProperties());
    Preconditions.checkNotNull(oldPartitioning, "Existing dataset has no partitioning");
    Preconditions.checkNotNull(newPartitioning, "New properties do not contain partitioning");
    if (!Iterators.elementsEqual(oldPartitioning.getFields().entrySet().iterator(), newPartitioning.getFields().entrySet().iterator())) {
        throw new IncompatibleUpdateException(String.format("Partitioning cannot be changed. Existing: %s, new: %s", oldPartitioning, newPartitioning));
    }
    Map<String, String> pfsProperties = new HashMap<>(properties.getProperties());
    // define the columns for indexing on the partitionsTable
    DatasetProperties indexedTableProperties = DatasetProperties.builder().addAll(properties.getProperties()).add(IndexedTable.INDEX_COLUMNS_CONF_KEY, INDEXED_COLS).build();
    // only set the default base path property if the default was set the last time it was configured,
    // and no base path is in the current properties.
    DatasetSpecification currentFileSpec = currentSpec.getSpecification(FILESET_NAME);
    DatasetProperties.Builder newFileProperties = DatasetProperties.builder().addAll(properties.getProperties());
    String useNameAsBasePathDefault = currentSpec.getProperty(NAME_AS_BASE_PATH_DEFAULT);
    if (Boolean.parseBoolean(useNameAsBasePathDefault) && !properties.getProperties().containsKey(FileSetProperties.BASE_PATH)) {
        newFileProperties.add(FileSetProperties.BASE_PATH, instanceName);
        pfsProperties.put(NAME_AS_BASE_PATH_DEFAULT, Boolean.TRUE.toString());
    }
    return DatasetSpecification.builder(instanceName, getName()).properties(pfsProperties).datasets(AbstractDatasetDefinition.reconfigure(filesetDef, FILESET_NAME, newFileProperties.build(), currentFileSpec), AbstractDatasetDefinition.reconfigure(indexedTableDef, PARTITION_TABLE_NAME, indexedTableProperties, currentSpec.getSpecification(PARTITION_TABLE_NAME))).build();
}
Also used : Partitioning(io.cdap.cdap.api.dataset.lib.Partitioning) HashMap(java.util.HashMap) DatasetProperties(io.cdap.cdap.api.dataset.DatasetProperties) DatasetSpecification(io.cdap.cdap.api.dataset.DatasetSpecification) IncompatibleUpdateException(io.cdap.cdap.api.dataset.IncompatibleUpdateException)

Example 8 with IncompatibleUpdateException

use of io.cdap.cdap.api.dataset.IncompatibleUpdateException in project cdap by caskdata.

the class InMemoryDatasetFramework method updateInstance.

@Override
public void updateInstance(DatasetId datasetInstanceId, DatasetProperties props) throws DatasetManagementException, IOException {
    writeLock.lock();
    try {
        DatasetSpecification oldSpec = instances.get(datasetInstanceId.getParent(), datasetInstanceId);
        if (oldSpec == null) {
            throw new InstanceNotFoundException(datasetInstanceId.getEntityName());
        }
        DatasetDefinition def = getDefinitionForType(datasetInstanceId.getParent(), oldSpec.getType());
        if (def == null) {
            throw new DatasetManagementException(String.format("Dataset type '%s' is neither registered in the '%s' namespace nor in the system namespace", oldSpec.getType(), datasetInstanceId.getParent()));
        }
        DatasetSpecification spec = AbstractDatasetDefinition.reconfigure(def, datasetInstanceId.getEntityName(), props, oldSpec).setOriginalProperties(props);
        if (props.getDescription() != null) {
            spec = spec.setDescription(props.getDescription());
        }
        instances.put(datasetInstanceId.getParent(), datasetInstanceId, spec);
        DatasetAdmin admin = def.getAdmin(DatasetContext.from(datasetInstanceId.getNamespace()), spec, null);
        if (admin instanceof Updatable) {
            ((Updatable) admin).update(oldSpec);
        } else {
            admin.upgrade();
        }
        publishAudit(datasetInstanceId, AuditType.UPDATE);
    } catch (IncompatibleUpdateException e) {
        throw new InstanceConflictException("Update failed for dataset instance " + datasetInstanceId, e);
    } finally {
        writeLock.unlock();
    }
}
Also used : DatasetManagementException(io.cdap.cdap.api.dataset.DatasetManagementException) InstanceConflictException(io.cdap.cdap.api.dataset.InstanceConflictException) InstanceNotFoundException(io.cdap.cdap.api.dataset.InstanceNotFoundException) Updatable(io.cdap.cdap.api.dataset.Updatable) DatasetSpecification(io.cdap.cdap.api.dataset.DatasetSpecification) DatasetAdmin(io.cdap.cdap.api.dataset.DatasetAdmin) DatasetDefinition(io.cdap.cdap.api.dataset.DatasetDefinition) AbstractDatasetDefinition(io.cdap.cdap.api.dataset.lib.AbstractDatasetDefinition) IncompatibleUpdateException(io.cdap.cdap.api.dataset.IncompatibleUpdateException)

Example 9 with IncompatibleUpdateException

use of io.cdap.cdap.api.dataset.IncompatibleUpdateException in project cdap by cdapio.

the class InMemoryDatasetFramework method updateInstance.

@Override
public void updateInstance(DatasetId datasetInstanceId, DatasetProperties props) throws DatasetManagementException, IOException {
    writeLock.lock();
    try {
        DatasetSpecification oldSpec = instances.get(datasetInstanceId.getParent(), datasetInstanceId);
        if (oldSpec == null) {
            throw new InstanceNotFoundException(datasetInstanceId.getEntityName());
        }
        DatasetDefinition def = getDefinitionForType(datasetInstanceId.getParent(), oldSpec.getType());
        if (def == null) {
            throw new DatasetManagementException(String.format("Dataset type '%s' is neither registered in the '%s' namespace nor in the system namespace", oldSpec.getType(), datasetInstanceId.getParent()));
        }
        DatasetSpecification spec = AbstractDatasetDefinition.reconfigure(def, datasetInstanceId.getEntityName(), props, oldSpec).setOriginalProperties(props);
        if (props.getDescription() != null) {
            spec = spec.setDescription(props.getDescription());
        }
        instances.put(datasetInstanceId.getParent(), datasetInstanceId, spec);
        DatasetAdmin admin = def.getAdmin(DatasetContext.from(datasetInstanceId.getNamespace()), spec, null);
        if (admin instanceof Updatable) {
            ((Updatable) admin).update(oldSpec);
        } else {
            admin.upgrade();
        }
        publishAudit(datasetInstanceId, AuditType.UPDATE);
    } catch (IncompatibleUpdateException e) {
        throw new InstanceConflictException("Update failed for dataset instance " + datasetInstanceId, e);
    } finally {
        writeLock.unlock();
    }
}
Also used : DatasetManagementException(io.cdap.cdap.api.dataset.DatasetManagementException) InstanceConflictException(io.cdap.cdap.api.dataset.InstanceConflictException) InstanceNotFoundException(io.cdap.cdap.api.dataset.InstanceNotFoundException) Updatable(io.cdap.cdap.api.dataset.Updatable) DatasetSpecification(io.cdap.cdap.api.dataset.DatasetSpecification) DatasetAdmin(io.cdap.cdap.api.dataset.DatasetAdmin) DatasetDefinition(io.cdap.cdap.api.dataset.DatasetDefinition) AbstractDatasetDefinition(io.cdap.cdap.api.dataset.lib.AbstractDatasetDefinition) IncompatibleUpdateException(io.cdap.cdap.api.dataset.IncompatibleUpdateException)

Example 10 with IncompatibleUpdateException

use of io.cdap.cdap.api.dataset.IncompatibleUpdateException in project cdap by cdapio.

the class DatasetDefinitionRegistryWithDefaultModules method testFileSetReconfigure.

private void testFileSetReconfigure(boolean expectSuccess, DatasetDefinition def, Boolean wasExternal, String path, Boolean newExternal, String newPath, DatasetProperties extraProps) throws IncompatibleUpdateException {
    Assert.assertTrue(def instanceof Reconfigurable);
    DatasetProperties props = buildFileSetProps(extraProps, wasExternal, path);
    DatasetProperties newProps = buildFileSetProps(extraProps, newExternal, newPath);
    DatasetSpecification spec = def.configure("fs", props);
    if (expectSuccess) {
        ((Reconfigurable) def).reconfigure("fs", newProps, spec);
    } else {
        try {
            ((Reconfigurable) def).reconfigure("fs", newProps, spec);
            Assert.fail("reconfigure should have thrown exception");
        } catch (IncompatibleUpdateException e) {
        // expected
        }
    }
}
Also used : DatasetProperties(io.cdap.cdap.api.dataset.DatasetProperties) DatasetSpecification(io.cdap.cdap.api.dataset.DatasetSpecification) Reconfigurable(io.cdap.cdap.api.dataset.Reconfigurable) IncompatibleUpdateException(io.cdap.cdap.api.dataset.IncompatibleUpdateException)

Aggregations

DatasetSpecification (io.cdap.cdap.api.dataset.DatasetSpecification)22 IncompatibleUpdateException (io.cdap.cdap.api.dataset.IncompatibleUpdateException)22 DatasetProperties (io.cdap.cdap.api.dataset.DatasetProperties)12 Reconfigurable (io.cdap.cdap.api.dataset.Reconfigurable)8 DatasetAdmin (io.cdap.cdap.api.dataset.DatasetAdmin)6 DatasetDefinition (io.cdap.cdap.api.dataset.DatasetDefinition)6 Updatable (io.cdap.cdap.api.dataset.Updatable)6 Test (org.junit.Test)6 DatasetContext (io.cdap.cdap.api.dataset.DatasetContext)4 ConflictException (io.cdap.cdap.common.ConflictException)4 DatasetType (io.cdap.cdap.data2.datafabric.dataset.DatasetType)4 DatasetId (io.cdap.cdap.proto.id.DatasetId)4 Map (java.util.Map)4 DatasetManagementException (io.cdap.cdap.api.dataset.DatasetManagementException)2 InstanceConflictException (io.cdap.cdap.api.dataset.InstanceConflictException)2 InstanceNotFoundException (io.cdap.cdap.api.dataset.InstanceNotFoundException)2 AbstractDatasetDefinition (io.cdap.cdap.api.dataset.lib.AbstractDatasetDefinition)2 Partitioning (io.cdap.cdap.api.dataset.lib.Partitioning)2 AccessException (io.cdap.cdap.api.security.AccessException)2 BadRequestException (io.cdap.cdap.common.BadRequestException)2