类com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue源码实例Demo

下面列出了怎么用com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue的API类实例代码及写法,或者点击链接到github查看源代码。

源代码1 项目: strongbox   文件: GenericDynamoDB.java
@Override
public void create(Entry entry) {
    readWriteLock.writeLock().lock();

    try {
        Map<String, AttributeValue> keys = createKey(entry);
        Map<String, AttributeValueUpdate> attributes = createAttributes(entry);
        Map<String, ExpectedAttributeValue> expected = expectNotExists();

        try {
            executeUpdate(keys, attributes, expected);
        } catch (ConditionalCheckFailedException e) {
            throw new AlreadyExistsException("DynamoDB store entry already exists:" + keys.toString());
        }
    } finally {
        readWriteLock.writeLock().unlock();
    }
}
 
源代码2 项目: strongbox   文件: GenericDynamoDB.java
@Override
public void update(Entry entry, Entry existingEntry) {
    readWriteLock.writeLock().lock();

    try {
        Map<String, AttributeValue> keys = createKey(entry);
        Map<String, AttributeValueUpdate> attributes = createAttributes(entry);
        Map<String, ExpectedAttributeValue> expected = expectExists(existingEntry);

        try {
            executeUpdate(keys, attributes, expected);
        } catch (ConditionalCheckFailedException e) {
            throw new DoesNotExistException("Precondition to update entry in DynamoDB failed:" + keys.toString());
        }
    } finally {
        readWriteLock.writeLock().unlock();
    }

}
 
private void addExpectedValueIfPresent(final StaticBuffer column, final Map<String, ExpectedAttributeValue> expectedValueMap) {
    final String dynamoDbColumn = encodeKeyBuffer(column);

    if (expectedValueMap.containsKey(dynamoDbColumn)) {
        return;
    }

    if (transaction.contains(store, key, column)) {
        final StaticBuffer expectedValue = transaction.get(store, key, column);
        final ExpectedAttributeValue expectedAttributeValue;
        if (expectedValue == null) {
            expectedAttributeValue = new ExpectedAttributeValue().withExists(false);
        } else {
            final AttributeValue attributeValue = encodeValue(expectedValue);
            expectedAttributeValue = new ExpectedAttributeValue().withValue(attributeValue)
                                                                 .withComparisonOperator(ComparisonOperator.EQ);
        }
        expectedValueMap.put(dynamoDbColumn, expectedAttributeValue);
    }
}
 
源代码4 项目: aws-dynamodb-encryption-java   文件: MetaStore.java
/**
 * Create a new MetaStore with specified table name and extra data supplier.
 *
 * @param ddb Interface for accessing DynamoDB.
 * @param tableName DynamoDB table name for this {@link MetaStore}.
 * @param encryptor used to perform crypto operations on the record attributes
 * @param extraDataSupplier provides extra data that should be stored along with the material.
 */
public MetaStore(final AmazonDynamoDB ddb, final String tableName,
        final DynamoDBEncryptor encryptor, final ExtraDataSupplier extraDataSupplier) {
    this.ddb = checkNotNull(ddb, "ddb must not be null");
    this.tableName = checkNotNull(tableName, "tableName must not be null");
    this.encryptor = checkNotNull(encryptor, "encryptor must not be null");
    this.extraDataSupplier = checkNotNull(extraDataSupplier, "extraDataSupplier must not be null");

    this.ddbCtx = new EncryptionContext.Builder().withTableName(this.tableName)
            .withHashKeyName(DEFAULT_HASH_KEY).withRangeKeyName(DEFAULT_RANGE_KEY).build();

    final Map<String, ExpectedAttributeValue> tmpExpected = new HashMap<>();
    tmpExpected.put(DEFAULT_HASH_KEY, new ExpectedAttributeValue().withExists(false));
    tmpExpected.put(DEFAULT_RANGE_KEY, new ExpectedAttributeValue().withExists(false));
    doesNotExist = Collections.unmodifiableMap(tmpExpected);

    this.doNotEncrypt = getSignedOnlyFields(extraDataSupplier);
}
 
源代码5 项目: dynamodb-transactions   文件: TransactionItem.java
/**
 * Inserts a new transaction item into the table.  Assumes txKey is already initialized.
 * @return the txItem
 * @throws TransactionException if the transaction already exists
 */
