Search in sources :

Example 6 with Status

use of org.apache.accumulo.core.client.ConditionalWriter.Status in project accumulo-examples by apache.

the class ARS method reserve.

public ReservationResult reserve(String what, String when, String who) throws Exception {
    String row = what + ":" + when;
    // EXCERCISE This code assumes there is no reservation and tries to create one. If a reservation exist then the update will fail. This is a good strategy
    // when it is expected there are usually no reservations. Could modify the code to scan first.
    // The following mutation requires that the column tx:seq does not exist and will fail if it does.
    ConditionalMutation update = new ConditionalMutation(row, new Condition("tx", "seq"));
    update.put("tx", "seq", "0");
    update.put("res", String.format("%04d", 0), who);
    ReservationResult result = ReservationResult.RESERVED;
    // it is important to use an isolated scanner so that only whole mutations are seen
    try (ConditionalWriter cwriter = conn.createConditionalWriter(rTable, new ConditionalWriterConfig());
        Scanner scanner = new IsolatedScanner(conn.createScanner(rTable, Authorizations.EMPTY))) {
        while (true) {
            Status status = cwriter.write(update).getStatus();
            switch(status) {
                case ACCEPTED:
                    return result;
                case REJECTED:
                case UNKNOWN:
                    // read the row and decide what to do
                    break;
                default:
                    throw new RuntimeException("Unexpected status " + status);
            }
            // EXCERCISE in the case of many threads trying to reserve a slot, this approach of immediately retrying is inefficient. Exponential back-off is good
            // general solution to solve contention problems like this. However in this particular case, exponential back-off could penalize the earliest threads
            // that attempted to make a reservation by putting them later in the list. A more complex solution could involve having independent sub-queues within
            // the row that approximately maintain arrival order and use exponential back off to fairly merge the sub-queues into the main queue.
            scanner.setRange(new Range(row));
            int seq = -1;
            int maxReservation = -1;
            for (Entry<Key, Value> entry : scanner) {
                String cf = entry.getKey().getColumnFamilyData().toString();
                String cq = entry.getKey().getColumnQualifierData().toString();
                String val = entry.getValue().toString();
                if (cf.equals("tx") && cq.equals("seq")) {
                    seq = Integer.parseInt(val);
                } else if (cf.equals("res")) {
                    // data differently in Accumulo so that finding the reserver could be done quickly.
                    if (val.equals(who))
                        if (maxReservation == -1)
                            // already have the first reservation
                            return ReservationResult.RESERVED;
                        else
                            // already on wait list
                            return ReservationResult.WAIT_LISTED;
                    // EXCERCISE the way this code finds the max reservation is very inefficient.... it would be better if it did not have to scan the entire row.
                    // One possibility is to just use the sequence number. Could also consider sorting the data in another way and/or using an iterator.
                    maxReservation = Integer.parseInt(cq);
                }
            }
            Condition condition = new Condition("tx", "seq");
            if (seq >= 0)
                // only expect a seq # if one was seen
                condition.setValue(seq + "");
            update = new ConditionalMutation(row, condition);
            update.put("tx", "seq", (seq + 1) + "");
            update.put("res", String.format("%04d", maxReservation + 1), who);
            // EXCERCISE if set capacity is implemented, then result should take capacity into account
            if (maxReservation == -1)
                // if successful, will be first reservation
                result = ReservationResult.RESERVED;
            else
                result = ReservationResult.WAIT_LISTED;
        }
    }
}
Also used : Condition(org.apache.accumulo.core.data.Condition) Status(org.apache.accumulo.core.client.ConditionalWriter.Status) IsolatedScanner(org.apache.accumulo.core.client.IsolatedScanner) Scanner(org.apache.accumulo.core.client.Scanner) Range(org.apache.accumulo.core.data.Range) ConditionalWriter(org.apache.accumulo.core.client.ConditionalWriter) ConditionalMutation(org.apache.accumulo.core.data.ConditionalMutation) Value(org.apache.accumulo.core.data.Value) ConditionalWriterConfig(org.apache.accumulo.core.client.ConditionalWriterConfig) IsolatedScanner(org.apache.accumulo.core.client.IsolatedScanner) Key(org.apache.accumulo.core.data.Key)

