use of io.cdap.cdap.api.dataset.DatasetAdmin 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();
}
}
use of io.cdap.cdap.api.dataset.DatasetAdmin in project cdap by caskdata.
the class CubeDatasetAdmin method update.
@Override
public void update(DatasetSpecification oldSpec) throws IOException {
// update all existing resolution tables, create all new resolutions
for (Map.Entry<String, DatasetSpecification> entry : spec.getSpecifications().entrySet()) {
DatasetSpecification oldSubSpec = spec.getSpecification(entry.getKey());
DatasetAdmin subAdmin = delegates.get(entry.getKey());
if (oldSubSpec != null && subAdmin instanceof Updatable) {
((Updatable) subAdmin).update(oldSubSpec);
} else if (oldSubSpec == null) {
subAdmin.create();
}
}
// TODO (CDAP-6342) delete all resolutions that were removed as part of the update
}
use of io.cdap.cdap.api.dataset.DatasetAdmin in project cdap by caskdata.
the class TableTest method testConflictDetection.
private void testConflictDetection(ConflictDetection level) throws Exception {
// we use tableX_Y format for variable names which means "tableX that is used in tx Y"
String table1 = "table1";
String table2 = "table2";
DatasetProperties props = TableProperties.builder().setConflictDetection(level).build();
DatasetAdmin admin1 = getTableAdmin(CONTEXT1, table1, props);
DatasetAdmin admin2 = getTableAdmin(CONTEXT1, table2, props);
admin1.create();
admin2.create();
try (Table table11 = getTable(CONTEXT1, table1, props);
Table table22 = getTable(CONTEXT1, table2, props);
Table table13 = getTable(CONTEXT1, table1, props);
Table table14 = getTable(CONTEXT1, table1, props);
Table table15 = getTable(CONTEXT1, table1, props);
Table table16 = getTable(CONTEXT1, table1, props);
Table table17 = getTable(CONTEXT1, table1, props);
Table table18 = getTable(CONTEXT1, table1, props);
Table table19 = getTable(CONTEXT1, table1, props)) {
// 1) Test conflicts when using different tables
Transaction tx1 = txClient.startShort();
((TransactionAware) table11).startTx(tx1);
// write r1->c1,v1 but not commit
table11.put(R1, a(C1), a(V1));
// start new tx
Transaction tx2 = txClient.startShort();
((TransactionAware) table22).startTx(tx2);
// change in tx2 same data but in different table
table22.put(R1, a(C1), a(V2));
// start new tx
Transaction tx3 = txClient.startShort();
((TransactionAware) table13).startTx(tx3);
// change in tx3 same data in same table as tx1
table13.put(R1, a(C1), a(V2));
// committing tx1
txClient.canCommitOrThrow(tx1, ((TransactionAware) table11).getTxChanges());
Assert.assertTrue(((TransactionAware) table11).commitTx());
txClient.commitOrThrow(tx1);
// no conflict should be when committing tx2
txClient.canCommitOrThrow(tx2, ((TransactionAware) table22).getTxChanges());
// but conflict should be when committing tx3
if (level != ConflictDetection.NONE) {
try {
txClient.canCommitOrThrow(tx3, ((TransactionAware) table13).getTxChanges());
Assert.fail("Conflict not detected!");
} catch (TransactionConflictException e) {
// expected
}
((TransactionAware) table13).rollbackTx();
txClient.abort(tx3);
} else {
txClient.canCommitOrThrow(tx3, ((TransactionAware) table13).getTxChanges());
}
// 2) Test conflicts when using different rows
Transaction tx4 = txClient.startShort();
((TransactionAware) table14).startTx(tx4);
// write r1->c1,v1 but not commit
table14.put(R1, a(C1), a(V1));
// start new tx
Transaction tx5 = txClient.startShort();
((TransactionAware) table15).startTx(tx5);
// change in tx5 same data but in different row
table15.put(R2, a(C1), a(V2));
// start new tx
Transaction tx6 = txClient.startShort();
((TransactionAware) table16).startTx(tx6);
// change in tx6 in same row as tx1
table16.put(R1, a(C2), a(V2));
// committing tx4
txClient.canCommitOrThrow(tx4, ((TransactionAware) table14).getTxChanges());
Assert.assertTrue(((TransactionAware) table14).commitTx());
txClient.commitOrThrow(tx4);
// no conflict should be when committing tx5
txClient.canCommitOrThrow(tx5, ((TransactionAware) table15).getTxChanges());
// but conflict should be when committing tx6 iff we resolve on row level
if (level == ConflictDetection.ROW) {
try {
txClient.canCommitOrThrow(tx6, ((TransactionAware) table16).getTxChanges());
Assert.fail("Conflict not detected!");
} catch (TransactionConflictException e) {
// expected
}
((TransactionAware) table16).rollbackTx();
txClient.abort(tx6);
} else {
txClient.canCommitOrThrow(tx6, ((TransactionAware) table16).getTxChanges());
}
// 3) Test conflicts when using different columns
Transaction tx7 = txClient.startShort();
((TransactionAware) table17).startTx(tx7);
// write r1->c1,v1 but not commit
table17.put(R1, a(C1), a(V1));
// start new tx
Transaction tx8 = txClient.startShort();
((TransactionAware) table18).startTx(tx8);
// change in tx8 same data but in different column
table18.put(R1, a(C2), a(V2));
// start new tx
Transaction tx9 = txClient.startShort();
((TransactionAware) table19).startTx(tx9);
// change in tx9 same column in same column as tx1
table19.put(R1, a(C1), a(V2));
// committing tx7
txClient.canCommitOrThrow(tx7, ((TransactionAware) table17).getTxChanges());
Assert.assertTrue(((TransactionAware) table17).commitTx());
txClient.commitOrThrow(tx7);
// no conflict should be when committing tx8 iff we resolve on column level
if (level == ConflictDetection.COLUMN || level == ConflictDetection.NONE) {
txClient.canCommitOrThrow(tx8, ((TransactionAware) table18).getTxChanges());
} else {
try {
txClient.canCommitOrThrow(tx8, ((TransactionAware) table18).getTxChanges());
Assert.fail("Conflict not detected!");
} catch (TransactionConflictException e) {
// expected
}
((TransactionAware) table18).rollbackTx();
txClient.abort(tx8);
}
// but conflict should be when committing tx9
if (level != ConflictDetection.NONE) {
try {
txClient.canCommitOrThrow(tx9, ((TransactionAware) table19).getTxChanges());
Assert.fail("Conflict not detected!");
} catch (TransactionConflictException e) {
// expected
}
((TransactionAware) table19).rollbackTx();
txClient.abort(tx9);
} else {
txClient.canCommitOrThrow(tx9, ((TransactionAware) table19).getTxChanges());
}
} finally {
// NOTE: we are doing our best to cleanup junk between tests to isolate errors, but we are not going to be
// crazy about it
admin1.drop();
admin2.drop();
}
}
use of io.cdap.cdap.api.dataset.DatasetAdmin in project cdap by caskdata.
the class TableTest method testEmptyDelete.
@Test
public void testEmptyDelete() throws Exception {
DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
admin.create();
try (Table myTable = getTable(CONTEXT1, MY_TABLE)) {
Transaction tx = txClient.startShort();
((TransactionAware) myTable).startTx(tx);
myTable.put(R1, C1, V1);
myTable.put(R1, C2, V2);
myTable.put(R1, C3, V3);
// specifying empty columns means to delete nothing
myTable.delete(R1, new byte[][] {});
myTable.delete(new Delete(R1, new byte[][] {}));
myTable.delete(new Delete(R1, ImmutableList.<byte[]>of()));
myTable.delete(new Delete(Bytes.toString(R1), new String[] {}));
myTable.delete(new Delete(Bytes.toString(R1), ImmutableList.<String>of()));
// verify the above delete calls deleted none of the rows
Row row = myTable.get(R1);
Assert.assertEquals(3, row.getColumns().size());
Assert.assertArrayEquals(R1, row.getRow());
Assert.assertArrayEquals(V1, row.get(C1));
Assert.assertArrayEquals(V2, row.get(C2));
Assert.assertArrayEquals(V3, row.get(C3));
// test deletion of only one column
Delete delete = new Delete(R1);
Assert.assertNull(delete.getColumns());
delete.add(C1);
Assert.assertNotNull(delete.getColumns());
myTable.delete(delete);
row = myTable.get(R1);
Assert.assertEquals(2, row.getColumns().size());
Assert.assertArrayEquals(R1, row.getRow());
Assert.assertArrayEquals(V2, row.get(C2));
Assert.assertArrayEquals(V3, row.get(C3));
// test delete of all columns
myTable.delete(new Delete(R1));
Assert.assertEquals(0, myTable.get(R1).getColumns().size());
txClient.abort(tx);
} finally {
admin.drop();
}
}
use of io.cdap.cdap.api.dataset.DatasetAdmin in project cdap by caskdata.
the class TableTest method testRollingBackPersistedChanges.
@Test
public void testRollingBackPersistedChanges() throws Exception {
DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
admin.create();
try (Table myTable0 = getTable(CONTEXT1, MY_TABLE);
Table myTable1 = getTable(CONTEXT1, MY_TABLE);
Table myTable2 = getTable(CONTEXT1, MY_TABLE)) {
// write and commit one row/column
Transaction tx0 = txClient.startShort();
((TransactionAware) myTable0).startTx(tx0);
myTable0.put(R2, a(C2), a(V2));
txClient.canCommitOrThrow(tx0, ((TransactionAware) myTable0).getTxChanges());
Assert.assertTrue(((TransactionAware) myTable0).commitTx());
txClient.commitOrThrow(tx0);
((TransactionAware) myTable0).postTxCommit();
Transaction tx1 = txClient.startShort();
((TransactionAware) myTable1).startTx(tx1);
// write r1->c1,v1 but not commit
myTable1.put(R1, a(C1), a(V1));
// also overwrite the value from tx0
myTable1.put(R2, a(C2), a(V3));
// TableAssert.verify can see changes inside tx
TableAssert.assertRow(a(C1, V1), myTable1.get(R1, a(C1)));
// persisting changes
Assert.assertTrue(((TransactionAware) myTable1).commitTx());
// let's pretend that after persisting changes we still got conflict when finalizing tx, so
// rolling back changes
Assert.assertTrue(((TransactionAware) myTable1).rollbackTx());
// making tx visible
txClient.abort(tx1);
// start new tx
Transaction tx2 = txClient.startShort();
((TransactionAware) myTable2).startTx(tx2);
// TableAssert.verify don't see rolled back changes
TableAssert.assertRow(a(), myTable2.get(R1, a(C1)));
// TableAssert.verify we still see the previous value
TableAssert.assertRow(a(C2, V2), myTable2.get(R2, a(C2)));
} finally {
admin.drop();
}
}
Aggregations