private Map<String, AttributeValue> insert() {
    Map<String, AttributeValue> item = new HashMap<String, AttributeValue>();
    item.put(AttributeName.STATE.toString(), new AttributeValue(STATE_PENDING));
    item.put(AttributeName.VERSION.toString(), new AttributeValue().withN(Integer.toString(1)));
    item.put(AttributeName.DATE.toString(), txManager.getCurrentTimeAttribute());
    item.putAll(txKey);
    
    Map<String, ExpectedAttributeValue> expectNotExists = new HashMap<String, ExpectedAttributeValue>(2);
    expectNotExists.put(AttributeName.TXID.toString(), new ExpectedAttributeValue(false));
    expectNotExists.put(AttributeName.STATE.toString(), new ExpectedAttributeValue(false));
    
    PutItemRequest request = new PutItemRequest()
        .withTableName(txManager.getTransactionTableName())
        .withItem(item)
        .withExpected(expectNotExists);
    
    try {
        txManager.getClient().putItem(request);
        return item;
    } catch (ConditionalCheckFailedException e) {
        throw new TransactionException("Failed to create new transaction with id " + txId, e);
    }
}
 
/**
 * Checks a map of expected values against a map of actual values in a way
 * that's compatible with how the DynamoDB service interprets the Expected
 * parameter of PutItem, UpdateItem and DeleteItem.
 *
 * @param expectedValues
 *            A description of the expected values.
 * @param item
 *            The actual values.
 * @throws ConditionalCheckFailedException
 *             Thrown if the values do not match the expected values.
 */
public static void checkExpectedValues(Map<String, ExpectedAttributeValue> expectedValues, Map<String, AttributeValue> item) {
    for (Map.Entry<String, ExpectedAttributeValue> entry : expectedValues.entrySet()) {
        // if the attribute is expected to exist (null for isExists means
        // true)
        if ((entry.getValue().isExists() == null || entry.getValue().isExists() == true)
                // but the item doesn't
                && (item == null
                        // or the attribute doesn't
                        || item.get(entry.getKey()) == null
                        // or it doesn't have the expected value
                        || !expectedValueMatches(entry.getValue().getValue(), item.get(entry.getKey())))) {
            throw new ConditionalCheckFailedException(
                    "expected attribute(s) " + expectedValues
                            + " but found " + item);
        } else if (entry.getValue().isExists() != null
                && !entry.getValue().isExists()
                && item != null && item.get(entry.getKey()) != null) {
            // the attribute isn't expected to exist, but the item exists
            // and the attribute does too
            throw new ConditionalCheckFailedException(
                    "expected attribute(s) " + expectedValues
                            + " but found " + item);
        }
    }
}
 
源代码7 项目: strongbox   文件: GenericDynamoDB.java
private void executeUpdate(Map<String, AttributeValue> keys, Map<String, AttributeValueUpdate> attributes, Map<String, ExpectedAttributeValue> expected) {
    UpdateItemRequest updateEntry = new UpdateItemRequest()
            .withTableName(tableName)
            .withKey(keys)
            .withAttributeUpdates(attributes)
            .withExpected(expected);

    client.updateItem(updateEntry);
}
 
源代码8 项目: strongbox   文件: GenericDynamoDB.java
private Map<String, ExpectedAttributeValue> expectExists(Entry entry) {
    Map<String, ExpectedAttributeValue> expected = new HashMap<>();

    ExpectedAttributeValue expectedAttributeValue = new ExpectedAttributeValue(true);
    expectedAttributeValue.setValue(new AttributeValue(getPartitionKeyValue(entry)));
    expected.put(partitionKeyName.toString(), expectedAttributeValue);

    // FIXME: hardcode whole file, or make generic
    ExpectedAttributeValue expectedSha = new ExpectedAttributeValue(true);
    expectedSha.setValue(new AttributeValue(sha(entry)));
    expected.put(OPTIMISTIC_LOCK_FIELD_NAME, expectedSha);

    return expected;
}
 
