diff --git a/.changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-f810b1c.json b/.changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-f810b1c.json new file mode 100644 index 000000000000..4dcb1f1be3e9 --- /dev/null +++ b/.changes/next-release/bugfix-AmazonDynamoDBEnhancedClient-f810b1c.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "Amazon DynamoDB Enhanced Client", + "contributor": "swar8080", + "description": "Provides a clearer exception message when building a ReadBatch or WriteBatch without setting the mappedTableResource (table)" +} diff --git a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/model/ReadBatch.java b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/model/ReadBatch.java index 1bdae4d4995c..e9d4364fec81 100644 --- a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/model/ReadBatch.java +++ b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/model/ReadBatch.java @@ -15,6 +15,8 @@ package software.amazon.awssdk.enhanced.dynamodb.model; +import static java.util.Objects.requireNonNull; + import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -211,6 +213,9 @@ private static boolean compareNullableBooleans(Boolean one, Boolean two) { @NotThreadSafe private static final class BuilderImpl implements Builder { + private static final String MAPPED_TABLE_RESOURCE_NOT_NULL_MESSAGE = String.format("A mappedTableResource (table) is " + + "required when building a %s", + ReadBatch.class.getSimpleName()); private MappedTableResource mappedTableResource; private List requests = new ArrayList<>(); @@ -243,6 +248,7 @@ public Builder addGetItem(Key key) { @Override public Builder addGetItem(T keyItem) { + requireNonNull(mappedTableResource, MAPPED_TABLE_RESOURCE_NOT_NULL_MESSAGE); return addGetItem(this.mappedTableResource.keyFrom(keyItem)); } diff --git a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/model/WriteBatch.java b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/model/WriteBatch.java index d8fec912ba84..d2aa68572906 100644 --- a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/model/WriteBatch.java +++ b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/model/WriteBatch.java @@ -15,6 +15,7 @@ package software.amazon.awssdk.enhanced.dynamodb.model; +import static java.util.Objects.requireNonNull; import static software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils.getItemsFromSupplier; import java.util.ArrayList; @@ -187,7 +188,9 @@ public interface Builder { } private static final class BuilderImpl implements Builder { - + private static final String MAPPED_TABLE_RESOURCE_NOT_NULL_MESSAGE = String.format("A mappedTableResource (table) is " + + "required when building a %s", + WriteBatch.class.getSimpleName()); private Class itemClass; private List> itemSupplierList = new ArrayList<>(); private MappedTableResource mappedTableResource; @@ -204,6 +207,7 @@ public Builder mappedTableResource(MappedTableResource mappedTableResource @Override public Builder addDeleteItem(DeleteItemEnhancedRequest request) { + requireNonNull(mappedTableResource, MAPPED_TABLE_RESOURCE_NOT_NULL_MESSAGE); itemSupplierList.add(() -> generateWriteRequest(() -> mappedTableResource, DeleteItemOperation.create(request))); return this; } @@ -222,11 +226,13 @@ public Builder addDeleteItem(Key key) { @Override public Builder addDeleteItem(T keyItem) { + requireNonNull(mappedTableResource, MAPPED_TABLE_RESOURCE_NOT_NULL_MESSAGE); return addDeleteItem(this.mappedTableResource.keyFrom(keyItem)); } @Override public Builder addPutItem(PutItemEnhancedRequest request) { + requireNonNull(mappedTableResource, MAPPED_TABLE_RESOURCE_NOT_NULL_MESSAGE); itemSupplierList.add(() -> generateWriteRequest(() -> mappedTableResource, PutItemOperation.create(request))); return this; } diff --git a/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/model/ReadBatchTest.java b/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/model/ReadBatchTest.java index b5c2c8265d19..2e9547b119d6 100644 --- a/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/model/ReadBatchTest.java +++ b/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/model/ReadBatchTest.java @@ -19,6 +19,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThrows; import static software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItem.createUniqueFakeItem; import java.util.Collections; @@ -95,4 +96,13 @@ public void builder_maximal_builder_style() { assertThat(builtObject.keysAndAttributes().keys(), containsInAnyOrder(Collections.singletonList(fakeItemMap).toArray())); } + @Test + public void builder_missing_mapped_table_resource_error_message() { + FakeItem fakeItem = createUniqueFakeItem(); + + ReadBatch.Builder builder = ReadBatch.builder(FakeItem.class); + + NullPointerException exception = assertThrows(NullPointerException.class, () -> builder.addGetItem(fakeItem)); + assertThat(exception.getMessage(), is("A mappedTableResource (table) is required when building a ReadBatch")); + } } diff --git a/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/model/WriteBatchTest.java b/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/model/WriteBatchTest.java index 793d83eacddf..b3f49b03926e 100644 --- a/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/model/WriteBatchTest.java +++ b/services-custom/dynamodb-enhanced/src/test/java/software/amazon/awssdk/enhanced/dynamodb/model/WriteBatchTest.java @@ -19,16 +19,21 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThrows; import static software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItem.createUniqueFakeItem; import java.util.Map; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.function.ThrowingRunnable; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable; +import software.amazon.awssdk.enhanced.dynamodb.Key; import software.amazon.awssdk.enhanced.dynamodb.functionaltests.models.FakeItem; import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; @@ -100,6 +105,31 @@ public void builder_maximal_builder_style() { assertThat(builtObject.writeRequests(), containsInAnyOrder(putRequest(fakeItemMap), deleteRequest(fakeItemMap))); } + @Test + public void builder_missing_mapped_table_resource_error_message() { + FakeItem fakeItem = createUniqueFakeItem(); + PutItemEnhancedRequest putItemRequest = PutItemEnhancedRequest.builder(FakeItem.class).item(fakeItem).build(); + + Key partitionKey = Key.builder().partitionValue(fakeItem.getId()).build(); + DeleteItemEnhancedRequest deleteItemRequest = DeleteItemEnhancedRequest.builder() + .key(partitionKey) + .build(); + + WriteBatch.Builder builder = WriteBatch.builder(FakeItem.class); + + assertThrowsMappedTableResourceNullException(() -> builder.addPutItem(putItemRequest)); + assertThrowsMappedTableResourceNullException(() -> builder.addPutItem(fakeItem)); + assertThrowsMappedTableResourceNullException(() -> builder.addPutItem(r -> r.item(fakeItem))); + assertThrowsMappedTableResourceNullException(() -> builder.addDeleteItem(deleteItemRequest)); + assertThrowsMappedTableResourceNullException(() -> builder.addDeleteItem(fakeItem)); + assertThrowsMappedTableResourceNullException(() -> builder.addDeleteItem(r -> r.key(partitionKey))); + } + + private static void assertThrowsMappedTableResourceNullException(ThrowingRunnable runnable) { + NullPointerException exception = assertThrows(NullPointerException.class, runnable); + assertThat(exception.getMessage(), is("A mappedTableResource (table) is required when building a WriteBatch")); + } + private static WriteRequest putRequest(Map itemMap) { return WriteRequest.builder().putRequest(PutRequest.builder().item(itemMap).build()).build(); }