Search in sources :

Example 86 with DatasetAdmin

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

the class TableTest method testBasicCompareAndSwapWithTx.

@Test
public void testBasicCompareAndSwapWithTx() throws Exception {
    DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
    admin.create();
    try (Table myTable1 = getTable(CONTEXT1, MY_TABLE);
        Table myTable2 = getTable(CONTEXT1, MY_TABLE);
        Table myTable3 = getTable(CONTEXT1, MY_TABLE);
        Table myTable4 = getTable(CONTEXT1, MY_TABLE)) {
        Transaction tx1 = txClient.startShort();
        ((TransactionAware) myTable1).startTx(tx1);
        // write r1->c1,v1 but not commit
        myTable1.put(R1, a(C1), a(V1));
        // write r1->c2,v2 but not commit
        Assert.assertTrue(myTable1.compareAndSwap(R1, C2, null, V5));
        // TableAssert.verify compare and swap result visible inside tx before commit
        TableAssert.assertRow(a(C1, V1, C2, V5), myTable1.get(R1, a(C1, C2)));
        Assert.assertArrayEquals(V1, myTable1.get(R1, C1));
        Assert.assertArrayEquals(V5, myTable1.get(R1, C2));
        Assert.assertArrayEquals(null, myTable1.get(R1, C3));
        TableAssert.assertRow(a(C1, V1, C2, V5), myTable1.get(R1));
        // these should fail
        Assert.assertFalse(myTable1.compareAndSwap(R1, C1, null, V1));
        Assert.assertFalse(myTable1.compareAndSwap(R1, C1, V2, V1));
        Assert.assertFalse(myTable1.compareAndSwap(R1, C2, null, V2));
        Assert.assertFalse(myTable1.compareAndSwap(R1, C2, V2, V1));
        // but this should succeed
        Assert.assertTrue(myTable1.compareAndSwap(R1, C2, V5, V2));
        // start new tx (doesn't see changes of the tx1)
        Transaction tx2 = txClient.startShort();
        // committing tx1 in stages to check races are handled well
        // * first, flush operations of table
        txClient.canCommitOrThrow(tx1, ((TransactionAware) myTable1).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable1).commitTx());
        // check that tx2 doesn't see changes (even though they were flushed) of tx1 by trying to compareAndSwap
        // assuming current value is null
        ((TransactionAware) myTable2).startTx(tx2);
        Assert.assertTrue(myTable2.compareAndSwap(R1, C1, null, V3));
        // start tx3 and TableAssert.verify same thing again
        Transaction tx3 = txClient.startShort();
        ((TransactionAware) myTable3).startTx(tx3);
        Assert.assertTrue(myTable3.compareAndSwap(R1, C1, null, V2));
        // * second, make tx visible
        txClient.commitOrThrow(tx1);
        // TableAssert.verify that tx2 cannot commit because of the conflicts...
        try {
            txClient.canCommitOrThrow(tx2, ((TransactionAware) myTable2).getTxChanges());
            Assert.fail("Conflict not detected!");
        } catch (TransactionConflictException e) {
        // expected
        }
        ((TransactionAware) myTable2).rollbackTx();
        txClient.abort(tx2);
        // start tx4 and TableAssert.verify that changes of tx1 are now visible
        Transaction tx4 = txClient.startShort();
        ((TransactionAware) myTable4).startTx(tx4);
        TableAssert.assertRow(a(C1, V1, C2, V2), myTable4.get(R1, a(C1, C2)));
        Assert.assertArrayEquals(V1, myTable4.get(R1, C1));
        Assert.assertArrayEquals(V2, myTable4.get(R1, C2));
        Assert.assertArrayEquals(null, myTable4.get(R1, C3));
        TableAssert.assertRow(a(C2, V2), myTable4.get(R1, a(C2)));
        TableAssert.assertRow(a(C1, V1, C2, V2), myTable4.get(R1));
        // tx3 still cannot see tx1 changes
        Assert.assertTrue(myTable3.compareAndSwap(R1, C2, null, V5));
        // and it cannot commit because its changes cause conflicts
        try {
            txClient.canCommitOrThrow(tx3, ((TransactionAware) myTable3).getTxChanges());
            Assert.fail("Conflict not detected!");
        } catch (TransactionConflictException e) {
        // expected
        }
        ((TransactionAware) myTable3).rollbackTx();
        txClient.abort(tx3);
        // TableAssert.verify we can do some ops with tx4 based on data written with tx1
        Assert.assertFalse(myTable4.compareAndSwap(R1, C1, null, V4));
        Assert.assertFalse(myTable4.compareAndSwap(R1, C2, null, V5));
        Assert.assertTrue(myTable4.compareAndSwap(R1, C1, V1, V3));
        Assert.assertTrue(myTable4.compareAndSwap(R1, C2, V2, V4));
        myTable4.delete(R1, a(C1));
        // committing tx4
        txClient.canCommitOrThrow(tx4, ((TransactionAware) myTable3).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable4).commitTx());
        txClient.commitOrThrow(tx4);
        // TableAssert.verifying the result contents in next transaction
        Transaction tx5 = txClient.startShort();
        // NOTE: table instance can be re-used in series of transactions
        ((TransactionAware) myTable4).startTx(tx5);
        TableAssert.assertRow(a(C2, V4), myTable4.get(R1, a(C1, C2)));
        Assert.assertArrayEquals(null, myTable4.get(R1, C1));
        Assert.assertArrayEquals(V4, myTable4.get(R1, C2));
        TableAssert.assertRow(a(C2, V4), myTable4.get(R1));
        txClient.canCommitOrThrow(tx5, ((TransactionAware) myTable3).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable3).commitTx());
        txClient.commitOrThrow(tx5);
    } 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) TransactionConflictException(org.apache.tephra.TransactionConflictException) Test(org.junit.Test)