@Override
public Collection<MutateWorker> createMutationWorkers(final Map<StaticBuffer, KCVMutation> mutationMap, final DynamoDbStoreTransaction txh) {

    final List<MutateWorker> workers = Lists.newLinkedList();

    for (Map.Entry<StaticBuffer, KCVMutation> entry : mutationMap.entrySet()) {
        final StaticBuffer hashKey = entry.getKey();
        final KCVMutation mutation = entry.getValue();

        final Map<String, AttributeValue> key = new ItemBuilder().hashKey(hashKey)
                                                           .build();

        // Using ExpectedAttributeValue map to handle large mutations in a single request
        // Large mutations would require multiple requests using expressions
        final Map<String, ExpectedAttributeValue> expected =
            new SingleExpectedAttributeValueBuilder(this, txh, hashKey).build(mutation);

        final Map<String, AttributeValueUpdate> attributeValueUpdates =
            new SingleUpdateBuilder().deletions(mutation.getDeletions())
                .additions(mutation.getAdditions())
                .build();

        final UpdateItemRequest request = super.createUpdateItemRequest()
               .withKey(key)
               .withReturnValues(ReturnValue.ALL_NEW)
               .withAttributeUpdates(attributeValueUpdates)
               .withExpected(expected);

        final MutateWorker worker;
        if (mutation.hasDeletions() && !mutation.hasAdditions()) {
            worker = new SingleUpdateWithCleanupWorker(request, client.getDelegate());
        } else {
            worker = new UpdateItemWorker(request, client.getDelegate());
        }
        workers.add(worker);
    }
    return workers;
}
 
public Map<String, ExpectedAttributeValue> build(final KCVMutation mutation) {
    final Map<String, ExpectedAttributeValue> expected = Maps.newHashMapWithExpectedSize(mutation.getTotalMutations());

    for (Entry addedColumn : mutation.getAdditions()) {
        final StaticBuffer columnKey = addedColumn.getColumn();
        addExpectedValueIfPresent(columnKey, expected);
    }

    for (StaticBuffer deletedKey : mutation.getDeletions()) {
        addExpectedValueIfPresent(deletedKey, expected);
    }

    return expected;
}
 
源代码11 项目: dynamodb-transactions   文件: Transaction.java
/**
 * Releases the lock for the item.  If the item was inserted only to acquire the lock (if the item didn't exist before 
 * for a DeleteItem or LockItem), it will be deleted now.
 * 
 * Otherwise, all of the attributes uses for the transaction (tx id, transient flag, applied flag) will be removed.
 * 
 * Conditions on our transaction id owning the item
 * 
 * To be used once the transaction has committed only.
 * @param request
 */
protected void unlockItemAfterCommit(Request request) {
    try {
        Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>();
        expected.put(AttributeName.TXID.toString(), new ExpectedAttributeValue().withValue(new AttributeValue(txId)));
        
        if(request instanceof PutItem || request instanceof UpdateItem) {
            Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
            updates.put(AttributeName.TXID.toString(), new AttributeValueUpdate().withAction(AttributeAction.DELETE));
            updates.put(AttributeName.TRANSIENT.toString(), new AttributeValueUpdate().withAction(AttributeAction.DELETE));
            updates.put(AttributeName.APPLIED.toString(), new AttributeValueUpdate().withAction(AttributeAction.DELETE));
            updates.put(AttributeName.DATE.toString(), new AttributeValueUpdate().withAction(AttributeAction.DELETE));
            
            UpdateItemRequest update = new UpdateItemRequest()
                .withTableName(request.getTableName())
                .withKey(request.getKey(txManager))
                .withAttributeUpdates(updates)
                .withExpected(expected);
            txManager.getClient().updateItem(update);
        } else if(request instanceof DeleteItem) {
            DeleteItemRequest delete = new DeleteItemRequest()
                .withTableName(request.getTableName())
                .withKey(request.getKey(txManager))
                .withExpected(expected);
            txManager.getClient().deleteItem(delete);
        } else if(request instanceof GetItem) {
            releaseReadLock(request.getTableName(), request.getKey(txManager));
        } else {
            throw new TransactionAssertionException(txId, "Unknown request type: " + request.getClass());
        }
    } catch (ConditionalCheckFailedException e) {
        // ignore, unlock already happened
        // TODO if we really want to be paranoid we could condition on applied = 1, and then here
        //      we would have to read the item again and make sure that applied was 1 if we owned the lock (and assert otherwise) 
    }
}
 
