From fa3a5ce04443aff3698aaa2ac7e62d84cbfd9ecc Mon Sep 17 00:00:00 2001 From: Zaker Farahi Date: Sun, 22 Sep 2024 18:44:13 +0200 Subject: [PATCH] Align behaviour of default table creation between sync and async table This adds the behaviour introduced in the sync DDB table to the async version as well. See commit ef2aa905c87 for original code --- .../bugfix-AmazonDynamoDB-d32dcc5.json | 6 ++ .../client/DefaultDynamoDbAsyncTable.java | 12 ++- .../internal/client/DefaultDynamoDbTable.java | 51 +----------- .../internal/client/DynamoDbTableUtils.java | 78 +++++++++++++++++++ 4 files changed, 99 insertions(+), 48 deletions(-) create mode 100644 .changes/next-release/bugfix-AmazonDynamoDB-d32dcc5.json create mode 100644 services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/client/DynamoDbTableUtils.java diff --git a/.changes/next-release/bugfix-AmazonDynamoDB-d32dcc5.json b/.changes/next-release/bugfix-AmazonDynamoDB-d32dcc5.json new file mode 100644 index 000000000000..4e93384b0ebd --- /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 1538e977b4c3..e9a858c5b0cd 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 1bd2638892bd..fab563c66508 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 000000000000..a70fdc43aba4 --- /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(); + } + +}