Example 7 with Status

use of org.apache.accumulo.core.client.ConditionalWriter.Status in project accumulo by apache.

the class ConditionalWriterIT method testSecurity.

@Test
public void testSecurity() throws Exception {
    // test against table user does not have read and/or write permissions for
    Connector conn = getConnector();
    String user = null;
    ClientConfiguration clientConf = cluster.getClientConfig();
    final boolean saslEnabled = clientConf.hasSasl();
    // Create a new user
    ClusterUser user1 = getUser(0);
    user = user1.getPrincipal();
    if (saslEnabled) {
        conn.securityOperations().createLocalUser(user, null);
    } else {
        conn.securityOperations().createLocalUser(user, new PasswordToken(user1.getPassword()));
    }
    String[] tables = getUniqueNames(3);
    String table1 = tables[0], table2 = tables[1], table3 = tables[2];
    // Create three tables
    conn.tableOperations().create(table1);
    conn.tableOperations().create(table2);
    conn.tableOperations().create(table3);
    // Grant R on table1, W on table2, R/W on table3
    conn.securityOperations().grantTablePermission(user, table1, TablePermission.READ);
    conn.securityOperations().grantTablePermission(user, table2, TablePermission.WRITE);
    conn.securityOperations().grantTablePermission(user, table3, TablePermission.READ);
    conn.securityOperations().grantTablePermission(user, table3, TablePermission.WRITE);
    // Login as the user
    Connector conn2 = conn.getInstance().getConnector(user, user1.getToken());
    ConditionalMutation cm1 = new ConditionalMutation("r1", new Condition("tx", "seq"));
    cm1.put("tx", "seq", "1");
    cm1.put("data", "x", "a");
    try (ConditionalWriter cw1 = conn2.createConditionalWriter(table1, new ConditionalWriterConfig());
        ConditionalWriter cw2 = conn2.createConditionalWriter(table2, new ConditionalWriterConfig());
        ConditionalWriter cw3 = conn2.createConditionalWriter(table3, new ConditionalWriterConfig())) {
        // Should be able to conditional-update a table we have R/W on
        Assert.assertEquals(Status.ACCEPTED, cw3.write(cm1).getStatus());
        // Conditional-update to a table we only have read on should fail
        try {
            Status status = cw1.write(cm1).getStatus();
            Assert.fail("Expected exception writing conditional mutation to table the user doesn't have write access to, Got status: " + status);
        } catch (AccumuloSecurityException ase) {
        }
        // Conditional-update to a table we only have writer on should fail
        try {
            Status status = cw2.write(cm1).getStatus();
            Assert.fail("Expected exception writing conditional mutation to table the user doesn't have read access to. Got status: " + status);
        } catch (AccumuloSecurityException ase) {
        }
    }
}
Also used : Condition(org.apache.accumulo.core.data.Condition) Status(org.apache.accumulo.core.client.ConditionalWriter.Status) Connector(org.apache.accumulo.core.client.Connector) ConditionalWriter(org.apache.accumulo.core.client.ConditionalWriter) PasswordToken(org.apache.accumulo.core.client.security.tokens.PasswordToken) ConditionalMutation(org.apache.accumulo.core.data.ConditionalMutation) ClusterUser(org.apache.accumulo.cluster.ClusterUser) ConditionalWriterConfig(org.apache.accumulo.core.client.ConditionalWriterConfig) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) ClientConfiguration(org.apache.accumulo.core.client.ClientConfiguration) Test(org.junit.Test)

Example 8 with Status

use of org.apache.accumulo.core.client.ConditionalWriter.Status in project accumulo by apache.