源代码12 项目: dynamodb-transactions   文件: Transaction.java
protected static void releaseReadLock(String txId, TransactionManager txManager, String tableName, Map<String, AttributeValue> key) {
    Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>();
    expected.put(AttributeName.TXID.toString(), new ExpectedAttributeValue().withValue(new AttributeValue(txId)));
    expected.put(AttributeName.TRANSIENT.toString(), new ExpectedAttributeValue().withExists(false));
    expected.put(AttributeName.APPLIED.toString(), new ExpectedAttributeValue().withExists(false));
    
    try {
        Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>(1);
        updates.put(AttributeName.TXID.toString(), new AttributeValueUpdate().withAction(AttributeAction.DELETE));
        updates.put(AttributeName.DATE.toString(), new AttributeValueUpdate().withAction(AttributeAction.DELETE));
        
        UpdateItemRequest update = new UpdateItemRequest()
            .withTableName(tableName)
            .withAttributeUpdates(updates)
            .withKey(key)
            .withExpected(expected);
        txManager.getClient().updateItem(update);
    } catch (ConditionalCheckFailedException e) {
        try {
            expected.put(AttributeName.TRANSIENT.toString(), new ExpectedAttributeValue().withValue(new AttributeValue().withS(BOOLEAN_TRUE_ATTR_VAL)));
            
            DeleteItemRequest delete = new DeleteItemRequest()
                .withTableName(tableName)
                .withKey(key)
                .withExpected(expected);
            txManager.getClient().deleteItem(delete);    
        } catch (ConditionalCheckFailedException e1) {
            // Ignore, means it was definitely rolled back
            // Re-read to ensure that it wasn't applied
            Map<String, AttributeValue> item = getItem(txManager, tableName, key);
            txAssert(! (item != null && txId.equals(getOwner(item)) && item.containsKey(AttributeName.APPLIED.toString())), 
                "Item should not have been applied.  Unable to release lock", "item", item);
        }
    }
}
 
源代码13 项目: dynamodb-transactions   文件: TransactionItem.java
/**
 * Saves the old copy of the item.  Does not mutate the item, unless an exception is thrown.
 * 
 * @param item
 * @param rid
 */
public void saveItemImage(Map<String, AttributeValue> item, int rid) {
    txAssert(! item.containsKey(AttributeName.APPLIED.toString()), txId, "The transaction has already applied this item image, it should not be saving over the item image with it");
    
    AttributeValue existingTxId = item.put(AttributeName.TXID.toString(), new AttributeValue(txId));
    if(existingTxId != null && ! txId.equals(existingTxId.getS())) {
        throw new TransactionException(txId, "Items in transactions may not contain the attribute named " + AttributeName.TXID.toString());
    }
    
    // Don't save over the already saved item.  Prevents us from saving the applied image instead of the previous image in the case
    // of a re-drive.
    // If we want to be extremely paranoid, we could expect every attribute to be set exactly already in a second write step, and assert
    Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>(1);
    expected.put(AttributeName.IMAGE_ID.toString(), new ExpectedAttributeValue().withExists(false));
    
    AttributeValue existingImageId = item.put(AttributeName.IMAGE_ID.toString(), new AttributeValue(txId + "#" + rid));
    if(existingImageId != null) {
        throw new TransactionException(txId, "Items in transactions may not contain the attribute named " + AttributeName.IMAGE_ID.toString() + ", value was already " + existingImageId); 
    }
    
    // TODO failures?  Size validation?
    try {
        txManager.getClient().putItem(new PutItemRequest()
            .withTableName(txManager.getItemImageTableName())
            .withExpected(expected)
            .withItem(item));
    } catch (ConditionalCheckFailedException e) {
        // Already was saved
    }
    
    // do not mutate the item for the customer unless if there aren't exceptions
    item.remove(AttributeName.IMAGE_ID.toString());
}
 
源代码14 项目: dynamodb-transactions   文件: TransactionItem.java
/**
 * Marks the transaction item as either COMMITTED or ROLLED_BACK, but only if it was in the PENDING state.
 * It will also condition on the expected version. 
 * 
 * @param targetState
 * @param expectedVersion 
 * @throws ConditionalCheckFailedException if the transaction doesn't exist, isn't PENDING, is finalized, 
 *         or the expected version doesn't match (if specified)  
 */
