@Test public void testCreateEntryAlreadyExists() throws Exception { RawSecretEntry rawSecretEntry = constructRawEntry(SECRET_NAME); UpdateItemRequest expectedUpdateRequest = constructUpdateItemRequest(rawSecretEntry, false, Optional.empty()); // Already exists will cause a check failed exception. when(mockDynamoDBClient.updateItem(expectedUpdateRequest)).thenThrow( new ConditionalCheckFailedException("")); boolean exceptionThrown = false; try { dynamoDB.create(rawSecretEntry); } catch (AlreadyExistsException e) { assertEquals(e.getMessage(), "DynamoDB store entry already exists:{1={S: secret1,}, 2={N: 1,}}"); exceptionThrown = true; } assertTrue(exceptionThrown); verify(mockDynamoDBClient, times(1)).updateItem(expectedUpdateRequest); }
@Test public void testUpdateEntryDoesNotExist() throws Exception { RawSecretEntry rawSecretEntry = constructRawEntry(SECRET_NAME); RawSecretEntry alternativeRawSecretEntry = constructAlternativeRawSecretEntry(SECRET_NAME); UpdateItemRequest expectedUpdateRequest = constructUpdateItemRequest(rawSecretEntry, true, Optional.of(alternativeRawSecretEntry)); when(mockDynamoDBClient.updateItem(expectedUpdateRequest)).thenThrow( new ConditionalCheckFailedException("")); boolean exceptionThrown = false; try { dynamoDB.update(rawSecretEntry, alternativeRawSecretEntry); } catch (DoesNotExistException e) { assertEquals(e.getMessage(), "Precondition to update entry in DynamoDB failed:{1={S: secret1,}, 2={N: 1,}}"); exceptionThrown = true; } assertTrue(exceptionThrown); // Check all the expected calls to AWS were made. verify(mockDynamoDBClient, times(1)).updateItem(expectedUpdateRequest); }
UpdateItemResult updateItem(final UpdateItemRequest request) throws BackendException { setUserAgent(request); UpdateItemResult result; final int bytes; if (request.getUpdateExpression() != null) { bytes = calculateExpressionBasedUpdateSize(request); } else { bytes = calculateItemUpdateSizeInBytes(request.getAttributeUpdates()); } getBytesHistogram(UPDATE_ITEM, request.getTableName()).update(bytes); final int wcu = computeWcu(bytes); timedWriteThrottle(UPDATE_ITEM, request.getTableName(), wcu); final Timer.Context apiTimerContext = getTimerContext(UPDATE_ITEM, request.getTableName()); try { result = client.updateItem(request); } catch (Exception e) { throw processDynamoDbApiException(e, UPDATE_ITEM, request.getTableName()); } finally { apiTimerContext.stop(); } meterConsumedCapacity(UPDATE_ITEM, result.getConsumedCapacity()); return result; }
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); }
/** * Sends an update request to the service and returns true if the request is successful. */ public boolean sendUpdateRequest(Map<String, AttributeValue> primaryKey, Map<String, AttributeValueUpdate> updateItems, Map<String, ExpectedAttributeValue> expectedItems) throws Exception { if (updateItems.isEmpty()) { return false; // No update, return false } UpdateItemRequest updateItemRequest = new UpdateItemRequest().withTableName(tableName).withKey(primaryKey).withReturnValues(ReturnValue.UPDATED_NEW) .withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL).withAttributeUpdates(updateItems); if (expectedItems != null) { updateItemRequest.withExpected(expectedItems); } UpdateItemResult result = dynamoDBClient.updateItem(updateItemRequest); if(!isRunningOnDDBLocal) { // DDB Local does not support rate limiting tableWriteRateLimiter.adjustRateWithConsumedCapacity(result.getConsumedCapacity()); } return true; }
private void updateRow(String key, String appid, Map<String, AttributeValue> row) { if (StringUtils.isBlank(key) || StringUtils.isBlank(appid) || row == null || row.isEmpty()) { return; } Map<String, AttributeValueUpdate> rou = new HashMap<>(); try { for (Entry<String, AttributeValue> attr : row.entrySet()) { rou.put(attr.getKey(), new AttributeValueUpdate(attr.getValue(), AttributeAction.PUT)); } UpdateItemRequest updateItemRequest = new UpdateItemRequest(getTableNameForAppid(appid), Collections.singletonMap(Config._KEY, new AttributeValue(getKeyForAppid(key, appid))), rou); client().updateItem(updateItemRequest); } catch (Exception e) { logger.error("Could not update row in DB - appid={}, key={}", appid, key, e); } }
public UpdatePointResult updatePoint(UpdatePointRequest updatePointRequest) { long geohash = S2Manager.generateGeohash(updatePointRequest.getGeoPoint()); long hashKey = S2Manager.generateHashKey(geohash, config.getHashKeyLength()); UpdateItemRequest updateItemRequest = updatePointRequest.getUpdateItemRequest(); updateItemRequest.setTableName(config.getTableName()); AttributeValue hashKeyValue = new AttributeValue().withN(String.valueOf(hashKey)); updateItemRequest.getKey().put(config.getHashKeyAttributeName(), hashKeyValue); updateItemRequest.getKey().put(config.getRangeKeyAttributeName(), updatePointRequest.getRangeKeyValue()); // Geohash and geoJson cannot be updated. updateItemRequest.getAttributeUpdates().remove(config.getGeohashAttributeName()); updateItemRequest.getAttributeUpdates().remove(config.getGeoJsonAttributeName()); UpdateItemResult updateItemResult = config.getDynamoDBClient().updateItem(updateItemRequest); UpdatePointResult updatePointResult = new UpdatePointResult(updateItemResult); return updatePointResult; }
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); }
@Test public void testCreateEntry() throws Exception { RawSecretEntry rawSecretEntry = constructRawEntry(SECRET_NAME); UpdateItemRequest expectedUpdateRequest = constructUpdateItemRequest(rawSecretEntry, false, Optional.empty()); dynamoDB.create(rawSecretEntry); verify(mockDynamoDBClient, times(1)).updateItem(expectedUpdateRequest); }
@Test public void testUpdateEntry() throws Exception { RawSecretEntry rawSecretEntry = constructRawEntry(SECRET_NAME); RawSecretEntry alternativeRawSecretEntry = constructAlternativeRawSecretEntry(SECRET_NAME); UpdateItemRequest expectedUpdateRequest = constructUpdateItemRequest(rawSecretEntry, true, Optional.of(alternativeRawSecretEntry)); dynamoDB.update(rawSecretEntry, alternativeRawSecretEntry); verify(mockDynamoDBClient, times(1)).updateItem(expectedUpdateRequest); }
public CompletableFuture<UpdateItemResult> updateItem(final UpdateItemRequest updateItemRequest) { return asyncExecutor.execute(new Callable<UpdateItemResult>() { @Override public UpdateItemResult call() throws Exception { return dbExecutor.updateItem(updateItemRequest); } }); }
@Override public void execute() { UpdateItemResult result = ddbClient.updateItem(new UpdateItemRequest() .withTableName(determineTableName()) .withKey(determineKey()) .withAttributeUpdates(determineUpdateValues()) .withExpected(determineUpdateCondition()) .withReturnValues(determineReturnValues())); addAttributesToResult(result.getAttributes()); }
/** * This method calculates a lower bound of the size of a new item created with UpdateItem UpdateExpression. It does not * account for the size of the attribute names of the document paths in the attribute names map and it assumes that the * UpdateExpression only uses the SET action to assign to top-level attributes. * @param request UpdateItem request that uses update expressions * @return the size of the post-update image of the item */ private int calculateExpressionBasedUpdateSize(final UpdateItemRequest request) { if (request == null || request.getUpdateExpression() == null) { throw new IllegalArgumentException("request did not use update expression"); } int size = calculateItemSizeInBytes(request.getKey()); for (AttributeValue value : request.getExpressionAttributeValues().values()) { size += calculateAttributeSizeInBytes(value); } return size; }
@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; }
@Override public Object handleRequest(Object input, Context context) { context.getLogger().log("input: " + input); if (input.toString().equals("{}") || input.toString().equals("")) { context.getLogger().log("input is empty: abort"); return "{\"status\":\"error\",\"message\":\"input at lambda function is empty\"}"; } dynamoDB = new AmazonDynamoDBClient().withRegion(Region .getRegion(Regions.EU_WEST_1)); HashMap<String, String> mapInput = (HashMap<String, String>) input; Map<String, AttributeValue> employeeKey = new HashMap<String, AttributeValue>(); String employeeId = mapInput.get("employee_id"); context.getLogger().log("employee_id: " + employeeId); employeeKey.put("employee_id", new AttributeValue().withS(employeeId)); Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<String, AttributeValueUpdate>(); attributeUpdates.put("approval", new AttributeValueUpdate() .withValue(new AttributeValue().withS("approved"))); UpdateItemRequest updateItemRequest = new UpdateItemRequest() .withKey(employeeKey).withAttributeUpdates(attributeUpdates) .withTableName("lambda-reimbursment"); UpdateItemResult updateItemResult = dynamoDB .updateItem(updateItemRequest); context.getLogger().log("Result: " + updateItemResult); return "{'status':'done'}"; }
@Override public UpdateItemResult updateItem(String tableName, HashMap<String, AttributeValue> primaryKey, Map<String, AttributeValueUpdate> updateItems) { Map<String, AttributeValueUpdate> attributeValueUpdates = new HashMap<String, AttributeValueUpdate>(); attributeValueUpdates.putAll(updateItems); UpdateItemRequest updateItemRequest = new UpdateItemRequest() .withTableName(tableName) .withKey(primaryKey).withReturnValues(ReturnValue.UPDATED_NEW) .withAttributeUpdates(updateItems); UpdateItemResult updateItemResult = dynamoDBClient.updateItem(updateItemRequest); LOG.info("Successful by updating item from " + tableName + ": " + updateItemResult); return updateItemResult; }
/** * Update the Inventory table with the state of an Aggregator. * * @param streamName The Kinesis Stream being aggregated. * @param applicationName The application name running the aggregator. * @param workerId The worker ID which encapsulates an instance of an * Aggregator. * @param lastLowSeq The lowest sequence number observed in all records * which were flushed prior to this update. * @param lastHighSeq The highest sequence number for all records flushed in * this update. * @param lastWriteTime The write time of the data to Dynamo DB. * @param status The {@link STATE} of the Aggregator. * @throws Exception */ public void update(final String streamName, final String applicationName, final String namespace, final String shardId, final String lastLowSeq, final String lastHighSeq, final long lastWriteTime, final STATE status) throws Exception { // create the last write time value final String lastUpdateDateLabel = StreamAggregator.dateFormatter.format(new Date( lastWriteTime)); // generate the item update Map<String, AttributeValueUpdate> inventoryUpdate = new HashMap<String, AttributeValueUpdate>() { { put(InventoryModel.LAST_WRITE_TIME, new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue( new AttributeValue().withS(lastUpdateDateLabel))); if (lastLowSeq != null) put(InventoryModel.LAST_LOW_SEQ, new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue( new AttributeValue().withS(lastLowSeq))); if (lastHighSeq != null) put(InventoryModel.LAST_HIGH_SEQ, new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue( new AttributeValue().withS(lastHighSeq))); if (status != null) put(InventoryModel.STATUS, new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue( new AttributeValue().withS(status.name()))); } }; DynamoUtils.updateWithRetries( dynamoClient, new UpdateItemRequest().withTableName(InventoryModel.TABLE_NAME).withKey( getKey(streamName, applicationName, namespace, shardId)).withAttributeUpdates( inventoryUpdate)); }
private static void updateAddNewAttribute() { try { HashMap<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("Id", new AttributeValue().withN("121")); Map<String, AttributeValue> expressionAttributeValues = new HashMap<String, AttributeValue>(); expressionAttributeValues.put(":val1", new AttributeValue().withS("Some value")); ReturnValue returnValues = ReturnValue.ALL_NEW; UpdateItemRequest updateItemRequest = new UpdateItemRequest() .withTableName(tableName) .withKey(key) .withUpdateExpression("set NewAttribute = :val1") .withExpressionAttributeValues(expressionAttributeValues) .withReturnValues(returnValues); UpdateItemResult result = client.updateItem(updateItemRequest); // Check the response. System.out.println("Printing item after adding new attribute..."); printItem(result.getAttributes()); } catch (AmazonServiceException ase) { System.err.println("Failed to add new attribute in " + tableName); System.err.println(ase.getMessage()); } }
private static void updateMultipleAttributes() { try { HashMap<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("Id", new AttributeValue().withN("120")); Map<String, AttributeValue> expressionAttributeValues = new HashMap<String, AttributeValue>(); expressionAttributeValues.put(":val1", new AttributeValue().withSS("Author YY", "Author ZZ")); expressionAttributeValues.put(":val2", new AttributeValue().withS("someValue")); ReturnValue returnValues = ReturnValue.ALL_NEW; UpdateItemRequest updateItemRequest = new UpdateItemRequest() .withTableName(tableName) .withKey(key) .withUpdateExpression("add Authors :val1 set NewAttribute=:val2") .withExpressionAttributeValues(expressionAttributeValues) .withReturnValues(returnValues); UpdateItemResult result = client.updateItem(updateItemRequest); // Check the response. System.out.println("Printing item after multiple attribute update..."); printItem(result.getAttributes()); } catch (AmazonServiceException ase) { System.err.println("Failed to update multiple attributes in " + tableName); System.out.println(ase.getMessage()); //DELETEME System.err.println("Failed to update multiple attributes in " + tableName); //DELETEME } }
private static void updateExistingAttributeConditionally() { try { HashMap<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("Id", new AttributeValue().withN("120")); // Specify the desired price (25.00) and also the condition (price = 20.00) Map<String, AttributeValue> expressionAttributeValues = new HashMap<String, AttributeValue>(); expressionAttributeValues.put(":val1", new AttributeValue().withN("25.00")); expressionAttributeValues.put(":val2", new AttributeValue().withN("20.00")); ReturnValue returnValues = ReturnValue.ALL_NEW; UpdateItemRequest updateItemRequest = new UpdateItemRequest() .withTableName(tableName) .withKey(key) .withUpdateExpression("set Price = :val1") .withConditionExpression("Price = :val2") .withExpressionAttributeValues(expressionAttributeValues) .withReturnValues(returnValues); UpdateItemResult result = client.updateItem(updateItemRequest); // Check the response. System.out.println("Printing item after conditional update to new attribute..."); printItem(result.getAttributes()); } catch (ConditionalCheckFailedException cse) { // Reload object and retry code. System.err.println("Conditional check failed in " + tableName); } catch (AmazonServiceException ase) { System.err.println("Error updating item in " + tableName); } }
@Override public Map<String, AttributeValue> put( final Map<String, AttributeValueUpdate> attrs) throws IOException { final AmazonDynamoDB aws = this.credentials.aws(); final Attributes expected = this.attributes.only(this.keys); try { final UpdateItemRequest request = new UpdateItemRequest() .withTableName(this.name) .withExpected(expected.asKeys()) .withKey(expected) .withAttributeUpdates(attrs) .withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL) .withReturnValues(ReturnValue.UPDATED_NEW); final long start = System.currentTimeMillis(); final UpdateItemResult result = aws.updateItem(request); Logger.info( this, "#put('%s'): updated item to DynamoDB, %s, in %[ms]s", attrs, new PrintableConsumedCapacity( result.getConsumedCapacity() ).print(), System.currentTimeMillis() - start ); return result.getAttributes(); } catch (final AmazonClientException ex) { throw new IOException( String.format( "failed to put %s into \"%s\" with %s", attrs, this.name, this.keys ), ex ); } finally { aws.shutdown(); } }
public UpdatePointRequest(GeoPoint geoPoint, AttributeValue rangeKeyValue) { updateItemRequest = new UpdateItemRequest(); updateItemRequest.setKey(new HashMap<String, AttributeValue>()); updateItemRequest.setAttributeUpdates(new HashMap<String, AttributeValueUpdate>()); this.geoPoint = geoPoint; this.rangeKeyValue = rangeKeyValue; }
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); }
public UpdateItemResult updateItem(final UpdateItemRequest updateItemRequest) { return dynamoDB.updateItem(updateItemRequest); }
@Override public UpdateItemResult updateItem(UpdateItemRequest updateItemRequest) { this.updateItemRequest = updateItemRequest; return new UpdateItemResult().withAttributes(getAttributes()); }
protected UpdateItemRequest createUpdateItemRequest() { return new UpdateItemRequest() .withTableName(tableName) .withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL); }
public UpdateItem(final UpdateItemRequest request, final DynamoDbDelegate delegate) { super(request, delegate, UPDATE_ITEM_RETRIES); }
public UpdateItemResult updateConditionalValue(final AmazonDynamoDB dynamoClient, final String tableName, final UpdateKey key, final String attribute, final AggregateAttributeModification update) throws Exception { Map<String, AttributeValue> updateKey = StreamAggregatorUtils.getTableKey(key); UpdateItemResult result; final ReturnValue returnValue = ReturnValue.UPDATED_NEW; final String setAttribute = StreamAggregatorUtils.methodToColumn(attribute); // create the update that we want to write final Map<String, AttributeValueUpdate> thisCalcUpdate = new HashMap<String, AttributeValueUpdate>() { { put(setAttribute, new AttributeValueUpdate().withAction(AttributeAction.PUT).withValue( new AttributeValue().withN("" + update.getFinalValue()))); } }; // create the request UpdateItemRequest req = new UpdateItemRequest().withTableName(tableName).withKey(updateKey).withReturnValues( returnValue).withAttributeUpdates(thisCalcUpdate); Map<String, ExpectedAttributeValue> expected = new HashMap<>(); final SummaryCalculation calc = update.getCalculationApplied(); // try an update to PUT the value if NOT EXISTS, to establish if we // are the first writer for this key expected = new HashMap<String, ExpectedAttributeValue>() { { put(setAttribute, new ExpectedAttributeValue().withExists(false)); } }; req.setExpected(expected); try { result = DynamoUtils.updateWithRetries(dynamoClient, req); // yay - we were the first writer, so our value was written return result; } catch (ConditionalCheckFailedException e1) { // set the expected to the comparison contained in the update // calculation expected.clear(); expected.put( setAttribute, new ExpectedAttributeValue().withComparisonOperator( calc.getDynamoComparisonOperator()).withValue( new AttributeValue().withN("" + update.getFinalValue()))); req.setExpected(expected); // do the conditional update on the summary // calculation. this may result in no update being // applied because the new value is greater than the // current minimum for MIN, or less than the current // maximum for MAX. try { result = DynamoUtils.updateWithRetries(dynamoClient, req); return result; } catch (ConditionalCheckFailedException e2) { // no worries - we just weren't the min or max! return null; } } }
@Test public void leadingAndTrailingZeros() { DynamoDBMapper mapper = new DynamoDBMapper(client, DynamoDBMapperConfig.DEFAULT, 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)); }
@Override public <T extends Message> boolean update(T item, Modifier... modifiers) throws DataStoreException { DynamoClassMapping<T> tableInfo = getClassMapping(item); log.debug("Update {} {} [{}]", item.getClass().getSimpleName(), item, modifiers); UpdateItemRequest request = new UpdateItemRequest(); request.setTableName(tableInfo.getDynamoTableName()); request.setKey(tableInfo.buildCompleteKey(item)); Map<String, ExpectedAttributeValue> expected = Maps.newHashMap(); expected.put(FIELD_HASH_KEY, new ExpectedAttributeValue().withComparisonOperator(ComparisonOperator.NOT_NULL)); for (Modifier modifier : modifiers) { if (modifier instanceof WhereModifier) { WhereModifier where = (WhereModifier) modifier; Map<FieldDescriptor, Object> matcherFields = where.getMatcher().getAllFields(); for (Map.Entry<FieldDescriptor, Object> matcherField : matcherFields.entrySet()) { FieldDescriptor fieldDescriptor = matcherField.getKey(); Object fieldValue = matcherField.getValue(); tableInfo.addFilter(expected, fieldDescriptor, fieldValue); } } else { throw new UnsupportedOperationException(); } } Map<String, AttributeValueUpdate> attributeUpdates = tableInfo.mapToUpdate(item); request.setAttributeUpdates(attributeUpdates); request.setExpected(expected); if (expected.size() > 1) { request.setConditionalOperator(ConditionalOperator.AND); } try { UpdateItemResult response = dynamoDB.updateItem(request); return true; } catch (ConditionalCheckFailedException e) { log.debug("Update failed (conditional check failed)"); return false; } }
public UpdateItemRequest getUpdateItemRequest() { return updateItemRequest; }