use of io.cdap.cdap.data2.dataset2.lib.table.Update in project cdap by caskdata.
the class InMemoryTableService method swap.
public static synchronized boolean swap(String tableName, byte[] row, byte[] column, byte[] oldValue, byte[] newValue) {
ConcurrentNavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, Update>>> table = tables.get(tableName);
// get the correct row from the table, create it if it doesn't exist
NavigableMap<byte[], NavigableMap<Long, Update>> rowMap = table.get(row);
Update existingValue = null;
if (rowMap != null) {
NavigableMap<Long, Update> columnMap = rowMap.get(column);
if (columnMap != null) {
existingValue = columnMap.lastEntry().getValue();
}
}
// verify existing value matches
if (oldValue == null && existingValue != null) {
return false;
}
if (oldValue != null && (existingValue == null || !Bytes.equals(oldValue, existingValue.getBytes()))) {
return false;
}
// write new value
if (newValue == null) {
if (rowMap != null) {
rowMap.remove(column);
}
} else {
if (rowMap == null) {
rowMap = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
table.put(row, rowMap);
}
NavigableMap<Long, Update> columnMap = rowMap.get(column);
if (columnMap == null) {
columnMap = Maps.newTreeMap();
rowMap.put(column, columnMap);
}
PutValue newPut = new PutValue(newValue);
columnMap.put(System.currentTimeMillis(), newPut);
}
return true;
}
use of io.cdap.cdap.data2.dataset2.lib.table.Update in project cdap by caskdata.
the class LevelDBTable method persist.
@Override
protected void persist(NavigableMap<byte[], NavigableMap<byte[], Update>> changes) throws Exception {
persistedVersion = tx == null ? System.currentTimeMillis() : tx.getWritePointer();
NavigableMap<byte[], NavigableMap<byte[], byte[]>> puts = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
NavigableMap<byte[], NavigableMap<byte[], Long>> increments = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
for (Map.Entry<byte[], NavigableMap<byte[], Update>> rowEntry : changes.entrySet()) {
for (Map.Entry<byte[], Update> colEntry : rowEntry.getValue().entrySet()) {
Update val = colEntry.getValue();
if (val instanceof IncrementValue) {
NavigableMap<byte[], Long> incrCols = increments.get(rowEntry.getKey());
if (incrCols == null) {
incrCols = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
increments.put(rowEntry.getKey(), incrCols);
}
incrCols.put(colEntry.getKey(), ((IncrementValue) val).getValue());
} else if (val instanceof PutValue) {
NavigableMap<byte[], byte[]> putCols = puts.get(rowEntry.getKey());
if (putCols == null) {
putCols = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
puts.put(rowEntry.getKey(), putCols);
}
putCols.put(colEntry.getKey(), ((PutValue) val).getValue());
}
}
}
if (!increments.isEmpty() || !puts.isEmpty()) {
persist(increments, puts);
}
}
use of io.cdap.cdap.data2.dataset2.lib.table.Update in project cdap by caskdata.
the class InMemoryDatasetOpExecutor method update.
@Override
public DatasetCreationResponse update(DatasetId datasetInstanceId, DatasetTypeMeta typeMeta, DatasetProperties props, DatasetSpecification existing) throws Exception {
DatasetType type = client.getDatasetType(typeMeta, null, new ConstantClassLoaderProvider());
if (type == null) {
throw new IllegalArgumentException("Dataset type cannot be instantiated for provided type meta: " + typeMeta);
}
try {
DatasetSpecification spec = type.reconfigure(datasetInstanceId.getEntityName(), props, existing);
DatasetAdmin admin = type.getAdmin(DatasetContext.from(datasetInstanceId.getNamespace()), spec);
if (admin instanceof Updatable) {
((Updatable) admin).update(existing);
} else {
admin.create();
}
if (spec.getDescription() == null && existing.getDescription() != null) {
spec.setDescription(existing.getDescription());
}
return new DatasetCreationResponse(spec, null);
} catch (IncompatibleUpdateException e) {
throw new ConflictException(e.getMessage());
}
}
use of io.cdap.cdap.data2.dataset2.lib.table.Update in project cdap by caskdata.
the class AbstractDatasetFrameworkTest method testAuditPublish.
@Test
public void testAuditPublish() throws Exception {
// Clear all audit messages
inMemoryAuditPublisher.popMessages();
List<AuditMessage> expectedMessages = new ArrayList<>();
// Adding modules
DatasetFramework framework = getFramework();
framework.addModule(IN_MEMORY, new InMemoryTableModule());
// Creating instances
framework.addInstance(Table.class.getName(), MY_TABLE, DatasetProperties.EMPTY);
expectedMessages.add(new AuditMessage(0, MY_TABLE, "", AuditType.CREATE, AuditPayload.EMPTY_PAYLOAD));
framework.addInstance(Table.class.getName(), MY_TABLE2, DatasetProperties.EMPTY);
expectedMessages.add(new AuditMessage(0, MY_TABLE2, "", AuditType.CREATE, AuditPayload.EMPTY_PAYLOAD));
// Update instance
framework.updateInstance(MY_TABLE, DatasetProperties.EMPTY);
expectedMessages.add(new AuditMessage(0, MY_TABLE, "", AuditType.UPDATE, AuditPayload.EMPTY_PAYLOAD));
// Access instance
ProgramRunId runId = new ProgramId("ns", "app", ProgramType.WORKER, "worker").run(RunIds.generate().getId());
LineageWriterDatasetFramework lineageFramework = new LineageWriterDatasetFramework(framework, new NoOpLineageWriter(), new NoOpUsageRegistry(), new AuthenticationTestContext(), new NoOpAccessController());
lineageFramework.setContext(new TestProgramContext(runId));
lineageFramework.setAuditPublisher(inMemoryAuditPublisher);
lineageFramework.getDataset(MY_TABLE, ImmutableMap.<String, String>of(), getClass().getClassLoader());
expectedMessages.add(new AuditMessage(0, MY_TABLE, "", AuditType.ACCESS, new AccessPayload(AccessType.UNKNOWN, runId)));
// Truncate instance
framework.truncateInstance(MY_TABLE);
expectedMessages.add(new AuditMessage(0, MY_TABLE, "", AuditType.TRUNCATE, AuditPayload.EMPTY_PAYLOAD));
// Delete instance
framework.deleteInstance(MY_TABLE);
expectedMessages.add(new AuditMessage(0, MY_TABLE, "", AuditType.DELETE, AuditPayload.EMPTY_PAYLOAD));
// Delete all instances in a namespace
framework.deleteAllInstances(MY_TABLE2.getParent());
expectedMessages.add(new AuditMessage(0, MY_TABLE2, "", AuditType.DELETE, AuditPayload.EMPTY_PAYLOAD));
Assert.assertEquals(expectedMessages, inMemoryAuditPublisher.popMessages());
// cleanup
framework.deleteModule(IN_MEMORY);
}
use of io.cdap.cdap.data2.dataset2.lib.table.Update in project cdap by caskdata.
the class DatasetInstanceService method executeAdmin.
/**
* Executes an admin operation on a dataset.
*
* @param datasetId the datasetId to execute the admin operation on
* @param method the type of admin operation to execute
* @return the {@link DatasetAdminOpResponse} from the HTTP handler
* @throws NamespaceNotFoundException if the requested namespace was not found
* @throws IOException if there was a problem in checking if the namespace exists over HTTP
* @throws UnauthorizedException if perimeter security and authorization are enabled, and the current user does not
* have -
* <ol>
* <li>{@link StandardPermission#DELETE} privileges on the dataset for "truncate" </li>
* <li>{@link StandardPermission#UPDATE} privileges on the dataset for "upgrade" </li>
* <li>read privileges on the dataset for "exists"</li>
* <ol>
*/
DatasetAdminOpResponse executeAdmin(DatasetId datasetId, String method) throws Exception {
ensureNamespaceExists(datasetId.getParent());
Object result = null;
// NOTE: one cannot directly call create and drop, instead this should be called thru
// POST/DELETE @ /data/datasets/{datasetId-id}. Because we must create/drop metadata for these at same time
Principal principal = authenticationContext.getPrincipal();
switch(method) {
case "exists":
// ensure the user has some privilege on the dataset datasetId if it is not system dataset
if (!DatasetsUtil.isSystemDatasetInUserNamespace(datasetId)) {
accessEnforcer.enforce(datasetId, principal, StandardPermission.GET);
}
result = opExecutorClient.exists(datasetId);
break;
case "truncate":
if (!DatasetsUtil.isSystemDatasetInUserNamespace(datasetId)) {
accessEnforcer.enforce(datasetId, principal, StandardPermission.DELETE);
}
if (instanceManager.get(datasetId) == null) {
throw new DatasetNotFoundException(datasetId);
}
opExecutorClient.truncate(datasetId);
publishAudit(datasetId, AuditType.TRUNCATE);
break;
case "upgrade":
if (!DatasetsUtil.isSystemDatasetInUserNamespace(datasetId)) {
accessEnforcer.enforce(datasetId, principal, StandardPermission.UPDATE);
}
if (instanceManager.get(datasetId) == null) {
throw new DatasetNotFoundException(datasetId);
}
opExecutorClient.upgrade(datasetId);
publishAudit(datasetId, AuditType.UPDATE);
break;
default:
throw new HandlerException(HttpResponseStatus.NOT_FOUND, "Invalid admin operation: " + method);
}
return new DatasetAdminOpResponse(result, null);
}
Aggregations