public void finish(final State targetState, final int expectedVersion) throws ConditionalCheckFailedException {
    txAssert(State.COMMITTED.equals(targetState) || State.ROLLED_BACK.equals(targetState),"Illegal state in finish(): " + targetState, "txItem", txItem);
    Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>(2);
    expected.put(AttributeName.STATE.toString(), new ExpectedAttributeValue().withValue(new AttributeValue().withS(STATE_PENDING)));
    expected.put(AttributeName.FINALIZED.toString(), new ExpectedAttributeValue().withExists(false));
    expected.put(AttributeName.VERSION.toString(), new ExpectedAttributeValue().withValue(new AttributeValue().withN(Integer.toString(expectedVersion))));
    
    Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
    updates.put(AttributeName.STATE.toString(), new AttributeValueUpdate()
        .withAction(AttributeAction.PUT)
        .withValue(new AttributeValue(stateToString(targetState))));
    updates.put(AttributeName.DATE.toString(), new AttributeValueUpdate()
        .withAction(AttributeAction.PUT)
        .withValue(txManager.getCurrentTimeAttribute()));
    
    UpdateItemRequest finishRequest = new UpdateItemRequest()
        .withTableName(txManager.getTransactionTableName())
        .withKey(txKey)
        .withAttributeUpdates(updates)
        .withReturnValues(ReturnValue.ALL_NEW)
        .withExpected(expected);
    
    UpdateItemResult finishResult = txManager.getClient().updateItem(finishRequest);
    txItem = finishResult.getAttributes();
    if(txItem == null) {
        throw new TransactionAssertionException(txId, "Unexpected null tx item after committing " + targetState);
    }
}
 
源代码15 项目: dynamodb-transactions   文件: TransactionItem.java
/**
 * Completes a transaction by marking its "Finalized" attribute.  This leaves the completed transaction item around
 * so that the party who created the transaction can see whether it was completed or rolled back.  They can then either 
 * delete the transaction record when they're done, or they can run a sweeper process to go and delete the completed transactions
 * later on. 
 * 
 * @param expectedCurrentState
 * @throws ConditionalCheckFailedException if the transaction is completed, doesn't exist anymore, or even if it isn't committed or rolled back  
 */
public void complete(final State expectedCurrentState) throws ConditionalCheckFailedException {
    Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>(2);
    
    if(State.COMMITTED.equals(expectedCurrentState)) {
        expected.put(AttributeName.STATE.toString(), new ExpectedAttributeValue(new AttributeValue(STATE_COMMITTED)));
    } else if(State.ROLLED_BACK.equals(expectedCurrentState)) {
        expected.put(AttributeName.STATE.toString(), new ExpectedAttributeValue(new AttributeValue(STATE_ROLLED_BACK)));
    } else {
        throw new TransactionAssertionException(txId, "Illegal state in finish(): " + expectedCurrentState + " txItem " + txItem);
    }
    
    Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
    updates.put(AttributeName.FINALIZED.toString(), new AttributeValueUpdate()
        .withAction(AttributeAction.PUT)
        .withValue(new AttributeValue(Transaction.BOOLEAN_TRUE_ATTR_VAL)));
    updates.put(AttributeName.DATE.toString(), new AttributeValueUpdate()
        .withAction(AttributeAction.PUT)
        .withValue(txManager.getCurrentTimeAttribute()));
    
    UpdateItemRequest completeRequest = new UpdateItemRequest()
        .withTableName(txManager.getTransactionTableName())
        .withKey(txKey)
        .withAttributeUpdates(updates)
        .withReturnValues(ReturnValue.ALL_NEW)
        .withExpected(expected);
    
    txItem = txManager.getClient().updateItem(completeRequest).getAttributes();
}
 
源代码16 项目: dynamodb-transactions   文件: TransactionItem.java
/**
 * Deletes the tx item, only if it was in the "finalized" state.
 * 
 * @throws ConditionalCheckFailedException if the item does not exist or is not finalized
 */
