Search in sources :

Example 11 with DatasetAdmin

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();
    }
}
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 12 with DatasetAdmin

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
}
Also used : Updatable(io.cdap.cdap.api.dataset.Updatable) DatasetSpecification(io.cdap.cdap.api.dataset.DatasetSpecification) DatasetAdmin(io.cdap.cdap.api.dataset.DatasetAdmin) CompositeDatasetAdmin(io.cdap.cdap.api.dataset.lib.CompositeDatasetAdmin) Map(java.util.Map)

Example 13 with DatasetAdmin

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();
    }
}
Also used : Table(io.cdap.cdap.api.dataset.table.Table) HBaseTable(io.cdap.cdap.data2.dataset2.lib.table.hbase.HBaseTable) Transaction(org.apache.tephra.Transaction) TransactionAware(org.apache.tephra.TransactionAware) DatasetProperties(io.cdap.cdap.api.dataset.DatasetProperties) DatasetAdmin(io.cdap.cdap.api.dataset.DatasetAdmin) TransactionConflictException(org.apache.tephra.TransactionConflictException)

Example 14 with DatasetAdmin

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();
    }
}
Also used : Delete(io.cdap.cdap.api.dataset.table.Delete) Table(io.cdap.cdap.api.dataset.table.Table) HBaseTable(io.cdap.cdap.data2.dataset2.lib.table.hbase.HBaseTable) Transaction(org.apache.tephra.Transaction) TransactionAware(org.apache.tephra.TransactionAware) DatasetAdmin(io.cdap.cdap.api.dataset.DatasetAdmin) Row(io.cdap.cdap.api.dataset.table.Row) Test(org.junit.Test)

Example 15 with DatasetAdmin

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();
    }
}
Also used : Table(io.cdap.cdap.api.dataset.table.Table) HBaseTable(io.cdap.cdap.data2.dataset2.lib.table.hbase.HBaseTable) Transaction(org.apache.tephra.Transaction) TransactionAware(org.apache.tephra.TransactionAware) DatasetAdmin(io.cdap.cdap.api.dataset.DatasetAdmin) Test(org.junit.Test)

Aggregations

DatasetAdmin (io.cdap.cdap.api.dataset.DatasetAdmin)112 Test (org.junit.Test)60 Table (io.cdap.cdap.api.dataset.table.Table)54 Transaction (org.apache.tephra.Transaction)54 TransactionAware (org.apache.tephra.TransactionAware)46 HBaseTable (io.cdap.cdap.data2.dataset2.lib.table.hbase.HBaseTable)42 DatasetSpecification (io.cdap.cdap.api.dataset.DatasetSpecification)20 DatasetProperties (io.cdap.cdap.api.dataset.DatasetProperties)16 Get (io.cdap.cdap.api.dataset.table.Get)16 Put (io.cdap.cdap.api.dataset.table.Put)14 IOException (java.io.IOException)14 Row (io.cdap.cdap.api.dataset.table.Row)12 DatasetType (io.cdap.cdap.data2.datafabric.dataset.DatasetType)10 TransactionConflictException (org.apache.tephra.TransactionConflictException)10 Scan (io.cdap.cdap.api.dataset.table.Scan)8 BufferingTableTest (io.cdap.cdap.data2.dataset2.lib.table.BufferingTableTest)8 AbstractModule (com.google.inject.AbstractModule)6 TypeLiteral (com.google.inject.TypeLiteral)6 DatasetContext (io.cdap.cdap.api.dataset.DatasetContext)6 DatasetManagementException (io.cdap.cdap.api.dataset.DatasetManagementException)6