下面列出了怎么用com.amazonaws.services.dynamodbv2.model.AttributeAction的API类实例代码及写法,或者点击链接到github查看源代码。
private Map<String, AttributeValueUpdate> createAttributes(Entry entry) {
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(OPTIMISTIC_LOCK_FIELD_NAME, new AttributeValueUpdate()
.withAction(AttributeAction.PUT)
.withValue(new AttributeValue().withS(sha(entry))));
for (Map.Entry<Integer, String> e : attributeMappings.entrySet()) {
Object value = getValue(entry, e.getValue());
if (value != null) {
attributes.put(e.getKey().toString(),
new AttributeValueUpdate()
.withAction(AttributeAction.PUT)
.withValue(getAttribute(value)));
}
}
return attributes;
}
@Test
public void test_updateItem_WithAllParameters() throws Exception {
createTable();
putItem(TEST_ATTRIBUTE, TEST_ATTRIBUTE_VALUE);
String UPDATE_ATTRIBUTE_VALUE = "UpdateAttributeValue1";
Map<String, AttributeValue> key = new HashMap<String, AttributeValue>();
key.put(TEST_ATTRIBUTE, new AttributeValue()
.withS(TEST_ATTRIBUTE_VALUE));
Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<String, AttributeValueUpdate>();
attributeUpdates.put(TEST_ATTRIBUTE, new AttributeValueUpdate()
.withAction(AttributeAction.PUT)
.withValue(new AttributeValue()
.withS(UPDATE_ATTRIBUTE_VALUE)));
String returnValues = "";
UpdateItemResult result = dynamoDb.updateItem(TEST_TABLE_NAME, key, attributeUpdates, returnValues);
Double units = result.getConsumedCapacity().getCapacityUnits();
GetItemResult getItemResult = getItem(TEST_ATTRIBUTE, UPDATE_ATTRIBUTE_VALUE);
String updatedValue = getItemResult.getItem().get(TEST_ATTRIBUTE).getS();
assertThat(units.doubleValue(), equalTo(1.0));
assertThat(updatedValue, equalTo(UPDATE_ATTRIBUTE_VALUE));
}
public static void updateItem(AmazonDynamoDBClient client, String tableName, String id, String val) {
java.util.Map<String, AttributeValue> key = new HashMap<String, AttributeValue>();
key.put("Id", new AttributeValue().withN(id));
Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<String, AttributeValueUpdate>();
AttributeValueUpdate update = new AttributeValueUpdate()
.withAction(AttributeAction.PUT)
.withValue(new AttributeValue().withS(val));
attributeUpdates.put("attribute-2", update);
UpdateItemRequest updateItemRequest = new UpdateItemRequest()
.withTableName(tableName)
.withKey(key)
.withAttributeUpdates(attributeUpdates);
client.updateItem(updateItemRequest);
}
@Test
public void getThenUpdateNewItem() {
Transaction t1 = manager.newTransaction();
Map<String, AttributeValue> key1 = newKey(INTEG_HASH_TABLE_NAME);
Map<String, AttributeValue> item1 = new HashMap<String, AttributeValue>(key1);
item1.put("asdf", new AttributeValue("didn't exist"));
Map<String, AttributeValueUpdate> updates1 = new HashMap<String, AttributeValueUpdate>();
updates1.put("asdf", new AttributeValueUpdate(new AttributeValue("didn't exist"), AttributeAction.PUT));
Map<String, AttributeValue> getResult = t1.getItem(new GetItemRequest().withTableName(INTEG_HASH_TABLE_NAME).withKey(key1)).getItem();
assertItemLocked(INTEG_HASH_TABLE_NAME, key1, t1.getId(), true, false);
assertNull(getResult);
Map<String, AttributeValue> updateResult = t1.updateItem(new UpdateItemRequest().withTableName(INTEG_HASH_TABLE_NAME).withKey(key1)
.withAttributeUpdates(updates1).withReturnValues(ReturnValue.ALL_NEW)).getAttributes();
assertItemLocked(INTEG_HASH_TABLE_NAME, key1, item1, t1.getId(), true, true);
assertEquals(item1, updateResult);
t1.commit();
assertItemNotLocked(INTEG_HASH_TABLE_NAME, key1, item1, true);
}
@Test
public void getThenUpdateExistingItem() {
Transaction t1 = manager.newTransaction();
Map<String, AttributeValue> item0a = new HashMap<String, AttributeValue>(item0);
item0a.put("wef", new AttributeValue("new attr"));
Map<String, AttributeValueUpdate> updates1 = new HashMap<String, AttributeValueUpdate>();
updates1.put("wef", new AttributeValueUpdate(new AttributeValue("new attr"), AttributeAction.PUT));
Map<String, AttributeValue> getResult = t1.getItem(new GetItemRequest().withTableName(INTEG_HASH_TABLE_NAME).withKey(key0)).getItem();
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item0, t1.getId(), false, false);
assertEquals(item0, getResult);
Map<String, AttributeValue> updateResult = t1.updateItem(new UpdateItemRequest().withTableName(INTEG_HASH_TABLE_NAME).withKey(key0)
.withAttributeUpdates(updates1).withReturnValues(ReturnValue.ALL_NEW)).getAttributes();
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item0a, t1.getId(), false, true);
assertEquals(item0a, updateResult);
t1.commit();
assertItemNotLocked(INTEG_HASH_TABLE_NAME, key0, item0a, true);
}
@Test
public void updateItemAllOldInsert() {
Transaction t1 = manager.newTransaction();
Map<String, AttributeValue> key1 = newKey(INTEG_HASH_TABLE_NAME);
Map<String, AttributeValue> item1 = new HashMap<String, AttributeValue>(key1);
item1.put("asdf", new AttributeValue("wef"));
Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
updates.put("asdf", new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(new AttributeValue("wef")));
Map<String, AttributeValue> result1 = t1.updateItem(new UpdateItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withKey(key1)
.withAttributeUpdates(updates)
.withReturnValues(ReturnValue.ALL_OLD)).getAttributes();
assertItemLocked(INTEG_HASH_TABLE_NAME, key1, item1, t1.getId(), true, true);
assertNull(result1);
t1.commit();
assertItemNotLocked(INTEG_HASH_TABLE_NAME, key1, item1, true);
}
@Test
public void updateItemAllOldOverwrite() {
Transaction t1 = manager.newTransaction();
Map<String, AttributeValue> item1 = new HashMap<String, AttributeValue>(item0);
item1.put("asdf", new AttributeValue("wef"));
Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
updates.put("asdf", new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(new AttributeValue("wef")));
Map<String, AttributeValue> result1 = t1.updateItem(new UpdateItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withKey(key0)
.withAttributeUpdates(updates)
.withReturnValues(ReturnValue.ALL_OLD)).getAttributes();
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item1, t1.getId(), false, true);
assertEquals(result1, item0);
t1.commit();
assertItemNotLocked(INTEG_HASH_TABLE_NAME, key0, item1, true);
}
@Test
public void updateItemAllNewInsert() {
Transaction t1 = manager.newTransaction();
Map<String, AttributeValue> key1 = newKey(INTEG_HASH_TABLE_NAME);
Map<String, AttributeValue> item1 = new HashMap<String, AttributeValue>(key1);
item1.put("asdf", new AttributeValue("wef"));
Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
updates.put("asdf", new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(new AttributeValue("wef")));
Map<String, AttributeValue> result1 = t1.updateItem(new UpdateItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withKey(key1)
.withAttributeUpdates(updates)
.withReturnValues(ReturnValue.ALL_NEW)).getAttributes();
assertItemLocked(INTEG_HASH_TABLE_NAME, key1, item1, t1.getId(), true, true);
assertEquals(result1, item1);
t1.commit();
assertItemNotLocked(INTEG_HASH_TABLE_NAME, key1, item1, true);
}
@Test
public void updateItemAllNewOverwrite() {
Transaction t1 = manager.newTransaction();
Map<String, AttributeValue> item1 = new HashMap<String, AttributeValue>(item0);
item1.put("asdf", new AttributeValue("wef"));
Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
updates.put("asdf", new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(new AttributeValue("wef")));
Map<String, AttributeValue> result1 = t1.updateItem(new UpdateItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withKey(key0)
.withAttributeUpdates(updates)
.withReturnValues(ReturnValue.ALL_NEW)).getAttributes();
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item1, t1.getId(), false, true);
assertEquals(result1, item1);
t1.commit();
assertItemNotLocked(INTEG_HASH_TABLE_NAME, key0, item1, true);
}
/**
* Make an update.
* @param action The action
* @return The update
*/
public AttributeValueUpdate update(final AttributeAction action) {
return new AttributeValueUpdate()
.withAction(action)
.withValue(
new AttributeValue().withN(
Long.toString(this.longValue())
)
);
}
/**
* Save XML.
* @param xml The XML to save
* @throws IOException If fails
*/
private void save(final String xml) throws IOException {
this.item.put(
"usage",
new AttributeValueUpdate()
.withValue(new AttributeValue().withS(xml))
.withAction(AttributeAction.PUT)
);
}
/**
* Save total.
* @param total Total usage
* @throws IOException If fails
*/
private void save(final long total) throws IOException {
this.item.put(
"total",
new AttributeValueUpdate()
.withValue(new AttributeValue().withN(Long.toString(total)))
.withAction(AttributeAction.PUT)
);
}
public static void updateItem(AmazonDynamoDB dynamoDBClient, String tableName, String id, String val) {
java.util.Map<String, AttributeValue> key = new HashMap<String, AttributeValue>();
key.put("Id", new AttributeValue().withN(id));
Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<String, AttributeValueUpdate>();
AttributeValueUpdate update = new AttributeValueUpdate().withAction(AttributeAction.PUT)
.withValue(new AttributeValue().withS(val));
attributeUpdates.put("attribute-2", update);
UpdateItemRequest updateItemRequest = new UpdateItemRequest().withTableName(tableName).withKey(key)
.withAttributeUpdates(attributeUpdates);
dynamoDBClient.updateItem(updateItemRequest);
}
public SingleUpdateBuilder put(final StaticBuffer column, final StaticBuffer value) {
updates.put(encodeKeyBuffer(column),
new AttributeValueUpdate()
.withAction(AttributeAction.PUT)
.withValue(encodeValue(value)));
return this;
}
private void updateRowColumnUpdates(String storeName,
Map<String, AttributeValue> key,
List<DColumn> colList) {
Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<>();
for (DColumn col : colList) {
AttributeValue attrValue = mapColumnValue(storeName, col);
attributeUpdates.put(col.getName(), new AttributeValueUpdate(attrValue, AttributeAction.PUT));
}
m_service.updateRow(storeName, key, attributeUpdates);
}
private void updateRowColumnDeletes(String storeName,
Map<String, AttributeValue> key,
List<String> colNames) {
Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<>();
for (String colName : colNames) {
attributeUpdates.put(colName, new AttributeValueUpdate().withAction(AttributeAction.DELETE));
}
m_service.updateRow(storeName, key, attributeUpdates);
}
private void updatePoint(JSONObject requestObject, PrintWriter out) throws IOException, JSONException {
GeoPoint geoPoint = new GeoPoint(requestObject.getDouble("lat"), requestObject.getDouble("lng"));
AttributeValue rangeKeyAttributeValue = new AttributeValue().withS(requestObject.getString("rangeKey"));
String schoolName = requestObject.getString("schoolName");
AttributeValueUpdate schoolNameValueUpdate = null;
String memo = requestObject.getString("memo");
AttributeValueUpdate memoValueUpdate = null;
if (schoolName == null || schoolName.equalsIgnoreCase("")) {
schoolNameValueUpdate = new AttributeValueUpdate().withAction(AttributeAction.DELETE);
} else {
AttributeValue schoolNameAttributeValue = new AttributeValue().withS(schoolName);
schoolNameValueUpdate = new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(
schoolNameAttributeValue);
}
if (memo == null || memo.equalsIgnoreCase("")) {
memoValueUpdate = new AttributeValueUpdate().withAction(AttributeAction.DELETE);
} else {
AttributeValue memoAttributeValue = new AttributeValue().withS(memo);
memoValueUpdate = new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(memoAttributeValue);
}
UpdatePointRequest updatePointRequest = new UpdatePointRequest(geoPoint, rangeKeyAttributeValue);
updatePointRequest.getUpdateItemRequest().addAttributeUpdatesEntry("schoolName", schoolNameValueUpdate);
updatePointRequest.getUpdateItemRequest().addAttributeUpdatesEntry("memo", memoValueUpdate);
UpdatePointResult updatePointResult = geoDataManager.updatePoint(updatePointRequest);
printUpdatePointResult(updatePointResult, out);
}
@Test
public void getItemCommittedUpdated() {
Transaction t1 = manager.newTransaction();
Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
updates.put("asdf", new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(new AttributeValue("asdf")));
Map<String, AttributeValue> item1 = new HashMap<String, AttributeValue>(item0);
item1.put("asdf", new AttributeValue("asdf"));
t1.updateItem(new UpdateItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withAttributeUpdates(updates)
.withKey(key0));
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item1, t1.getId(), false, true);
Map<String, AttributeValue> item = manager.getItem(new GetItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withKey(key0), IsolationLevel.COMMITTED).getItem();
assertNoSpecialAttributes(item);
assertEquals(item0, item);
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item1, t1.getId(), false, true);
t1.commit();
item = manager.getItem(new GetItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withKey(key0), IsolationLevel.COMMITTED).getItem();
assertNoSpecialAttributes(item);
assertEquals(item1, item);
}
@Test
public void getItemCommittedUpdatedAndApplied() {
Transaction t1 = new Transaction(UUID.randomUUID().toString(), manager, true) {
@Override
protected void doCommit() {
//Skip cleaning up the transaction so we can validate reading.
}
};
Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
updates.put("asdf", new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(new AttributeValue("asdf")));
Map<String, AttributeValue> item1 = new HashMap<String, AttributeValue>(item0);
item1.put("asdf", new AttributeValue("asdf"));
t1.updateItem(new UpdateItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withAttributeUpdates(updates)
.withKey(key0));
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item1, t1.getId(), false, true);
t1.commit();
Map<String, AttributeValue> item = manager.getItem(new GetItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withKey(key0), IsolationLevel.COMMITTED).getItem();
assertNoSpecialAttributes(item);
assertEquals(item1, item);
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item1, t1.getId(), false, true);
}
@Test
public void getItemCommittedMissingImage() {
Transaction t1 = manager.newTransaction();
Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
updates.put("asdf", new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(new AttributeValue("asdf")));
Map<String, AttributeValue> item1 = new HashMap<String, AttributeValue>(item0);
item1.put("asdf", new AttributeValue("asdf"));
t1.updateItem(new UpdateItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withAttributeUpdates(updates)
.withKey(key0));
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item1, t1.getId(), false, true);
dynamodb.getRequestsToTreatAsDeleted.add(new GetItemRequest()
.withTableName(manager.getItemImageTableName())
.addKeyEntry(AttributeName.IMAGE_ID.toString(), new AttributeValue(t1.getTxItem().txId + "#" + 1))
.withConsistentRead(true));
try {
manager.getItem(new GetItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withKey(key0), IsolationLevel.COMMITTED).getItem();
fail("Should have thrown an exception.");
} catch (TransactionException e) {
assertEquals("null - Ran out of attempts to get a committed image of the item", e.getMessage());
}
}
/**
* This example shows that reads can be performed in a transaction, and read locks can be upgraded to write locks.
*/
public void readThenWrite() {
print("\n*** readThenWrite() ***\n");
Transaction t1 = txManager.newTransaction();
// Perform a GetItem request on the transaction
print("Reading Item1");
Map<String, AttributeValue> key1 = new HashMap<String, AttributeValue>();
key1.put(EXAMPLE_TABLE_HASH_KEY, new AttributeValue("Item1"));
Map<String, AttributeValue> item1 = t1.getItem(new GetItemRequest()
.withKey(key1)
.withTableName(EXAMPLE_TABLE_NAME)).getItem();
print("Item1: " + item1);
// Now call UpdateItem to add a new attribute.
// Notice that the library supports ReturnValues in writes
print("Updating Item1");
Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
updates.put("Color", new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(new AttributeValue("Green")));
item1 = t1.updateItem(new UpdateItemRequest()
.withKey(key1)
.withTableName(EXAMPLE_TABLE_NAME)
.withAttributeUpdates(updates)
.withReturnValues(ReturnValue.ALL_NEW)).getAttributes();
print("Item1 is now: " + item1);
t1.commit();
t1.delete();
}
/**
* 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)
}
}
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);
}
}
}
/**
* 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);
}
}
/**
* 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();
}
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);
}
/**
* Add one metric.
* @param metric XML with metric
* @throws IOException If fails
*/
private void add(final XML metric) throws IOException {
final Item item;
final Iterator<Item> items = this.table.frame()
.through(
new QueryValve()
.withLimit(1)
.withSelect(Select.ALL_ATTRIBUTES)
)
.where("metric", metric.xpath("@name").get(0))
.where("version", new Version().value())
.iterator();
if (items.hasNext()) {
item = items.next();
} else {
item = this.table.put(
new Attributes()
.with("metric", metric.xpath("@name").get(0))
.with("version", new Version().value())
.with("artifact", "?")
.with("champions", 0L)
// @checkstyle MagicNumber (2 lines)
.with("mean", new DyNum(0.5d).longValue())
.with("sigma", new DyNum(0.1d).longValue())
);
}
final double mean = Double.parseDouble(
metric.xpath("mean/text()").get(0)
);
final double sigma = Double.parseDouble(
metric.xpath("sigma/text()").get(0)
);
final boolean reverse = Boolean.parseBoolean(
metric.xpath("reverse/text()").get(0)
);
final double mbefore = new DyNum(item, "mean").doubleValue();
final double sbefore = new DyNum(item, "sigma").doubleValue();
// @checkstyle BooleanExpressionComplexityCheck (1 line)
if (sigma < sbefore || mean < mbefore && reverse
|| mean > mbefore && !reverse) {
item.put(
new AttributeUpdates()
.with("artifact", metric.xpath("/index/@artifact").get(0))
.with(
"champions",
new AttributeValueUpdate()
.withValue(new AttributeValue().withN("1"))
.withAction(AttributeAction.ADD)
)
.with("mean", new DyNum(mean).update())
.with("sigma", new DyNum(sigma).update())
);
}
}
private SingleUpdateBuilder delete(final StaticBuffer column) {
updates.put(encodeKeyBuffer(column),
new AttributeValueUpdate()
.withAction(AttributeAction.DELETE));
return this;
}
@Test
public void leadingAndTrailingZeros() {
DynamoDBMapper mapper = new DynamoDBMapper(client, CLOBBER_CONFIG, new AttributeEncryptor(symProv));
Mixed obj = new Mixed();
obj.setHashKey(0);
obj.setRangeKey(15);
obj.setIntSet(new HashSet<Integer>());
obj.getIntSet().add(3);
obj.getIntSet().add(5);
obj.getIntSet().add(7);
obj.setStringValue("Blargh!");
obj.setDoubleValue(15);
obj.setDoubleSet(
new HashSet<Double>(Arrays.asList(15.0D, 7.6D, -3D, -34.2D, 0.0D)));
mapper.save(obj);
// TODO: Update the mock to handle this appropriately.
// DynamoDb discards leading and trailing zeros from numbers
Map<String, AttributeValue> key = new HashMap<String, AttributeValue>();
key.put("hashKey", new AttributeValue().withN("0"));
key.put("rangeKey", new AttributeValue().withN("15"));
Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<String, AttributeValueUpdate>();
attributeUpdates.put("doubleValue", new AttributeValueUpdate(new AttributeValue().withN("15"), AttributeAction.PUT));
UpdateItemRequest update = new UpdateItemRequest("TableName", key, attributeUpdates);
client.updateItem(update);
Mixed result = mapper.load(Mixed.class, 0, 15);
assertEquals(obj, result);
result.setStringValue("Foo");
mapper.save(result);
Mixed result2 = mapper.load(Mixed.class, 0, 15);
assertEquals(result, result2);
mapper.delete(result);
assertNull(mapper.load(Mixed.class, 0, 15));
}
@Test
public void getItemCommittedConcurrentCommit() {
//Test reading an item while simulating another transaction committing concurrently.
//To do this we skip cleanup, make the item image appear to be deleted,
//and then make the reader get the uncommitted version of the transaction
//row for the first read and then actual updated version for later reads.
Transaction t1 = new Transaction(UUID.randomUUID().toString(), manager, true) {
@Override
protected void doCommit() {
//Skip cleaning up the transaction so we can validate reading.
}
};
Map<String, AttributeValueUpdate> updates = new HashMap<String, AttributeValueUpdate>();
updates.put("asdf", new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue(new AttributeValue("asdf")));
Map<String, AttributeValue> item1 = new HashMap<String, AttributeValue>(item0);
item1.put("asdf", new AttributeValue("asdf"));
t1.updateItem(new UpdateItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withAttributeUpdates(updates)
.withKey(key0));
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item1, t1.getId(), false, true);
GetItemRequest txItemRequest = new GetItemRequest()
.withTableName(manager.getTransactionTableName())
.addKeyEntry(AttributeName.TXID.toString(), new AttributeValue(t1.getTxItem().txId))
.withConsistentRead(true);
//Save the copy of the transaction before commit.
GetItemResult uncommittedTransaction = dynamodb.getItem(txItemRequest);
t1.commit();
assertItemLocked(INTEG_HASH_TABLE_NAME, key0, item1, t1.getId(), false, true);
dynamodb.getRequestsToStub.put(txItemRequest, new LinkedList<GetItemResult>(Collections.singletonList(uncommittedTransaction)));
//Stub out the image so it appears deleted
dynamodb.getRequestsToTreatAsDeleted.add(new GetItemRequest()
.withTableName(manager.getItemImageTableName())
.addKeyEntry(AttributeName.IMAGE_ID.toString(), new AttributeValue(t1.getTxItem().txId + "#" + 1))
.withConsistentRead(true));
Map<String, AttributeValue> item = manager.getItem(new GetItemRequest()
.withTableName(INTEG_HASH_TABLE_NAME)
.withKey(key0), IsolationLevel.COMMITTED).getItem();
assertNoSpecialAttributes(item);
assertEquals(item1, item);
}