public void delete() throws ConditionalCheckFailedException {
    Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>(1);
    expected.put(AttributeName.FINALIZED.toString(), new ExpectedAttributeValue().withValue(new AttributeValue(Transaction.BOOLEAN_TRUE_ATTR_VAL)));
    
    DeleteItemRequest completeRequest = new DeleteItemRequest()
        .withTableName(txManager.getTransactionTableName())
        .withKey(txKey)
        .withExpected(expected);
    txManager.getClient().deleteItem(completeRequest);
}
 
源代码17 项目: dynamodb-transactions   文件: Request.java
/**
 * Returns a new copy of Map that can be used in a write on the item to ensure it does not exist 
 * @param txManager
 * @return a map for use in an expected clause to ensure the item does not exist
 */
@JsonIgnore
protected Map<String, ExpectedAttributeValue> getExpectNotExists(TransactionManager txManager) {
    Map<String, AttributeValue> key = getKey(txManager);
    Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>(key.size());
    for(Map.Entry<String, AttributeValue> entry : key.entrySet()) {
        expected.put(entry.getKey(), new ExpectedAttributeValue().withExists(false));
    }
    return expected;
}
 
源代码18 项目: dynamodb-transactions   文件: Request.java
/**
 * Returns a new copy of Map that can be used in a write on the item to ensure it exists 
 * @param txManager
 * @return a map for use in an expected clause to ensure the item exists
 */
@JsonIgnore
protected Map<String, ExpectedAttributeValue> getExpectExists(TransactionManager txManager) {
    Map<String, AttributeValue> key = getKey(txManager);
    Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>(key.size());
    for(Map.Entry<String, AttributeValue> entry : key.entrySet()) {
        expected.put(entry.getKey(), new ExpectedAttributeValue().withValue(entry.getValue()));
    }
    return expected;
}
 
@Override
public DeleteItemResult deleteItem(DeleteItemRequest request)
        throws AmazonServiceException, AmazonClientException {
    Map<String, ExpectedAttributeValue> expectedValues = request.getExpected();
    checkExpectedValues(request.getTableName(), request.getKey(), expectedValues);

    // conditional checks are handled by the above call
    request.setExpected(null);
    return txn.deleteItem(request);
}
 
@Override
public PutItemResult putItem(PutItemRequest request)
        throws AmazonServiceException, AmazonClientException {
    Map<String, ExpectedAttributeValue> expectedValues = request.getExpected();
    checkExpectedValues(request.getTableName(), Request.getKeyFromItem(request.getTableName(),
            request.getItem(), txManager), expectedValues);

    // conditional checks are handled by the above call
    request.setExpected(null);
    return txn.putItem(request);
}
 
@Override
public UpdateItemResult updateItem(UpdateItemRequest request)
        throws AmazonServiceException, AmazonClientException {
    Map<String, ExpectedAttributeValue> expectedValues = request.getExpected();
    checkExpectedValues(request.getTableName(), request.getKey(), expectedValues);

    // conditional checks are handled by the above call
    request.setExpected(null);
    return txn.updateItem(request);
}
 
private void checkExpectedValues(String tableName,
        Map<String, AttributeValue> itemKey,
        Map<String, ExpectedAttributeValue> expectedValues) {
    if (expectedValues != null && !expectedValues.isEmpty()) {
        for (Map.Entry<String, ExpectedAttributeValue> entry : expectedValues.entrySet()) {
            if ((entry.getValue().isExists() == null || entry.getValue().isExists() == true)
                    && entry.getValue().getValue() == null) {
                throw new IllegalArgumentException("An explicit value is required when Exists is null or true, "
                        + "but none was found in expected values for item with key " + itemKey +
                        ": " + expectedValues);
            }
        }

        // simulate by loading the item and checking the values;
        // this also has the effect of locking the item, which gives the
        // same behavior
        GetItemResult result = getItem(new GetItemRequest()
                .withAttributesToGet(expectedValues.keySet())
                .withKey(itemKey)
                .withTableName(tableName));
        Map<String, AttributeValue> item = result.getItem();
        try {
            checkExpectedValues(expectedValues, item);
        } catch (ConditionalCheckFailedException e) {
            throw new ConditionalCheckFailedException("Item " + itemKey + " had unexpected attributes: " + e.getMessage());
        }
    }
}
 