Example 87 with DatasetAdmin

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

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)

Example 88 with DatasetAdmin

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

the class TableTest method testMultiIncrementWithFlush.

private void testMultiIncrementWithFlush(boolean readless) throws Exception {
    final String tableName = "incrFlush";
    DatasetProperties props = TableProperties.builder().setReadlessIncrementSupport(readless).build();
    DatasetAdmin admin = getTableAdmin(CONTEXT1, tableName, props);
    admin.create();
    Map<String, String> args = new HashMap<>();
    if (readless) {
        args.put(HBaseTable.SAFE_INCREMENTS, "true");
    }
    try (Table table = getTable(CONTEXT1, tableName, props, args);
        Table table2 = getTable(CONTEXT1, tableName, props, args)) {
        Transaction tx = txClient.startShort();
        try {
            ((TransactionAware) table).startTx(tx);
            // Write an increment, then flush it by calling commitTx.
            table.increment(new Increment(R1, C1, 10L));
            ((TransactionAware) table).commitTx();
        } finally {
            // invalidate the tx, leaving an excluded write in the table
            txClient.invalidate(tx.getTransactionId());
        }
        // validate the first write is not visible
        tx = txClient.startShort();
        try {
            ((TransactionAware) table).startTx(tx);
            Assert.assertEquals(null, table.get(new Get(R1, C1)).getLong(C1));
        } finally {
            txClient.commitOrThrow(tx);
        }
        tx = txClient.startShort();
        try {
            ((TransactionAware) table).startTx(tx);
            // Write an increment, then flush it by calling commitTx.
            table.increment(new Increment(R1, C1, 1L));
            ((TransactionAware) table).commitTx();
            // Write another increment, from both table instances
            table.increment(new Increment(R1, C1, 1L));
            if (readless) {
                ((TransactionAware) table2).startTx(tx);
                table2.increment(new Increment(R1, C1, 1L));
                ((TransactionAware) table2).commitTx();
            }
            ((TransactionAware) table).commitTx();
        } finally {
            txClient.commitOrThrow(tx);
        }
        // validate all increments are visible to a new tx
        tx = txClient.startShort();
        try {
            ((TransactionAware) table).startTx(tx);
            Assert.assertEquals(new Long(readless ? 3L : 2L), table.get(new Get(R1, C1)).getLong(C1));
        } finally {
            txClient.commitOrThrow(tx);
        }
    } finally {
        // drop table
        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) HashMap(java.util.HashMap) TransactionAware(org.apache.tephra.TransactionAware) DatasetProperties(io.cdap.cdap.api.dataset.DatasetProperties) Increment(io.cdap.cdap.api.dataset.table.Increment) Get(io.cdap.cdap.api.dataset.table.Get) DatasetAdmin(io.cdap.cdap.api.dataset.DatasetAdmin)

Example 89 with DatasetAdmin

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

the class TableTest method testBasicColumnRangeWithTx.

@Test
public void testBasicColumnRangeWithTx() throws Exception {
    // todo: test more tx logic (or add to get/put unit-test)
    DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
    admin.create();
    try (Table myTable1 = getTable(CONTEXT1, MY_TABLE);
        Table myTable2 = getTable(CONTEXT1, MY_TABLE)) {
        // write test data and commit
        Transaction tx1 = txClient.startShort();
        ((TransactionAware) myTable1).startTx(tx1);
        myTable1.put(R1, a(C1, C2, C3, C4, C5), a(V1, V2, V3, V4, V5));
        myTable1.put(R2, a(C1), a(V2));
        txClient.canCommitOrThrow(tx1, ((TransactionAware) myTable1).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable1).commitTx());
        txClient.commitOrThrow(tx1);
        // Now, we will test column range get
        Transaction tx2 = txClient.startShort();
        ((TransactionAware) myTable2).startTx(tx2);
        // bounded range
        TableAssert.assertRow(a(C2, V2, C3, V3, C4, V4), myTable2.get(R1, C2, C5, Integer.MAX_VALUE));
        // open start range
        TableAssert.assertRow(a(C1, V1, C2, V2, C3, V3), myTable2.get(R1, null, C4, Integer.MAX_VALUE));
        // open end range
        TableAssert.assertRow(a(C3, V3, C4, V4, C5, V5), myTable2.get(R1, C3, null, Integer.MAX_VALUE));
        // open ends range
        TableAssert.assertRow(a(C1, V1, C2, V2, C3, V3, C4, V4, C5, V5), myTable2.get(R1, null, null, Integer.MAX_VALUE));
        // same with limit
        // bounded range with limit
        TableAssert.assertRow(a(C2, V2), myTable2.get(R1, C2, C5, 1));
        // open start range with limit
        TableAssert.assertRow(a(C1, V1, C2, V2), myTable2.get(R1, null, C4, 2));
        // open end range with limit
        TableAssert.assertRow(a(C3, V3, C4, V4), myTable2.get(R1, C3, null, 2));
        // open ends range with limit
        TableAssert.assertRow(a(C1, V1, C2, V2, C3, V3, C4, V4), myTable2.get(R1, null, null, 4));
        // adding/changing/removing some columns
        myTable2.put(R1, a(C1, C2, C3), a(V4, V3, V2));
        myTable2.delete(R1, a(C4));
        txClient.canCommitOrThrow(tx2, ((TransactionAware) myTable2).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable2).commitTx());
        txClient.commitOrThrow(tx2);
        // Checking that changes are reflected in new scans in new tx
        Transaction tx3 = txClient.startShort();
        // NOTE: table can be re-used betweet tx
        ((TransactionAware) myTable1).startTx(tx3);
        TableAssert.assertRow(a(C2, V3, C3, V2), myTable1.get(R1, C2, C5, Integer.MAX_VALUE));
        txClient.canCommitOrThrow(tx3, ((TransactionAware) myTable1).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable1).commitTx());
        txClient.commitOrThrow(tx3);
    } 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)