the class ConditionalWriterIT method testBadColVis.

@Test
public void testBadColVis() throws Exception {
    // test when a user sets a col vis in a condition that can never be seen
    Connector conn = getConnector();
    String tableName = getUniqueNames(1)[0];
    conn.tableOperations().create(tableName);
    Authorizations auths = new Authorizations("A", "B");
    conn.securityOperations().changeUserAuthorizations(getAdminPrincipal(), auths);
    Authorizations filteredAuths = new Authorizations("A");
    ColumnVisibility cva = new ColumnVisibility("A");
    ColumnVisibility cvb = new ColumnVisibility("B");
    ColumnVisibility cvc = new ColumnVisibility("C");
    try (ConditionalWriter cw = conn.createConditionalWriter(tableName, new ConditionalWriterConfig().setAuthorizations(filteredAuths))) {
        // User has authorization, but didn't include it in the writer
        ConditionalMutation cm0 = new ConditionalMutation("99006", new Condition("tx", "seq").setVisibility(cvb));
        cm0.put("name", "last", cva, "doe");
        cm0.put("name", "first", cva, "john");
        cm0.put("tx", "seq", cva, "1");
        Assert.assertEquals(Status.INVISIBLE_VISIBILITY, cw.write(cm0).getStatus());
        ConditionalMutation cm1 = new ConditionalMutation("99006", new Condition("tx", "seq").setVisibility(cvb).setValue("1"));
        cm1.put("name", "last", cva, "doe");
        cm1.put("name", "first", cva, "john");
        cm1.put("tx", "seq", cva, "1");
        Assert.assertEquals(Status.INVISIBLE_VISIBILITY, cw.write(cm1).getStatus());
        // User does not have the authorization
        ConditionalMutation cm2 = new ConditionalMutation("99006", new Condition("tx", "seq").setVisibility(cvc));
        cm2.put("name", "last", cva, "doe");
        cm2.put("name", "first", cva, "john");
        cm2.put("tx", "seq", cva, "1");
        Assert.assertEquals(Status.INVISIBLE_VISIBILITY, cw.write(cm2).getStatus());
        ConditionalMutation cm3 = new ConditionalMutation("99006", new Condition("tx", "seq").setVisibility(cvc).setValue("1"));
        cm3.put("name", "last", cva, "doe");
        cm3.put("name", "first", cva, "john");
        cm3.put("tx", "seq", cva, "1");
        Assert.assertEquals(Status.INVISIBLE_VISIBILITY, cw.write(cm3).getStatus());
        // if any visibility is bad, good visibilities don't override
        ConditionalMutation cm4 = new ConditionalMutation("99006", new Condition("tx", "seq").setVisibility(cvb), new Condition("tx", "seq").setVisibility(cva));
        cm4.put("name", "last", cva, "doe");
        cm4.put("name", "first", cva, "john");
        cm4.put("tx", "seq", cva, "1");
        Assert.assertEquals(Status.INVISIBLE_VISIBILITY, cw.write(cm4).getStatus());
        ConditionalMutation cm5 = new ConditionalMutation("99006", new Condition("tx", "seq").setVisibility(cvb).setValue("1"), new Condition("tx", "seq").setVisibility(cva).setValue("1"));
        cm5.put("name", "last", cva, "doe");
        cm5.put("name", "first", cva, "john");
        cm5.put("tx", "seq", cva, "1");
        Assert.assertEquals(Status.INVISIBLE_VISIBILITY, cw.write(cm5).getStatus());
        ConditionalMutation cm6 = new ConditionalMutation("99006", new Condition("tx", "seq").setVisibility(cvb).setValue("1"), new Condition("tx", "seq").setVisibility(cva));
        cm6.put("name", "last", cva, "doe");
        cm6.put("name", "first", cva, "john");
        cm6.put("tx", "seq", cva, "1");
        Assert.assertEquals(Status.INVISIBLE_VISIBILITY, cw.write(cm6).getStatus());
        ConditionalMutation cm7 = new ConditionalMutation("99006", new Condition("tx", "seq").setVisibility(cvb), new Condition("tx", "seq").setVisibility(cva).setValue("1"));
        cm7.put("name", "last", cva, "doe");
        cm7.put("name", "first", cva, "john");
        cm7.put("tx", "seq", cva, "1");
        Assert.assertEquals(Status.INVISIBLE_VISIBILITY, cw.write(cm7).getStatus());
    }
    // test passing auths that exceed users configured auths
    Authorizations exceedingAuths = new Authorizations("A", "B", "D");
    try (ConditionalWriter cw2 = conn.createConditionalWriter(tableName, new ConditionalWriterConfig().setAuthorizations(exceedingAuths))) {
        ConditionalMutation cm8 = new ConditionalMutation("99006", new Condition("tx", "seq").setVisibility(cvb), new Condition("tx", "seq").setVisibility(cva).setValue("1"));
        cm8.put("name", "last", cva, "doe");
        cm8.put("name", "first", cva, "john");
        cm8.put("tx", "seq", cva, "1");
        try {
            Status status = cw2.write(cm8).getStatus();
            Assert.fail("Writing mutation with Authorizations the user doesn't have should fail. Got status: " + status);
        } catch (AccumuloSecurityException ase) {
        // expected, check specific failure?
        }
    }
}
Also used : Condition(org.apache.accumulo.core.data.Condition) Status(org.apache.accumulo.core.client.ConditionalWriter.Status) Connector(org.apache.accumulo.core.client.Connector) ConditionalWriter(org.apache.accumulo.core.client.ConditionalWriter) Authorizations(org.apache.accumulo.core.security.Authorizations) ConditionalMutation(org.apache.accumulo.core.data.ConditionalMutation) ConditionalWriterConfig(org.apache.accumulo.core.client.ConditionalWriterConfig) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) ColumnVisibility(org.apache.accumulo.core.security.ColumnVisibility) Test(org.junit.Test)