@Test
public void testCheckExpectedStringValueWithMatchingItem() {
    Map<String, AttributeValue> item = Collections.singletonMap("Foo", new AttributeValue("Bar"));
    Map<String, ExpectedAttributeValue> expected = Collections.singletonMap("Foo", new ExpectedAttributeValue(new AttributeValue("Bar")));

    TransactionDynamoDBFacade.checkExpectedValues(expected, item);
    // no exception expected
}
 
@Test
public void testCheckExpectedBinaryValueWithMatchingItem() {
    Map<String, AttributeValue> item = Collections.singletonMap("Foo", new AttributeValue().withB(ByteBuffer.wrap(new byte[] { 1, 127, -127 })));
    Map<String, ExpectedAttributeValue> expected = Collections.singletonMap("Foo", new ExpectedAttributeValue(new AttributeValue().withB(ByteBuffer.wrap(new byte[] { 1, 127, -127 }))));

    TransactionDynamoDBFacade.checkExpectedValues(expected, item);
    // no exception expected
}
 
@Test
public void testCheckExpectedNumericValueWithMatchingItem() {
    Map<String, AttributeValue> item = Collections.singletonMap("Foo", new AttributeValue().withN("3.14"));
    Map<String, ExpectedAttributeValue> expected = Collections.singletonMap("Foo", new ExpectedAttributeValue(new AttributeValue().withN("3.14")));

    TransactionDynamoDBFacade.checkExpectedValues(expected, item);
    // no exception expected
}
 
@Test
public void testCheckExpectedNumericValueWithMatchingNotStringEqualItem() {
    Map<String, AttributeValue> item = Collections.singletonMap("Foo", new AttributeValue().withN("3.140"));
    Map<String, ExpectedAttributeValue> expected = Collections.singletonMap("Foo", new ExpectedAttributeValue(new AttributeValue().withN("3.14")));

    TransactionDynamoDBFacade.checkExpectedValues(expected, item);
    // no exception expected
}
 
源代码27 项目: strongbox   文件: GenericDynamoDB.java
private Map<String, ExpectedAttributeValue> expectNotExists() {
    Map<String, ExpectedAttributeValue> expected = new HashMap<>();
    expected.put(partitionKeyName.toString(), new ExpectedAttributeValue(false));
    return expected;
}
 
源代码28 项目: strongbox   文件: GenericDynamoDBTest.java
private UpdateItemRequest constructUpdateItemRequest(RawSecretEntry rawSecretEntry, boolean expectExists, Optional<RawSecretEntry> expectedRawSecretEntry) {
    // Create item key.
    Map<String, AttributeValue> key = new HashMap<>();
    key.put(KEY_ATTRIBUTE_NAME.toString(), new AttributeValue().withS(rawSecretEntry.secretIdentifier.name));
    key.put(VERSION_ATTRIBUTE_NAME.toString(), new AttributeValue().withN(String.valueOf(rawSecretEntry.version)));


    // Create item attributes.
    Map<String, AttributeValueUpdate> attributes = new HashMap<>();
    attributes.put(SCHEMA_VERSION_FIELD_NAME,
            new AttributeValueUpdate()
                    .withAction(AttributeAction.PUT)
                    .withValue(new AttributeValue()
                            .withN(SCHEMA_VERSION)));

    attributes.put(NOT_BEFORE_ATTRIBUTE_NAME.toString(),
            new AttributeValueUpdate()
                    .withAction(AttributeAction.PUT)
                    .withValue(new AttributeValue()
                            .withN(FormattedTimestamp.epoch(rawSecretEntry.notBefore.get()).toString())));
    attributes.put(STATE_ATTRIBUTE_NAME.toString(),
            new AttributeValueUpdate()
                    .withAction(AttributeAction.PUT)
                    .withValue(new AttributeValue()
                            .withN(Byte.toString(rawSecretEntry.state.asByte()))));
    attributes.put(VALUE_ATTRIBUTE_NAME.toString(),
            new AttributeValueUpdate()
                    .withAction(AttributeAction.PUT)
                    .withValue(new AttributeValue()
                            .withS(Encoder.base64encode(rawSecretEntry.encryptedPayload))));
    attributes.put(OPTIMISTIC_LOCKING_ATTRIBUTE_NAME,
            new AttributeValueUpdate()
                    .withAction(AttributeAction.PUT)
                    .withValue(new AttributeValue()
                            .withS(Encoder.base64encode(rawSecretEntry.sha1OfEncryptionPayload()))));

    // Create the expected conditions map.
    Map<String, ExpectedAttributeValue> expected = new HashMap<>();
    if (expectExists) {
        expected.put(KEY_ATTRIBUTE_NAME.toString(), new ExpectedAttributeValue(true).withValue(
                new AttributeValue(rawSecretEntry.secretIdentifier.name)));
        expected.put(OPTIMISTIC_LOCKING_ATTRIBUTE_NAME, new ExpectedAttributeValue(true).withValue(
                new AttributeValue(Encoder.sha1(expectedRawSecretEntry.get().encryptedPayload))));
    } else {
        expected.put(KEY_ATTRIBUTE_NAME.toString(), new ExpectedAttributeValue(false));
    }

    return new UpdateItemRequest(tableName, key, attributes).withExpected(expected);
}
 