Example 90 with DatasetAdmin

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

the class TableTest method testScanAndDelete.

@Test
public void testScanAndDelete() throws Exception {
    DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
    admin.create();
    try (Table myTable1 = getTable(CONTEXT1, MY_TABLE)) {
        Transaction tx1 = txClient.startShort();
        ((TransactionAware) myTable1).startTx(tx1);
        myTable1.put(Bytes.toBytes("1_09a"), a(C1), a(V1));
        txClient.canCommitOrThrow(tx1, ((TransactionAware) myTable1).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable1).commitTx());
        txClient.commitOrThrow(tx1);
        // 
        Transaction tx2 = txClient.startShort();
        ((TransactionAware) myTable1).startTx(tx2);
        myTable1.delete(Bytes.toBytes("1_09a"));
        myTable1.put(Bytes.toBytes("1_08a"), a(C1), a(V1));
        myTable1.put(Bytes.toBytes("1_09b"), a(C1), a(V1));
        txClient.canCommitOrThrow(tx2, ((TransactionAware) myTable1).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable1).commitTx());
        txClient.commitOrThrow(tx2);
        // 
        Transaction tx3 = txClient.startShort();
        ((TransactionAware) myTable1).startTx(tx3);
        TableAssert.assertScan(a(Bytes.toBytes("1_08a"), Bytes.toBytes("1_09b")), aa(a(C1, V1), a(C1, V1)), myTable1, new Scan(Bytes.toBytes("1_"), Bytes.toBytes("2_")));
        myTable1.delete(Bytes.toBytes("1_08a"));
        myTable1.put(Bytes.toBytes("1_07a"), a(C1), a(V1));
        myTable1.delete(Bytes.toBytes("1_09b"));
        myTable1.put(Bytes.toBytes("1_08b"), a(C1), a(V1));
        myTable1.put(Bytes.toBytes("1_09c"), a(C1), a(V1));
        txClient.canCommitOrThrow(tx3, ((TransactionAware) myTable1).getTxChanges());
        Assert.assertTrue(((TransactionAware) myTable1).commitTx());
        txClient.commitOrThrow(tx3);
        // Now, we will test scans
        Transaction tx4 = txClient.startShort();
        ((TransactionAware) myTable1).startTx(tx4);
        TableAssert.assertScan(a(Bytes.toBytes("1_07a"), Bytes.toBytes("1_08b"), Bytes.toBytes("1_09c")), aa(a(C1, V1), a(C1, V1), a(C1, V1)), myTable1, new Scan(Bytes.toBytes("1_"), Bytes.toBytes("2_")));
    } 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) Scan(io.cdap.cdap.api.dataset.table.Scan) 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