Example 9 with Status

use of org.apache.accumulo.core.client.ConditionalWriter.Status in project accumulo by apache.

the class ConditionalWriterIT method testSameRow.

@Test
public void testSameRow() throws Exception {
    // test multiple mutations for same row in same batch
    Connector conn = getConnector();
    String tableName = getUniqueNames(1)[0];
    conn.tableOperations().create(tableName);
    try (ConditionalWriter cw = conn.createConditionalWriter(tableName, new ConditionalWriterConfig())) {
        ConditionalMutation cm1 = new ConditionalMutation("r1", new Condition("tx", "seq"));
        cm1.put("tx", "seq", "1");
        cm1.put("data", "x", "a");
        Assert.assertEquals(Status.ACCEPTED, cw.write(cm1).getStatus());
        ConditionalMutation cm2 = new ConditionalMutation("r1", new Condition("tx", "seq").setValue("1"));
        cm2.put("tx", "seq", "2");
        cm2.put("data", "x", "b");
        ConditionalMutation cm3 = new ConditionalMutation("r1", new Condition("tx", "seq").setValue("1"));
        cm3.put("tx", "seq", "2");
        cm3.put("data", "x", "c");
        ConditionalMutation cm4 = new ConditionalMutation("r1", new Condition("tx", "seq").setValue("1"));
        cm4.put("tx", "seq", "2");
        cm4.put("data", "x", "d");
        Iterator<Result> results = cw.write(Arrays.asList(cm2, cm3, cm4).iterator());
        int accepted = 0;
        int rejected = 0;
        int total = 0;
        while (results.hasNext()) {
            Status status = results.next().getStatus();
            if (status == Status.ACCEPTED)
                accepted++;
            if (status == Status.REJECTED)
                rejected++;
            total++;
        }
        Assert.assertEquals("Expected one accepted result", 1, accepted);
        Assert.assertEquals("Expected two rejected results", 2, rejected);
        Assert.assertEquals("Expected three total results", 3, total);
    }
}
Also used : Condition(org.apache.accumulo.core.data.Condition) Status(org.apache.accumulo.core.client.ConditionalWriter.Status) Connector(org.apache.accumulo.core.client.Connector) ConditionalWriter(org.apache.accumulo.core.client.ConditionalWriter) ConditionalMutation(org.apache.accumulo.core.data.ConditionalMutation) ConditionalWriterConfig(org.apache.accumulo.core.client.ConditionalWriterConfig) AlphaNumKeyConstraint(org.apache.accumulo.test.constraints.AlphaNumKeyConstraint) Result(org.apache.accumulo.core.client.ConditionalWriter.Result) Test(org.junit.Test)