源代码29 项目: dynamodb-transactions   文件: TransactionItem.java
/**
 * Adds a request object (input param) to the transaction item.  Enforces that request are unique for a given table name and primary key.
 * Doesn't let you do more than one write per item.  However you can upgrade a read lock to a write.
 * @param callerRequest 
 * @throws ConditionalCheckFailedException if the tx item changed out from under us.  If you get this you must throw this TransactionItem away.
 * @throws DuplicateRequestException If you get this you do not need to throw away the item.
 * @throws InvalidRequestException If the request would add too much data to the transaction
 * @return true if the request was added, false if it didn't need to be added (because it was a duplicate lock request)
 */
public synchronized boolean addRequest(Request callerRequest) throws ConditionalCheckFailedException, DuplicateRequestException {
    // 1. Ensure the request is unique (modifies the internal data structure if it is unique)
    //    However, do not not short circuit.  If we're doing a read in a resumed transaction, it's important to ensure we're returning
    //    any writes that happened before. 
    addRequestToMap(callerRequest);
    
    callerRequest.setRid(version);
    
    // 2. Write request to transaction item
    ByteBuffer requestBytes = Request.serialize(txId, callerRequest);
    AttributeValueUpdate txItemUpdate = new AttributeValueUpdate()
        .withAction(AttributeAction.ADD)
        .withValue(new AttributeValue().withBS(Arrays.asList(requestBytes)));
    
    Map<String, AttributeValueUpdate> txItemUpdates = new HashMap<String, AttributeValueUpdate>();
    txItemUpdates.put(AttributeName.REQUESTS.toString(), txItemUpdate);    
    txItemUpdates.put(AttributeName.VERSION.toString(), new AttributeValueUpdate().withAction(AttributeAction.ADD).withValue(new AttributeValue().withN("1")));
    txItemUpdates.put(AttributeName.DATE.toString(), new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(txManager.getCurrentTimeAttribute()));
    
    Map<String, ExpectedAttributeValue> expected = new HashMap<String, ExpectedAttributeValue>();
    expected.put(AttributeName.STATE.toString(), new ExpectedAttributeValue(new AttributeValue(STATE_PENDING)));
    expected.put(AttributeName.VERSION.toString(), new ExpectedAttributeValue(new AttributeValue().withN(Integer.toString(version))));
    
    UpdateItemRequest txItemUpdateRequest = new UpdateItemRequest()
        .withTableName(txManager.getTransactionTableName())
        .withKey(txKey)
        .withExpected(expected)
        .withReturnValues(ReturnValue.ALL_NEW)
        .withAttributeUpdates(txItemUpdates);
    
    try {
        txItem = txManager.getClient().updateItem(txItemUpdateRequest).getAttributes();
        int newVersion = Integer.parseInt(txItem.get(AttributeName.VERSION.toString()).getN());
        txAssert(newVersion == version + 1, txId, "Unexpected version number from update result");
        version = newVersion;
    } catch (AmazonServiceException e) {
        if("ValidationException".equals(e.getErrorCode())) {
            removeRequestFromMap(callerRequest);
            throw new InvalidRequestException("The amount of data in the transaction cannot exceed the DynamoDB item size limit", 
                txId, callerRequest.getTableName(), callerRequest.getKey(txManager), callerRequest);
        } else {
            throw e;
        }
    }
    return true;
}
 
 类方法
 同包方法