diff --git a/.changes/next-release/bugfix-AmazonDynamoDB-d32dcc5.json b/.changes/next-release/bugfix-AmazonDynamoDB-d32dcc5.json new file mode 100644 index 00000000000..4e93384b0eb --- /dev/null +++ b/.changes/next-release/bugfix-AmazonDynamoDB-d32dcc5.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "Amazon DynamoDB Enhanced", + "description": "This bugfix ensures that when using DynamoDbAsyncTable.createTable with no arguments any secondary indices defined in your TableSchema are also created. This behaviour was already present in the synchronous DynamoDbTable", + "contributor": "zakerf" +} diff --git a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DefaultDynamoDbAsyncTable.java b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DefaultDynamoDbAsyncTable.java index 1538e977b4c..e9a858c5b0c 100644 --- a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DefaultDynamoDbAsyncTable.java +++ b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DefaultDynamoDbAsyncTable.java @@ -16,12 +16,18 @@ package software.amazon.awssdk.enhanced.dynamodb.internal.client; import static software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils.createKeyFromItem; +import static software.amazon.awssdk.enhanced.dynamodb.internal.client.DynamoDbTableUtils.extractGlobalSecondaryIndices; +import static software.amazon.awssdk.enhanced.dynamodb.internal.client.DynamoDbTableUtils.extractLocalSecondaryIndices; +import static software.amazon.awssdk.enhanced.dynamodb.internal.client.DynamoDbTableUtils.splitSecondaryIndicesToLocalAndGlobalOnes; +import java.util.List; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbAsyncTable; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClientExtension; +import software.amazon.awssdk.enhanced.dynamodb.IndexMetadata; import software.amazon.awssdk.enhanced.dynamodb.Key; import software.amazon.awssdk.enhanced.dynamodb.TableMetadata; import software.amazon.awssdk.enhanced.dynamodb.TableSchema; @@ -114,7 +120,11 @@ public CompletableFuture createTable(Consumer createTable() { - return createTable(CreateTableEnhancedRequest.builder().build()); + Map> indexGroups = splitSecondaryIndicesToLocalAndGlobalOnes(tableSchema); + return createTable(CreateTableEnhancedRequest.builder() + .localSecondaryIndices(extractLocalSecondaryIndices(indexGroups)) + .globalSecondaryIndices(extractGlobalSecondaryIndices(indexGroups)) + .build()); } @Override diff --git a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DefaultDynamoDbTable.java b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DefaultDynamoDbTable.java index 1bd2638892b..fab563c6650 100644 --- a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DefaultDynamoDbTable.java +++ b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DefaultDynamoDbTable.java @@ -15,20 +15,19 @@ package software.amazon.awssdk.enhanced.dynamodb.internal.client; -import static java.util.Collections.emptyList; import static software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils.createKeyFromItem; +import static software.amazon.awssdk.enhanced.dynamodb.internal.client.DynamoDbTableUtils.extractGlobalSecondaryIndices; +import static software.amazon.awssdk.enhanced.dynamodb.internal.client.DynamoDbTableUtils.extractLocalSecondaryIndices; +import static software.amazon.awssdk.enhanced.dynamodb.internal.client.DynamoDbTableUtils.splitSecondaryIndicesToLocalAndGlobalOnes; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.function.Consumer; -import java.util.stream.Collectors; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClientExtension; import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable; import software.amazon.awssdk.enhanced.dynamodb.IndexMetadata; import software.amazon.awssdk.enhanced.dynamodb.Key; -import software.amazon.awssdk.enhanced.dynamodb.KeyAttributeMetadata; import software.amazon.awssdk.enhanced.dynamodb.TableMetadata; import software.amazon.awssdk.enhanced.dynamodb.TableSchema; import software.amazon.awssdk.enhanced.dynamodb.internal.operations.CreateTableOperation; @@ -46,8 +45,6 @@ import software.amazon.awssdk.enhanced.dynamodb.model.DeleteItemEnhancedRequest; import software.amazon.awssdk.enhanced.dynamodb.model.DeleteItemEnhancedResponse; import software.amazon.awssdk.enhanced.dynamodb.model.DescribeTableEnhancedResponse; -import software.amazon.awssdk.enhanced.dynamodb.model.EnhancedGlobalSecondaryIndex; -import software.amazon.awssdk.enhanced.dynamodb.model.EnhancedLocalSecondaryIndex; import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest; import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedResponse; import software.amazon.awssdk.enhanced.dynamodb.model.PageIterable; @@ -61,7 +58,6 @@ import software.amazon.awssdk.services.dynamodb.DynamoDbClient; import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest; import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse; -import software.amazon.awssdk.services.dynamodb.model.ProjectionType; @SdkInternalApi public class DefaultDynamoDbTable implements DynamoDbTable { @@ -126,52 +122,13 @@ public void createTable(Consumer requestCons @Override public void createTable() { - Map> indexGroups = splitSecondaryIndicesToLocalAndGlobalOnes(); + Map> indexGroups = splitSecondaryIndicesToLocalAndGlobalOnes(tableSchema); createTable(CreateTableEnhancedRequest.builder() .localSecondaryIndices(extractLocalSecondaryIndices(indexGroups)) .globalSecondaryIndices(extractGlobalSecondaryIndices(indexGroups)) .build()); } - private Map> splitSecondaryIndicesToLocalAndGlobalOnes() { - Collection indices = tableSchema.tableMetadata().indices(); - return indices.stream() - .filter(index -> !TableMetadata.primaryIndexName().equals(index.name())) - .collect(Collectors.groupingBy(metadata -> { - String partitionKeyName = metadata.partitionKey().map(KeyAttributeMetadata::name).orElse(null); - if (partitionKeyName == null) { - return IndexType.LSI; - } - return IndexType.GSI; - })); - } - - private List extractLocalSecondaryIndices(Map> indicesGroups) { - return indicesGroups.getOrDefault(IndexType.LSI, emptyList()).stream() - .map(this::mapIndexMetadataToEnhancedLocalSecondaryIndex) - .collect(Collectors.toList()); - } - - private EnhancedLocalSecondaryIndex mapIndexMetadataToEnhancedLocalSecondaryIndex(IndexMetadata indexMetadata) { - return EnhancedLocalSecondaryIndex.builder() - .indexName(indexMetadata.name()) - .projection(pb -> pb.projectionType(ProjectionType.ALL)) - .build(); - } - - private List extractGlobalSecondaryIndices(Map> indicesGroups) { - return indicesGroups.getOrDefault(IndexType.GSI, emptyList()).stream() - .map(this::mapIndexMetadataToEnhancedGlobalSecondaryIndex) - .collect(Collectors.toList()); - } - - private EnhancedGlobalSecondaryIndex mapIndexMetadataToEnhancedGlobalSecondaryIndex(IndexMetadata indexMetadata) { - return EnhancedGlobalSecondaryIndex.builder() - .indexName(indexMetadata.name()) - .projection(pb -> pb.projectionType(ProjectionType.ALL)) - .build(); - } - @Override public T deleteItem(DeleteItemEnhancedRequest request) { TableOperation> operation = DeleteItemOperation.create(request); diff --git a/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DynamoDbTableUtils.java b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DynamoDbTableUtils.java new file mode 100644 index 00000000000..a70fdc43aba --- /dev/null +++ b/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DynamoDbTableUtils.java @@ -0,0 +1,78 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package software.amazon.awssdk.enhanced.dynamodb.internal.client; + +import static java.util.Collections.emptyList; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.enhanced.dynamodb.IndexMetadata; +import software.amazon.awssdk.enhanced.dynamodb.KeyAttributeMetadata; +import software.amazon.awssdk.enhanced.dynamodb.TableMetadata; +import software.amazon.awssdk.enhanced.dynamodb.TableSchema; +import software.amazon.awssdk.enhanced.dynamodb.model.EnhancedGlobalSecondaryIndex; +import software.amazon.awssdk.enhanced.dynamodb.model.EnhancedLocalSecondaryIndex; +import software.amazon.awssdk.services.dynamodb.model.ProjectionType; + +@SdkInternalApi +public final class DynamoDbTableUtils { + + private DynamoDbTableUtils() { + } + + public static Map> splitSecondaryIndicesToLocalAndGlobalOnes(TableSchema tableSchema) { + Collection indices = tableSchema.tableMetadata().indices(); + return indices.stream() + .filter(index -> !TableMetadata.primaryIndexName().equals(index.name())) + .collect(Collectors.groupingBy(metadata -> { + String partitionKeyName = metadata.partitionKey().map(KeyAttributeMetadata::name).orElse(null); + if (partitionKeyName == null) { + return IndexType.LSI; + } + return IndexType.GSI; + })); + } + + public static List extractLocalSecondaryIndices(Map> indicesGroups) { + return indicesGroups.getOrDefault(IndexType.LSI, emptyList()).stream() + .map(DynamoDbTableUtils::mapIndexMetadataToEnhancedLocalSecondaryIndex) + .collect(Collectors.toList()); + } + + public static EnhancedLocalSecondaryIndex mapIndexMetadataToEnhancedLocalSecondaryIndex(IndexMetadata indexMetadata) { + return EnhancedLocalSecondaryIndex.builder() + .indexName(indexMetadata.name()) + .projection(pb -> pb.projectionType(ProjectionType.ALL)) + .build(); + } + + public static List extractGlobalSecondaryIndices(Map> indicesGroups) { + return indicesGroups.getOrDefault(IndexType.GSI, emptyList()).stream() + .map(DynamoDbTableUtils::mapIndexMetadataToEnhancedGlobalSecondaryIndex) + .collect(Collectors.toList()); + } + + public static EnhancedGlobalSecondaryIndex mapIndexMetadataToEnhancedGlobalSecondaryIndex(IndexMetadata indexMetadata) { + return EnhancedGlobalSecondaryIndex.builder() + .indexName(indexMetadata.name()) + .projection(pb -> pb.projectionType(ProjectionType.ALL)) + .build(); + } + +}