Example 10 with Status

use of org.apache.accumulo.core.client.ConditionalWriter.Status in project accumulo by apache.

the class ConditionalWriterIT method testError.

@Test
public void testError() throws Exception {
    String table = getUniqueNames(1)[0];
    Connector conn = getConnector();
    conn.tableOperations().create(table);
    try (ConditionalWriter cw = conn.createConditionalWriter(table, new ConditionalWriterConfig())) {
        IteratorSetting iterSetting = new IteratorSetting(5, BadIterator.class);
        ConditionalMutation cm1 = new ConditionalMutation("r1", new Condition("tx", "seq").setIterators(iterSetting));
        cm1.put("tx", "seq", "1");
        cm1.put("data", "x", "a");
        Result result = cw.write(cm1);
        try {
            Status status = result.getStatus();
            Assert.fail("Expected exception using iterator which throws an error, Got status: " + status);
        } catch (AccumuloException ae) {
        }
    }
}
Also used : Condition(org.apache.accumulo.core.data.Condition) Status(org.apache.accumulo.core.client.ConditionalWriter.Status) Connector(org.apache.accumulo.core.client.Connector) ConditionalWriter(org.apache.accumulo.core.client.ConditionalWriter) AccumuloException(org.apache.accumulo.core.client.AccumuloException) ConditionalMutation(org.apache.accumulo.core.data.ConditionalMutation) IteratorSetting(org.apache.accumulo.core.client.IteratorSetting) ConditionalWriterConfig(org.apache.accumulo.core.client.ConditionalWriterConfig) Result(org.apache.accumulo.core.client.ConditionalWriter.Result) Test(org.junit.Test)

Aggregations

ConditionalWriter (org.apache.accumulo.core.client.ConditionalWriter)10 Status (org.apache.accumulo.core.client.ConditionalWriter.Status)10 ConditionalWriterConfig (org.apache.accumulo.core.client.ConditionalWriterConfig)10 Condition (org.apache.accumulo.core.data.Condition)10 ConditionalMutation (org.apache.accumulo.core.data.ConditionalMutation)10 Connector (org.apache.accumulo.core.client.Connector)8 Test (org.junit.Test)8 Result (org.apache.accumulo.core.client.ConditionalWriter.Result)6 IsolatedScanner (org.apache.accumulo.core.client.IsolatedScanner)4 Scanner (org.apache.accumulo.core.client.Scanner)4 Key (org.apache.accumulo.core.data.Key)4 Range (org.apache.accumulo.core.data.Range)4 Value (org.apache.accumulo.core.data.Value)4 AccumuloException (org.apache.accumulo.core.client.AccumuloException)3 IteratorSetting (org.apache.accumulo.core.client.IteratorSetting)3 Authorizations (org.apache.accumulo.core.security.Authorizations)3 HashMap (java.util.HashMap)2 AccumuloSecurityException (org.apache.accumulo.core.client.AccumuloSecurityException)2 BatchWriter (org.apache.accumulo.core.client.BatchWriter)2 BatchWriterConfig (org.apache.accumulo.core.client.BatchWriterConfig)2