AWS amazondynamodb documentation change
Summary
Refactored Java code example for conditional TTL updates with improved error handling, constant definitions, and parameter validation. Changed condition from checking expiration time to checking primary key existence.
Security assessment
The changes primarily improve code structure and error handling. While the condition expression changed from checking TTL expiration to checking primary key existence, there's no explicit evidence this addresses a security vulnerability. The update focuses on code quality rather than security controls.
Diff
diff --git a/amazondynamodb/latest/developerguide/example_dynamodb_UpdateItemConditionalTTL_section.md b/amazondynamodb/latest/developerguide/example_dynamodb_UpdateItemConditionalTTL_section.md index 81ea2cdae..554e90224 100644 --- a//amazondynamodb/latest/developerguide/example_dynamodb_UpdateItemConditionalTTL_section.md +++ b//amazondynamodb/latest/developerguide/example_dynamodb_UpdateItemConditionalTTL_section.md @@ -19,0 +20,5 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. + import java.util.Map; + import java.util.Optional; + + import com.amazon.samplelib.CodeSampleUtils; + @@ -22,0 +28 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. + import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException; @@ -27,4 +32,0 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - import software.amazon.awssdk.utils.ImmutableMap; - - import java.util.Map; - import java.util.Optional; @@ -31,0 +34,4 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. + /** + * Updates an item in a DynamoDB table with TTL attributes using a conditional expression. + * This class demonstrates how to conditionally update TTL expiration timestamps. + */ @@ -33,2 +39,2 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - public static void main(String[] args) { - final String usage = """ + + private static final String USAGE = """ @@ -36 +42 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - <tableName> <primaryKey> <sortKey> <newTtlAttribute> <region> + <tableName> <primaryKey> <sortKey> <region> @@ -41 +46,0 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - newTtlAttribute - New attribute name (as part of the update command) @@ -44,3 +49,41 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - // Optional "region" parameter - if args list length is NOT 3 or 4, short-circuit exit. - if (!(args.length == 4 || args.length == 5)) { - System.out.println(usage); + private static final int DAYS_TO_EXPIRE = 90; + private static final int SECONDS_PER_DAY = 24 * 60 * 60; + private static final String PRIMARY_KEY_ATTR = "primaryKey"; + private static final String SORT_KEY_ATTR = "sortKey"; + private static final String UPDATED_AT_ATTR = "updatedAt"; + private static final String EXPIRE_AT_ATTR = "expireAt"; + private static final String UPDATE_EXPRESSION = "SET " + UPDATED_AT_ATTR + "=:c, " + EXPIRE_AT_ATTR + "=:e"; + private static final String CONDITION_EXPRESSION = "attribute_exists(" + PRIMARY_KEY_ATTR + ")"; + private static final String SUCCESS_MESSAGE = "%s UpdateItem operation with TTL successful."; + private static final String CONDITION_FAILED_MESSAGE = "Condition check failed. Item does not exist."; + private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found."; + + private final DynamoDbClient dynamoDbClient; + + /** + * Constructs an UpdateTTLConditional with a default DynamoDB client. + */ + public UpdateTTLConditional() { + this.dynamoDbClient = null; + } + + /** + * Constructs an UpdateTTLConditional with the specified DynamoDB client. + * + * @param dynamoDbClient The DynamoDB client to use + */ + public UpdateTTLConditional(final DynamoDbClient dynamoDbClient) { + this.dynamoDbClient = dynamoDbClient; + } + + /** + * Main method to demonstrate conditionally updating an item with TTL. + * + * @param args Command line arguments + */ + public static void main(final String[] args) { + try { + int result = new UpdateTTLConditional().processArgs(args); + System.exit(result); + } catch (Exception e) { + System.err.println(e.getMessage()); @@ -48,0 +92,15 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. + } + + /** + * Process command line arguments and conditionally update an item with TTL. + * + * @param args Command line arguments + * @return 0 if successful, non-zero otherwise + * @throws ResourceNotFoundException If the table doesn't exist + * @throws DynamoDbException If an error occurs during the operation + * @throws IllegalArgumentException If arguments are invalid + */ + public int processArgs(final String[] args) { + // Argument validation (remove or replace this line when reusing this code) + CodeSampleUtils.validateArgs(args, new int[]{3, 4}, USAGE); + @@ -52,2 +110,3 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - final String newTtlAttribute = args[3]; - Region region = Optional.ofNullable(args[4]).isEmpty() ? Region.US_EAST_1 : Region.of(args[4]); + final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null) + .map(Region::of) + .orElse(Region.US_EAST_1); @@ -58,12 +118,12 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - final long expireDate = currentTime + (90 * 24 * 60 * 60); - // An expression that defines one or more attributes to be updated, the action to be performed on them, and new values for them. - final String updateExpression = "SET newTtlAttribute = :val1"; - // A condition that must be satisfied in order for a conditional update to succeed. - final String conditionExpression = "expireAt > :val2"; - - final ImmutableMap<String, AttributeValue> keyMap = - ImmutableMap.of("primaryKey", AttributeValue.fromS(primaryKey), - "sortKey", AttributeValue.fromS(sortKey)); - final Map<String, AttributeValue> expressionAttributeValues = ImmutableMap.of( - ":val1", AttributeValue.builder().s(newTtlAttribute).build(), - ":val2", AttributeValue.builder().s(String.valueOf(expireDate)).build() + final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY); + + // Create the key map for the item to update + final Map<String, AttributeValue> keyMap = Map.of( + PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKey).build(), + SORT_KEY_ATTR, AttributeValue.builder().s(sortKey).build() + ); + + // Create the expression attribute values + final Map<String, AttributeValue> expressionAttributeValues = Map.of( + ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build(), + ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build() @@ -75,2 +135,2 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - .updateExpression(updateExpression) - .conditionExpression(conditionExpression) + .updateExpression(UPDATE_EXPRESSION) + .conditionExpression(CONDITION_EXPRESSION) @@ -79,3 +139,3 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - try (DynamoDbClient ddb = DynamoDbClient.builder() - .region(region) - .build()) { + + try (DynamoDbClient ddb = dynamoDbClient != null ? dynamoDbClient : + DynamoDbClient.builder().region(region).build()) { @@ -83,2 +143,5 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - System.out.println(tableName + " UpdateItem operation with conditional TTL successful. Request id is " - + response.responseMetadata().requestId()); + System.out.println(String.format(SUCCESS_MESSAGE, tableName)); + return 0; + } catch (ConditionalCheckFailedException e) { + System.err.println(CONDITION_FAILED_MESSAGE); + throw e; @@ -86,2 +149,2 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName); - System.exit(1); + System.err.format(TABLE_NOT_FOUND_ERROR, tableName); + throw e; @@ -90 +153 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - System.exit(1); + throw e; @@ -92 +154,0 @@ Update TTL on on an existing DynamoDB Item in a table, with a condition. - System.exit(0);