Search in sources :

Example 11 with Condition

use of org.apache.accumulo.core.data.Condition in project accumulo by apache.

the class ConditionalWriterIT method testOffline.

@Test
public void testOffline() throws Exception {
    String table = getUniqueNames(1)[0];
    Connector conn = getConnector();
    conn.tableOperations().create(table);
    try (ConditionalWriter cw = conn.createConditionalWriter(table, new ConditionalWriterConfig())) {
        conn.tableOperations().offline(table, true);
        ConditionalMutation cm1 = new ConditionalMutation("r1", new Condition("tx", "seq"));
        cm1.put("tx", "seq", "1");
        cm1.put("data", "x", "a");
        Result result = cw.write(cm1);
        try {
            Status status = result.getStatus();
            Assert.fail("Expected exception writing conditional mutation to offline table. Got status: " + status);
        } catch (AccumuloException ae) {
            Assert.assertEquals(TableOfflineException.class, ae.getCause().getClass());
        }
        try {
            conn.createConditionalWriter(table, new ConditionalWriterConfig());
            Assert.fail("Expected exception creating conditional writer to offline table");
        } catch (TableOfflineException e) {
        }
    }
}
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) TableOfflineException(org.apache.accumulo.core.client.TableOfflineException) ConditionalWriterConfig(org.apache.accumulo.core.client.ConditionalWriterConfig) Result(org.apache.accumulo.core.client.ConditionalWriter.Result) Test(org.junit.Test)

Example 12 with Condition

use of org.apache.accumulo.core.data.Condition in project accumulo-examples by apache.

the class ARS method cancel.

public void cancel(String what, String when, String who) throws Exception {
    String row = what + ":" + when;
    // its 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) {
            scanner.setRange(new Range(row));
            int seq = -1;
            String reservation = null;
            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") && val.equals(who)) {
                    reservation = cq;
                }
            }
            if (reservation != null) {
                ConditionalMutation update = new ConditionalMutation(row, new Condition("tx", "seq").setValue(seq + ""));
                update.putDelete("res", reservation);
                update.put("tx", "seq", (seq + 1) + "");
                Status status = cwriter.write(update).getStatus();
                switch(status) {
                    case ACCEPTED:
                        // successfully canceled reservation
                        return;
                    case REJECTED:
                    case UNKNOWN:
                        // EXCERCISE exponential back-off could be used here
                        break;
                    default:
                        throw new RuntimeException("Unexpected status " + status);
                }
            } else {
                // not reserved, nothing to do
                break;
            }
        }
    }
}
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 13 with Condition

use of org.apache.accumulo.core.data.Condition 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 14 with Condition

use of org.apache.accumulo.core.data.Condition in project incubator-rya by apache.

the class AccumuloRyaInstanceDetailsRepository method update.

@Override
public void update(final RyaDetails oldDetails, final RyaDetails newDetails) throws NotInitializedException, ConcurrentUpdateException, RyaDetailsRepositoryException {
    // Preconditions.
    requireNonNull(oldDetails);
    requireNonNull(newDetails);
    if (!newDetails.getRyaInstanceName().equals(instanceName)) {
        throw new RyaDetailsRepositoryException("The instance name that was in the provided 'newDetails' does not match " + "the instance name that this repository is connected to. Make sure you're connected to the" + "correct Rya instance.");
    }
    if (!isInitialized()) {
        throw new NotInitializedException("Could not update the details for the Rya instanced named '" + instanceName + "' because it has not been initialized yet.");
    }
    // Use a conditional writer so that we can detect when the old details
    // are no longer the currently stored ones.
    ConditionalWriter writer = null;
    try {
        // Setup the condition that ensures the details have not changed since the edits were made.
        final byte[] oldDetailsBytes = serializer.serialize(oldDetails);
        final Condition condition = new Condition(COL_FAMILY, COL_QUALIFIER);
        condition.setValue(oldDetailsBytes);
        // Create the mutation that only performs the update if the details haven't changed.
        final ConditionalMutation mutation = new ConditionalMutation(ROW_ID);
        mutation.addCondition(condition);
        final byte[] newDetailsBytes = serializer.serialize(newDetails);
        mutation.put(COL_FAMILY, COL_QUALIFIER, new Value(newDetailsBytes));
        // Do the write.
        writer = connector.createConditionalWriter(detailsTableName, new ConditionalWriterConfig());
        final Result result = writer.write(mutation);
        switch(result.getStatus()) {
            case REJECTED:
            case VIOLATED:
                throw new ConcurrentUpdateException("Could not update the details for the Rya instance named '" + instanceName + "' because the old value is out of date.");
            case UNKNOWN:
            case INVISIBLE_VISIBILITY:
                throw new RyaDetailsRepositoryException("Could not update the details for the Rya instance named '" + instanceName + "'.");
        }
    } catch (final TableNotFoundException | AccumuloException | AccumuloSecurityException e) {
        throw new RyaDetailsRepositoryException("Could not update the details for the Rya instance named '" + instanceName + "'.");
    } finally {
        if (writer != null) {
            writer.close();
        }
    }
}
Also used : Condition(org.apache.accumulo.core.data.Condition) AccumuloException(org.apache.accumulo.core.client.AccumuloException) Result(org.apache.accumulo.core.client.ConditionalWriter.Result) ConditionalWriter(org.apache.accumulo.core.client.ConditionalWriter) TableNotFoundException(org.apache.accumulo.core.client.TableNotFoundException) ConditionalMutation(org.apache.accumulo.core.data.ConditionalMutation) Value(org.apache.accumulo.core.data.Value) ConditionalWriterConfig(org.apache.accumulo.core.client.ConditionalWriterConfig) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException)

Example 15 with Condition

use of org.apache.accumulo.core.data.Condition in project accumulo by apache.

the class ConditionalWriterIT method testConstraints.

@Test
public void testConstraints() throws Exception {
    // ensure constraint violations are properly reported
    Connector conn = getConnector();
    String tableName = getUniqueNames(1)[0];
    conn.tableOperations().create(tableName);
    conn.tableOperations().addConstraint(tableName, AlphaNumKeyConstraint.class.getName());
    conn.tableOperations().clone(tableName, tableName + "_clone", true, new HashMap<>(), new HashSet<>());
    try (ConditionalWriter cw = conn.createConditionalWriter(tableName + "_clone", new ConditionalWriterConfig());
        Scanner scanner = conn.createScanner(tableName + "_clone", new Authorizations())) {
        ConditionalMutation cm0 = new ConditionalMutation("99006+", new Condition("tx", "seq"));
        cm0.put("tx", "seq", "1");
        Assert.assertEquals(Status.VIOLATED, cw.write(cm0).getStatus());
        Assert.assertFalse("Should find no results in the table is mutation result was violated", scanner.iterator().hasNext());
        ConditionalMutation cm1 = new ConditionalMutation("99006", new Condition("tx", "seq"));
        cm1.put("tx", "seq", "1");
        Assert.assertEquals(Status.ACCEPTED, cw.write(cm1).getStatus());
        Assert.assertTrue("Accepted result should be returned when reading table", scanner.iterator().hasNext());
    }
}
Also used : Condition(org.apache.accumulo.core.data.Condition) Connector(org.apache.accumulo.core.client.Connector) ConditionalWriter(org.apache.accumulo.core.client.ConditionalWriter) IsolatedScanner(org.apache.accumulo.core.client.IsolatedScanner) Scanner(org.apache.accumulo.core.client.Scanner) Authorizations(org.apache.accumulo.core.security.Authorizations) ConditionalMutation(org.apache.accumulo.core.data.ConditionalMutation) ConditionalWriterConfig(org.apache.accumulo.core.client.ConditionalWriterConfig) AlphaNumKeyConstraint(org.apache.accumulo.test.constraints.AlphaNumKeyConstraint) Test(org.junit.Test)

Aggregations

Condition (org.apache.accumulo.core.data.Condition)23 ConditionalMutation (org.apache.accumulo.core.data.ConditionalMutation)21 ConditionalWriter (org.apache.accumulo.core.client.ConditionalWriter)20 ConditionalWriterConfig (org.apache.accumulo.core.client.ConditionalWriterConfig)19 Connector (org.apache.accumulo.core.client.Connector)17 Test (org.junit.Test)17 IsolatedScanner (org.apache.accumulo.core.client.IsolatedScanner)11 Scanner (org.apache.accumulo.core.client.Scanner)11 Value (org.apache.accumulo.core.data.Value)11 Result (org.apache.accumulo.core.client.ConditionalWriter.Result)10 Status (org.apache.accumulo.core.client.ConditionalWriter.Status)10 Key (org.apache.accumulo.core.data.Key)9 Range (org.apache.accumulo.core.data.Range)8 Authorizations (org.apache.accumulo.core.security.Authorizations)7 Text (org.apache.hadoop.io.Text)7 AccumuloException (org.apache.accumulo.core.client.AccumuloException)5 ColumnVisibility (org.apache.accumulo.core.security.ColumnVisibility)5 AlphaNumKeyConstraint (org.apache.accumulo.test.constraints.AlphaNumKeyConstraint)5 ArrayList (java.util.ArrayList)4 AccumuloSecurityException (org.apache.accumulo.core.client.AccumuloSecurityException)4