Upgrade dependencies and migrate to latest AWS SDK API Update dependencies - AWS Java SDK to 2.35.7 - Docker Java API to 3.6.0 - dynamodb-lock-client to 1.4.0 - jackson to 2.20.0 - jna to 5.18.1 - joda-time to 2.14.0 - testcontainers to 1.21.3 Migrate to the current AWS Java SDK API and remove dependencies of the old one. Change-Id: Ib5bae5e3fbe4f8fd552ada864350500a4079f445
diff --git a/BUILD b/BUILD index f45d775..279e50b 100644 --- a/BUILD +++ b/BUILD
@@ -18,19 +18,34 @@ resources = glob(["src/main/resources/**/*"]), deps = [ ":global-refdb-neverlink", - "@amazon-aws-core//jar", - "@amazon-dynamodb//jar", - "@amazon-regions//jar", + "@amazon-dynamodb-lock-client//jar", + "@amazon-sdk-apache-client//jar", + "@amazon-sdk-auth//jar", + "@amazon-sdk-aws-core//jar", + "@amazon-sdk-aws-json-protocol//jar", + "@amazon-sdk-checksums-spi//jar", + "@amazon-sdk-checksums//jar", "@amazon-sdk-core//jar", - "@amazon-utils//jar", - "@aws-java-sdk-core//jar", - "@aws-java-sdk-dynamodb//jar", - "@dynamodb-lock-client//jar", + "@amazon-sdk-dynamodb//jar", + "@amazon-sdk-endpoints-spi//jar", + "@amazon-sdk-http-auth-aws//jar", + "@amazon-sdk-http-auth-spi//jar", + "@amazon-sdk-http-auth//jar", + "@amazon-sdk-http-client-spi//jar", + "@amazon-sdk-identity-spi//jar", + "@amazon-sdk-metrics-spi//jar", + "@amazon-sdk-profiles//jar", + "@amazon-sdk-regions//jar", + "@amazon-sdk-retries-spi//jar", + "@amazon-sdk-retries//jar", + "@amazon-sdk-third-party-jackson-core//jar", + "@amazon-sdk-utils//jar", "@jackson-annotations//jar", "@jackson-core//jar", "@jackson-databind//jar", "@jackson-dataformat-cbor//jar", "@joda-time//jar", + "@reactive-streams//jar", ], ) @@ -39,7 +54,9 @@ timeout = "long", srcs = glob(["src/test/java/**/*.java"]), resources = glob(["src/test/resources/**/*"]), - tags = ["aws-dynamodb-refdb"], + tags = [ + "aws-dynamodb-refdb", + ], deps = [ ":aws-dynamodb-refdb__plugin_test_deps", ], @@ -52,9 +69,16 @@ exports = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [ ":aws-dynamodb-refdb__plugin", "//plugins/global-refdb", - "@amazon-regions//jar", - "@aws-java-sdk-dynamodb//jar", + "@amazon-sdk-auth//jar", + "@amazon-sdk-dynamodb//jar", + "@amazon-sdk-http-client-spi//jar", + "@amazon-sdk-identity-spi//jar", + "@amazon-sdk-json-utils//jar", + "@amazon-sdk-netty-nio-client//jar", + "@amazon-sdk-protocol-core//jar", + "@amazon-sdk-regions//jar", "@docker-java-api//jar", + "@docker-java-transport-zerodep//jar", "@docker-java-transport//jar", "@duct-tape//jar", "@jna//jar",
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl index 8267357..d0046e7 100644 --- a/external_plugin_deps.bzl +++ b/external_plugin_deps.bzl
@@ -1,99 +1,211 @@ load("//tools/bzl:maven_jar.bzl", "maven_jar") -AWS_SDK_VER = "2.16.19" -AWS_KINESIS_VER = "2.3.4" -JACKSON_VER = "2.10.4" -DOCKER_JAVA_VERS = "3.2.8" - def external_plugin_deps(): + """Dependencies of the aws-dynamodb-refdb plugin""" + + AWS_SDK_VER = "2.35.7" + maven_jar( - name = "amazon-dynamodb", - artifact = "software.amazon.awssdk:dynamodb:" + AWS_SDK_VER, - sha1 = "33ec7d291973658779b5777db2a0214a5c469e81", + name = "amazon-dynamodb-lock-client", + artifact = "com.amazonaws:dynamodb-lock-client:1.4.0", + sha1 = "6aae4bc1b4eeab582e370333b2174623c62f82c7", ) maven_jar( - name = "aws-java-sdk-dynamodb", - artifact = "com.amazonaws:aws-java-sdk-dynamodb:1.11.1006", - sha1 = "dd2c9dff101ae8dad26197f7b09a06d4e13965ca", + name = "amazon-sdk-apache-client", + artifact = "software.amazon.awssdk:apache-client:" + AWS_SDK_VER, + sha1 = "e3ba5ade5c38238a8735bd07d030afb1286d6a0d", ) maven_jar( - name = "dynamodb-lock-client", - artifact = "com.amazonaws:dynamodb-lock-client:1.1.0", - sha1 = "3aadced3599f3b2fd058bc75d48dde374f66e544", + name = "amazon-sdk-auth", + artifact = "software.amazon.awssdk:auth:" + AWS_SDK_VER, + sha1 = "371377f6eeb54cc0d847536208bdf4a4685ea48c", ) maven_jar( - name = "amazon-regions", - artifact = "software.amazon.awssdk:regions:" + AWS_SDK_VER, - sha1 = "089f4f3d3ef20b2486f09e71da638c03100eab64", + name = "amazon-sdk-aws-core", + artifact = "software.amazon.awssdk:aws-core:" + AWS_SDK_VER, + sha1 = "a139bfdf6125379b3153d12b66b33597a60f1f8e", + ) + + maven_jar( + name = "amazon-sdk-aws-json-protocol", + artifact = "software.amazon.awssdk:aws-json-protocol:" + AWS_SDK_VER, + sha1 = "fe3580b0839932b5922fe16b68b6a0937131aba7", + ) + + maven_jar( + name = "amazon-sdk-checksums", + artifact = "software.amazon.awssdk:checksums:" + AWS_SDK_VER, + sha1 = "47ad6340a76b91706dff61a65e4318a791754733", + ) + + maven_jar( + name = "amazon-sdk-checksums-spi", + artifact = "software.amazon.awssdk:checksums-spi:" + AWS_SDK_VER, + sha1 = "a924e1f21f41be1fd37563938c4d5ff3287c54ba", ) maven_jar( name = "amazon-sdk-core", artifact = "software.amazon.awssdk:sdk-core:" + AWS_SDK_VER, - sha1 = "02a60fd9c138048272ef8b6c80ae67491dd386a9", + sha1 = "8e4fd7f3020a00ff00e8ca2dacbd2256486dbf93", ) maven_jar( - name = "amazon-aws-core", - artifact = "software.amazon.awssdk:aws-core:" + AWS_SDK_VER, - sha1 = "0f50f5cf2698a0de7d2d77322cbf3fb13f76187f", + name = "amazon-sdk-dynamodb", + artifact = "software.amazon.awssdk:dynamodb:" + AWS_SDK_VER, + sha1 = "40ef2f0e7256a03a97f5fa65b140f947538e8b7e", ) maven_jar( - name = "amazon-utils", + name = "amazon-sdk-endpoints-spi", + artifact = "software.amazon.awssdk:endpoints-spi:" + AWS_SDK_VER, + sha1 = "99f906164192dc3242aad2e17313c48231b7fb0b", + ) + + maven_jar( + name = "amazon-sdk-http-auth", + artifact = "software.amazon.awssdk:http-auth:" + AWS_SDK_VER, + sha1 = "0922970e363017e3eba324e7cd2d3a92b87fc97f", + ) + + maven_jar( + name = "amazon-sdk-http-auth-aws", + artifact = "software.amazon.awssdk:http-auth-aws:" + AWS_SDK_VER, + sha1 = "cef979ee5f39359b75189363867800cee6ff8fc1", + ) + + maven_jar( + name = "amazon-sdk-http-auth-spi", + artifact = "software.amazon.awssdk:http-auth-spi:" + AWS_SDK_VER, + sha1 = "f547073978d6f5968b08bc5a1eae1c689dd50006", + ) + + maven_jar( + name = "amazon-sdk-http-client-spi", + artifact = "software.amazon.awssdk:http-client-spi:" + AWS_SDK_VER, + sha1 = "55aaa5e6b03302b3d801f16e5cfb1b71de983bff", + ) + + maven_jar( + name = "amazon-sdk-identity-spi", + artifact = "software.amazon.awssdk:identity-spi:" + AWS_SDK_VER, + sha1 = "d3cc80a7a6a99492b242482c25020c737cbf3959", + ) + + maven_jar( + name = "amazon-sdk-json-utils", + artifact = "software.amazon.awssdk:json-utils:" + AWS_SDK_VER, + sha1 = "013636801d30c51e0e18f12636a75db8f45f501b", + ) + + maven_jar( + name = "amazon-sdk-metrics-spi", + artifact = "software.amazon.awssdk:metrics-spi:" + AWS_SDK_VER, + sha1 = "320c8205baad6a6e15d868c7f45b74f497b59d3e", + ) + + maven_jar( + name = "amazon-sdk-netty-nio-client", + artifact = "software.amazon.awssdk:netty-nio-client:" + AWS_SDK_VER, + sha1 = "98e60e5af0f421b42b9afc582d3f08ce7fc9c58f", + ) + + maven_jar( + name = "amazon-sdk-profiles", + artifact = "software.amazon.awssdk:profiles:" + AWS_SDK_VER, + sha1 = "199c71ed266e97011dd999e2a41d2d305dd8baa9", + ) + + maven_jar( + name = "amazon-sdk-protocol-core", + artifact = "software.amazon.awssdk:protocol-core:" + AWS_SDK_VER, + sha1 = "e02285068d1b7c78e09d0a7233f94c07c9d0c5bb", + ) + + maven_jar( + name = "amazon-sdk-regions", + artifact = "software.amazon.awssdk:regions:" + AWS_SDK_VER, + sha1 = "43a383d970fbaabb61ba261192c9a592f94b491d", + ) + + maven_jar( + name = "amazon-sdk-retries", + artifact = "software.amazon.awssdk:retries:" + AWS_SDK_VER, + sha1 = "81e625923a487d4a24e3e546ec74620b8ccc9e92", + ) + + maven_jar( + name = "amazon-sdk-retries-spi", + artifact = "software.amazon.awssdk:retries-spi:" + AWS_SDK_VER, + sha1 = "a902e42e49b32799af4b76f176cae715298dcdd8", + ) + + maven_jar( + name = "amazon-sdk-third-party-jackson-core", + artifact = "software.amazon.awssdk:third-party-jackson-core:" + AWS_SDK_VER, + sha1 = "039256c93502cb9a0d859600ce4d0623c45bdc55", + ) + + maven_jar( + name = "amazon-sdk-utils", artifact = "software.amazon.awssdk:utils:" + AWS_SDK_VER, - sha1 = "53edaa1f884682ac3091293eff3eb024ed0e36bb", + sha1 = "1240513bdae17b33857d34af95c7f8bd3090e2d0", ) maven_jar( - name = "aws-java-sdk-core", - artifact = "com.amazonaws:aws-java-sdk-core:1.11.960", - sha1 = "18b6b2a5cb83a0e2e33a593302b5dbe0ca2ade64", + name = "reactive-streams", + artifact = "org.reactivestreams:reactive-streams:1.0.4", + sha1 = "3864a1320d97d7b045f729a326e1e077661f31b7", ) + JACKSON_VER = "2.20.0" + maven_jar( name = "jackson-databind", artifact = "com.fasterxml.jackson.core:jackson-databind:" + JACKSON_VER, - sha1 = "76e9152e93d4cf052f93a64596f633ba5b1c8ed9", + sha1 = "f0a5e62fbd21285e9a5498a60dccb097e1ef793b", ) maven_jar( name = "jackson-dataformat-cbor", artifact = "com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:" + JACKSON_VER, - sha1 = "c854bb2d46138198cb5d4aae86ef6c04b8bc1e70", + sha1 = "c10e9032bec62df3089ca1cbdef43a1453aca261", ) maven_jar( name = "jackson-annotations", - artifact = "com.fasterxml.jackson.core:jackson-annotations:" + JACKSON_VER, - sha1 = "6ae6028aff033f194c9710ad87c224ccaadeed6c", + # the third part of the version number was missed in this release + artifact = "com.fasterxml.jackson.core:jackson-annotations:2.20", + sha1 = "6a5e7291ea3f2b590a7ce400adb7b3aea4d7e12c", ) maven_jar( name = "jackson-core", artifact = "com.fasterxml.jackson.core:jackson-core:" + JACKSON_VER, - sha1 = "8796585e716440d6dd5128b30359932a9eb74d0d", + sha1 = "3c97f7fad069f7cfae639d790bd93d6a0b2dff31", ) maven_jar( name = "joda-time", - artifact = "joda-time:joda-time:2.10.10", - sha1 = "29e8126e31f41e5c12b9fe3a7eb02e704c47d70b", + artifact = "joda-time:joda-time:2.14.0", + sha1 = "1fa665c1ce64a2c8c94f63fc5c1ee7bd742d2022", ) + TESTCONTAINERS_VERS = "1.21.3" + maven_jar( name = "testcontainer-localstack", - artifact = "org.testcontainers:localstack:1.15.2", - sha1 = "ae3c4717bc5f37410abbb490cb46d349a77990a0", + artifact = "org.testcontainers:localstack:" + TESTCONTAINERS_VERS, + sha1 = "86cd23aaba16741005c794d26419a16c8470a8e1", ) maven_jar( name = "testcontainers", - artifact = "org.testcontainers:testcontainers:1.15.3", - sha1 = "95c6cfde71c2209f0c29cb14e432471e0b111880", + artifact = "org.testcontainers:testcontainers:" + TESTCONTAINERS_VERS, + sha1 = "aa3e792d2cf4598019933c42f1cfa55bd608ce8b", ) maven_jar( @@ -102,16 +214,24 @@ sha1 = "20d31a578030ec8e941888537267d3123c2ad1c1", ) + DOCKER_JAVA_VERS = "3.6.0" + maven_jar( name = "docker-java-api", artifact = "com.github.docker-java:docker-java-api:" + DOCKER_JAVA_VERS, - sha1 = "4ac22a72d546a9f3523cd4b5fabffa77c4a6ec7c", + sha1 = "caeb5bee6a9c07bff31f73ace576436168e2aa47", ) maven_jar( name = "docker-java-transport", artifact = "com.github.docker-java:docker-java-transport:" + DOCKER_JAVA_VERS, - sha1 = "c3b5598c67d0a5e2e780bf48f520da26b9915eab", + sha1 = "d522c467aad17fd927e0db0130d2849a321a36aa", + ) + + maven_jar( + name = "docker-java-transport-zerodep", + artifact = "com.github.docker-java:docker-java-transport-zerodep:" + DOCKER_JAVA_VERS, + sha1 = "549f4985f9c7714deff47d1041603e85e132d184", ) maven_jar( @@ -122,6 +242,6 @@ maven_jar( name = "jna", - artifact = "net.java.dev.jna:jna:5.5.0", - sha1 = "0e0845217c4907822403912ad6828d8e0b256208", + artifact = "net.java.dev.jna:jna:5.18.1", + sha1 = "b27ba04287cc4abe769642fe8318d39fc89bf937", )
diff --git a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/AmazonDynamoDBProvider.java b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/AmazonDynamoDBProvider.java deleted file mode 100644 index eb13649..0000000 --- a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/AmazonDynamoDBProvider.java +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright (C) 2021 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License 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 com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb; - -import com.amazonaws.auth.AWSCredentialsProvider; -import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; -import com.amazonaws.auth.profile.ProfileCredentialsProvider; -import com.amazonaws.client.builder.AwsClientBuilder; -import com.amazonaws.regions.DefaultAwsRegionProviderChain; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; -import com.google.inject.Inject; -import com.google.inject.Provider; -import com.google.inject.Singleton; -import software.amazon.awssdk.regions.Region; - -@Singleton -class AmazonDynamoDBProvider implements Provider<AmazonDynamoDB> { - private final Configuration configuration; - - @Inject - AmazonDynamoDBProvider(Configuration configuration) { - this.configuration = configuration; - } - - @Override - public AmazonDynamoDB get() { - AmazonDynamoDBClientBuilder builder = AmazonDynamoDBClientBuilder.standard(); - String region = - configuration - .getRegion() - .map(Region::id) - .orElseGet(() -> new DefaultAwsRegionProviderChain().getRegion()); - - configuration - .getEndpoint() - .ifPresent( - endpoint -> - builder.withEndpointConfiguration( - new AwsClientBuilder.EndpointConfiguration(endpoint.toASCIIString(), region))); - return builder.withCredentials(getCredentialsProvider()).build(); - } - - private AWSCredentialsProvider getCredentialsProvider() { - return configuration - .getAwsConfigurationProfileName() - .<AWSCredentialsProvider>map(ProfileCredentialsProvider::new) - .orElse(new DefaultAWSCredentialsProviderChain()); - } -}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBLifeCycleManager.java b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBLifeCycleManager.java index 1003164..455beea 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBLifeCycleManager.java +++ b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBLifeCycleManager.java
@@ -1,51 +1,35 @@ -// Copyright (C) 2021 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License 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 com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb; import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.DynamoDBRefDatabase.LOCK_DB_PRIMARY_KEY; import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.DynamoDBRefDatabase.LOCK_DB_SORT_KEY; import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.DynamoDBRefDatabase.REF_DB_PRIMARY_KEY; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDBLockClient; -import com.amazonaws.services.dynamodbv2.CreateDynamoDBTableOptions; -import com.amazonaws.services.dynamodbv2.document.Table; -import com.amazonaws.services.dynamodbv2.model.AttributeDefinition; -import com.amazonaws.services.dynamodbv2.model.CreateTableRequest; -import com.amazonaws.services.dynamodbv2.model.KeySchemaElement; -import com.amazonaws.services.dynamodbv2.model.KeyType; -import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; -import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException; -import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType; -import com.amazonaws.services.dynamodbv2.util.TableUtils; import com.google.common.annotations.VisibleForTesting; import com.google.common.flogger.FluentLogger; import com.google.gerrit.extensions.events.LifecycleListener; import com.google.inject.Inject; import com.google.inject.Singleton; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition; +import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest; +import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest; +import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement; +import software.amazon.awssdk.services.dynamodb.model.KeyType; +import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput; +import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException; +import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType; +import software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter; @Singleton class DynamoDBLifeCycleManager implements LifecycleListener { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private final Configuration configuration; - private final AmazonDynamoDB dynamoDB; + private final DynamoDbClient dynamoDbClient; @Inject - DynamoDBLifeCycleManager(Configuration configuration, AmazonDynamoDB dynamoDB) { + DynamoDBLifeCycleManager(Configuration configuration, DynamoDbClient dynamoDbClient) { this.configuration = configuration; - this.dynamoDB = dynamoDB; + this.dynamoDbClient = dynamoDbClient; } // TODO: it is useful to create these at start up during development @@ -59,72 +43,110 @@ } @Override - public void stop() {} + public void stop() { + // No-op. The dynamoDbClient lifecycle is managed by the provider. + } private void createLockTableIfDoesntExist() { - if (!tableExists(dynamoDB, configuration.getLocksTableName())) { - logger.atWarning().log( - "Attempt to create lock table '%s'", configuration.getLocksTableName()); - AmazonDynamoDBLockClient.createLockTableInDynamoDB( - CreateDynamoDBTableOptions.builder( - dynamoDB, new ProvisionedThroughput(10L, 10L), configuration.getLocksTableName()) - .withPartitionKeyName(LOCK_DB_PRIMARY_KEY) - .withSortKeyName(LOCK_DB_SORT_KEY) - .build()); + String tableName = configuration.getLocksTableName(); + if (tableExists(dynamoDbClient, tableName)) { + logger.atFine().log("Lock table '%s' already exists, nothing to do.", tableName); + return; + } - try { - logger.atWarning().log( - "Wait for lock table '%s' creation", configuration.getLocksTableName()); - TableUtils.waitUntilActive(dynamoDB, configuration.getLocksTableName()); - logger.atWarning().log( - "lock table '%s' successfully created and active", configuration.getLocksTableName()); - } catch (InterruptedException e) { - logger.atSevere().withCause(e).log( - "Timeout when creating lock table '%s'", configuration.getLocksTableName()); + logger.atInfo().log("Attempting to create lock table '%s'", tableName); + try { + CreateTableRequest request = + CreateTableRequest.builder() + .tableName(tableName) + .attributeDefinitions( + AttributeDefinition.builder() + .attributeName(LOCK_DB_PRIMARY_KEY) + .attributeType(ScalarAttributeType.S) + .build(), + AttributeDefinition.builder() + .attributeName(LOCK_DB_SORT_KEY) + .attributeType(ScalarAttributeType.S) + .build()) + .keySchema( + KeySchemaElement.builder() + .attributeName(LOCK_DB_PRIMARY_KEY) + .keyType(KeyType.HASH) + .build(), + KeySchemaElement.builder() + .attributeName(LOCK_DB_SORT_KEY) + .keyType(KeyType.RANGE) + .build()) + .provisionedThroughput( + ProvisionedThroughput.builder() + .readCapacityUnits(10L) + .writeCapacityUnits(10L) + .build()) + .build(); + + dynamoDbClient.createTable(request); + + // Use a waiter to block until the table is active. + try (DynamoDbWaiter waiter = dynamoDbClient.waiter()) { + logger.atInfo().log("Waiting for lock table '%s' to become active...", tableName); + waiter.waitUntilTableExists(DescribeTableRequest.builder().tableName(tableName).build()); + logger.atInfo().log("Lock table '%s' successfully created and active.", tableName); } - } else { - logger.atWarning().log( - "Lock table '%s' already exists, nothing to do.", configuration.getLocksTableName()); + } catch (Exception e) { + // Catching a broad exception as waiter can throw different things. + logger.atSevere().withCause(e).log("Failed to create or wait for lock table '%s'", tableName); } } private void createRefsDbTableIfDoesntExist() { - boolean created = - TableUtils.createTableIfNotExists( - dynamoDB, - new CreateTableRequest() - .withTableName(configuration.getRefsDbTableName()) - .withAttributeDefinitions( - new AttributeDefinition(REF_DB_PRIMARY_KEY, ScalarAttributeType.S)) - .withKeySchema(new KeySchemaElement(REF_DB_PRIMARY_KEY, KeyType.HASH)) - .withProvisionedThroughput(new ProvisionedThroughput(10L, 10L))); + String tableName = configuration.getRefsDbTableName(); + if (tableExists(dynamoDbClient, tableName)) { + logger.atFine().log("RefsDb table '%s' already exists, nothing to do.", tableName); + return; + } - if (created) { - try { - logger.atWarning().log( - "Wait for refsDB table '%s' creation", configuration.getRefsDbTableName()); - TableUtils.waitUntilActive(dynamoDB, configuration.getRefsDbTableName()); - logger.atWarning().log( - "refsDb table '%s' successfully created and active", - configuration.getRefsDbTableName()); - } catch (InterruptedException e) { - logger.atSevere().withCause(e).log( - "Timeout when creating refsDb table '%s'", configuration.getRefsDbTableName()); + logger.atInfo().log("Attempting to create refsDb table '%s'", tableName); + try { + CreateTableRequest request = + CreateTableRequest.builder() + .tableName(tableName) + .attributeDefinitions( + AttributeDefinition.builder() + .attributeName(REF_DB_PRIMARY_KEY) + .attributeType(ScalarAttributeType.S) + .build()) + .keySchema( + KeySchemaElement.builder() + .attributeName(REF_DB_PRIMARY_KEY) + .keyType(KeyType.HASH) + .build()) + .provisionedThroughput( + ProvisionedThroughput.builder() + .readCapacityUnits(10L) + .writeCapacityUnits(10L) + .build()) + .build(); + + dynamoDbClient.createTable(request); + + try (DynamoDbWaiter waiter = dynamoDbClient.waiter()) { + logger.atInfo().log("Waiting for refsDb table '%s' to become active...", tableName); + waiter.waitUntilTableExists(DescribeTableRequest.builder().tableName(tableName).build()); + logger.atInfo().log("RefsDb table '%s' successfully created and active.", tableName); } - } else { - logger.atWarning().log( - "RefsDb table '%s' already exists, nothing to do.", configuration.getRefsDbTableName()); + } catch (Exception e) { + logger.atSevere().withCause(e).log( + "Failed to create or wait for refsDb table '%s'", tableName); } } @VisibleForTesting - static boolean tableExists(AmazonDynamoDB dynamoDB, String tableName) { - final Table table = new Table(dynamoDB, tableName); + static boolean tableExists(DynamoDbClient dynamoDbClient, String tableName) { try { - table.describe(); + dynamoDbClient.describeTable(DescribeTableRequest.builder().tableName(tableName).build()); + return true; } catch (ResourceNotFoundException e) { return false; } - return true; } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBLockClientProvider.java b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBLockClientProvider.java index 42009f1..b94629e 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBLockClientProvider.java +++ b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBLockClientProvider.java
@@ -17,30 +17,31 @@ import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.DynamoDBRefDatabase.LOCK_DB_PRIMARY_KEY; import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.DynamoDBRefDatabase.LOCK_DB_SORT_KEY; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBLockClient; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBLockClientOptions; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import java.util.concurrent.TimeUnit; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; @Singleton class DynamoDBLockClientProvider implements Provider<AmazonDynamoDBLockClient> { private final Configuration configuration; - private final AmazonDynamoDB dynamoDB; + private final DynamoDbClient dynamoDbClient; @Inject - DynamoDBLockClientProvider(Configuration configuration, AmazonDynamoDB dynamoDB) { + DynamoDBLockClientProvider(Configuration configuration, DynamoDbClient dynamoDbClient) { this.configuration = configuration; - this.dynamoDB = dynamoDB; + this.dynamoDbClient = dynamoDbClient; } @Override public AmazonDynamoDBLockClient get() { final boolean createHeartbeatBackgroundThread = true; + return new AmazonDynamoDBLockClient( - AmazonDynamoDBLockClientOptions.builder(dynamoDB, configuration.getLocksTableName()) + AmazonDynamoDBLockClientOptions.builder(dynamoDbClient, configuration.getLocksTableName()) .withPartitionKeyName(LOCK_DB_PRIMARY_KEY) .withSortKeyName(LOCK_DB_SORT_KEY) .withTimeUnit(TimeUnit.SECONDS)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBRefDatabase.java b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBRefDatabase.java index 712f5d1..68ac4e7 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBRefDatabase.java +++ b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBRefDatabase.java
@@ -17,22 +17,14 @@ import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.ProjectVersionCacheModule.PROJECT_VERSION_CACHE; import com.amazonaws.services.dynamodbv2.AcquireLockOptions; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBLockClient; import com.amazonaws.services.dynamodbv2.LockItem; -import com.amazonaws.services.dynamodbv2.model.AttributeAction; -import com.amazonaws.services.dynamodbv2.model.AttributeValue; -import com.amazonaws.services.dynamodbv2.model.AttributeValueUpdate; -import com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException; -import com.amazonaws.services.dynamodbv2.model.GetItemResult; import com.amazonaws.services.dynamodbv2.model.LockNotGrantedException; -import com.amazonaws.services.dynamodbv2.model.UpdateItemRequest; import com.gerritforge.gerrit.globalrefdb.ExtendedGlobalRefDatabase; import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException; import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableMap; import com.google.common.flogger.FluentLogger; import com.google.gerrit.common.Nullable; import com.google.gerrit.entities.Project; @@ -40,11 +32,19 @@ import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.name.Named; +import java.util.Map; import java.util.Optional; import java.util.concurrent.ExecutionException; import javax.inject.Singleton; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; +import software.amazon.awssdk.core.exception.SdkException; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.model.AttributeValue; +import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException; +import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; +import software.amazon.awssdk.services.dynamodb.model.GetItemResponse; +import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest; @Singleton public class DynamoDBRefDatabase implements ExtendedGlobalRefDatabase { @@ -57,14 +57,14 @@ private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private final AmazonDynamoDBLockClient lockClient; - private final AmazonDynamoDB dynamoDBClient; + private final DynamoDbClient dynamoDBClient; private final Configuration configuration; private final LoadingCache<String, Optional<Integer>> projectVersionCache; @Inject DynamoDBRefDatabase( AmazonDynamoDBLockClient lockClient, - AmazonDynamoDB dynamoDBClient, + DynamoDbClient dynamoDBClient, Configuration configuration, @Named(PROJECT_VERSION_CACHE) LoadingCache<String, Optional<Integer>> projectVersionCache) { this.lockClient = lockClient; @@ -88,12 +88,12 @@ @Override public boolean isUpToDate(Project.NameKey project, Ref ref) throws GlobalRefDbLockException { try { - GetItemResult result = getItemFromDynamoDB(pathFor(project, ref.getName())); - if (!exists(result)) { + GetItemResponse response = getItemFromDynamoDB(pathFor(project, ref.getName())); + if (!response.hasItem()) { return true; } - String valueInDynamoDB = result.getItem().get(REF_DB_VALUE_KEY).getS(); + String valueInDynamoDB = response.item().get(REF_DB_VALUE_KEY).s(); ObjectId objectIdInSharedRefDb = ObjectId.fromString(valueInDynamoDB); boolean isUpToDate = objectIdInSharedRefDb.equals(ref.getObjectId()); @@ -134,19 +134,22 @@ private boolean doCompareAndPut( Project.NameKey project, String refPath, String currValueForPath, String newValueForPath) throws GlobalRefDbSystemError { + Map<String, AttributeValue> key = getKey(refPath); + Map<String, AttributeValue> expressionAttributeValues = + Map.of( + ":old_value", AttributeValue.builder().s(currValueForPath).build(), + ":new_value", AttributeValue.builder().s(newValueForPath).build()); UpdateItemRequest updateItemRequest = - new UpdateItemRequest() - .withTableName(configuration.getRefsDbTableName()) - .withKey(ImmutableMap.of(REF_DB_PRIMARY_KEY, new AttributeValue(refPath))) - .withExpressionAttributeValues( - ImmutableMap.of( - ":old_value", new AttributeValue(currValueForPath), - ":new_value", new AttributeValue(newValueForPath))) - .withUpdateExpression(String.format("SET %s = %s", REF_DB_VALUE_KEY, ":new_value")) - .withConditionExpression( + UpdateItemRequest.builder() + .tableName(configuration.getRefsDbTableName()) + .key(key) + .expressionAttributeValues(expressionAttributeValues) + .updateExpression(String.format("SET %s = :new_value", REF_DB_VALUE_KEY)) + .conditionExpression( String.format( "attribute_not_exists(%s) OR %s = :old_value", - REF_DB_PRIMARY_KEY, REF_DB_VALUE_KEY)); + REF_DB_PRIMARY_KEY, REF_DB_VALUE_KEY)) + .build(); try { dynamoDBClient.updateItem(updateItemRequest); logger.atFine().log( @@ -158,7 +161,7 @@ "Conditional Check Failure when updating refPath %s. expected: %s New: %s", refPath, currValueForPath, newValueForPath); return false; - } catch (Exception e) { + } catch (SdkException e) { throw new GlobalRefDbSystemError( String.format( "Error updating refPath %s. expected: %s new: %s", @@ -175,16 +178,21 @@ public <T> void doPut(NameKey project, String refPath, T value) throws GlobalRefDbSystemError { String refValue = Optional.ofNullable(value).map(Object::toString).orElse(ObjectId.zeroId().getName()); + Map<String, AttributeValue> key = getKey(refPath); + Map<String, AttributeValue> expressionAttributeValues = + Map.of(":val", AttributeValue.builder().s(refValue).build()); + UpdateItemRequest request = + UpdateItemRequest.builder() + .tableName(configuration.getRefsDbTableName()) + .key(key) + .updateExpression(String.format("SET %s = :val", REF_DB_VALUE_KEY)) + .expressionAttributeValues(expressionAttributeValues) + .build(); try { - dynamoDBClient.updateItem( - configuration.getRefsDbTableName(), - ImmutableMap.of(REF_DB_PRIMARY_KEY, new AttributeValue(refPath)), - ImmutableMap.of( - REF_DB_VALUE_KEY, - new AttributeValueUpdate(new AttributeValue(refValue), AttributeAction.PUT))); + dynamoDBClient.updateItem(request); logger.atFine().log( "Updated path for project %s, path %s, value: %s", project.get(), refPath, refValue); - } catch (Exception e) { + } catch (SdkException e) { throw new GlobalRefDbSystemError( String.format( "Error updating path for project %s, path %s. value: %s", @@ -258,11 +266,11 @@ public <T> Optional<T> get(Project.NameKey project, String refName, Class<T> clazz) throws GlobalRefDbSystemError { try { - GetItemResult item = getItemFromDynamoDB(pathFor(project, refName)); - if (!exists(item)) { + GetItemResponse reponse = getItemFromDynamoDB(pathFor(project, refName)); + if (!reponse.hasItem()) { return Optional.empty(); } - String refValue = item.getItem().get(REF_DB_VALUE_KEY).getS(); + String refValue = reponse.item().get(REF_DB_VALUE_KEY).s(); // TODO: not every string might be cast to T (it should work now because the // only usage of this function requests string, but we should be serializing @@ -274,19 +282,27 @@ } } - private GetItemResult getItemFromDynamoDB(String refPath) { + private GetItemResponse getItemFromDynamoDB(String refPath) { return getItemFromDynamoDB(refPath, true); } - public GetItemResult getItemFromDynamoDB(String refPath, Boolean consistentRead) { - return dynamoDBClient.getItem( - configuration.getRefsDbTableName(), - ImmutableMap.of(REF_DB_PRIMARY_KEY, new AttributeValue(refPath)), - consistentRead); + public GetItemResponse getItemFromDynamoDB(String refPath, Boolean consistentRead) { + Map<String, AttributeValue> key = getKey(refPath); + GetItemRequest request = + GetItemRequest.builder() + .tableName(configuration.getRefsDbTableName()) + .key(key) + .consistentRead(consistentRead) + .build(); + return dynamoDBClient.getItem(request); } - public boolean exists(GetItemResult result) { - return result.getItem() != null && !result.getItem().isEmpty(); + public Map<String, AttributeValue> getKey(String refPath) { + return Map.of(REF_DB_PRIMARY_KEY, AttributeValue.builder().s(refPath).build()); + } + + public boolean exists(GetItemResponse response) { + return response.hasItem() && !response.item().isEmpty(); } static class ProjectVersionCacheLoader extends CacheLoader<String, Optional<Integer>> { @@ -300,13 +316,13 @@ @Override public Optional<Integer> load(String project) throws Exception { - GetItemResult item = + GetItemResponse item = dynamoDBRefDatabaseProvider .get() .getItemFromDynamoDB(currentVersionKey(Project.nameKey(project)), false); Integer currentVersion = dynamoDBRefDatabaseProvider.get().exists(item) - ? Integer.parseInt(item.getItem().get(REF_DB_VALUE_KEY).getS()) + ? Integer.parseInt(item.item().get(REF_DB_VALUE_KEY).s()) : null; return Optional.ofNullable(currentVersion); }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDbClientProvider.java b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDbClientProvider.java new file mode 100644 index 0000000..05b15b0 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDbClientProvider.java
@@ -0,0 +1,57 @@ +// Copyright (C) 2025 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License 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 com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; +import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; +import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; +import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; +import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; +import software.amazon.awssdk.services.dynamodb.DynamoDbClientBuilder; + +@Singleton +class DynamoDbClientProvider implements Provider<DynamoDbClient> { + private final Configuration configuration; + + @Inject + DynamoDbClientProvider(Configuration configuration) { + this.configuration = configuration; + } + + @Override + public DynamoDbClient get() { + DynamoDbClientBuilder builder = + DynamoDbClient.builder() + .credentialsProvider(getCredentialsProvider()) + .region( + configuration + .getRegion() + .orElseGet(() -> new DefaultAwsRegionProviderChain().getRegion())); + configuration.getEndpoint().ifPresent(builder::endpointOverride); + + return builder.build(); + } + + private AwsCredentialsProvider getCredentialsProvider() { + return configuration + .getAwsConfigurationProfileName() + .<AwsCredentialsProvider>map( + profileName -> ProfileCredentialsProvider.builder().profileName(profileName).build()) + .orElseGet(() -> DefaultCredentialsProvider.builder().build()); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/Module.java b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/Module.java index 4def9f6..a5a4b4e 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/Module.java +++ b/src/main/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/Module.java
@@ -16,13 +16,13 @@ import static com.google.inject.Scopes.SINGLETON; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBLockClient; import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase; import com.google.common.flogger.FluentLogger; import com.google.gerrit.extensions.registration.DynamicItem; import com.google.gerrit.lifecycle.LifecycleModule; import com.google.inject.Scopes; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; class Module extends LifecycleModule { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); @@ -34,7 +34,7 @@ .to(DynamoDBRefDatabase.class) .in(Scopes.SINGLETON); install(new ProjectVersionCacheModule()); - bind(AmazonDynamoDB.class).toProvider(AmazonDynamoDBProvider.class).in(SINGLETON); + bind(DynamoDbClient.class).toProvider(DynamoDbClientProvider.class).in(SINGLETON); bind(AmazonDynamoDBLockClient.class).toProvider(DynamoDBLockClientProvider.class).in(SINGLETON); listener().to(DynamoDBLifeCycleManager.class); }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBRefDatabaseIT.java b/src/test/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBRefDatabaseIT.java index 246ff79..c39d0b3 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBRefDatabaseIT.java +++ b/src/test/java/com/googlesource/gerrit/plugins/validation/dfsrefdb/dynamodb/DynamoDBRefDatabaseIT.java
@@ -19,9 +19,9 @@ import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.Configuration.DEFAULT_REFS_DB_TABLE_NAME; import static org.testcontainers.containers.localstack.LocalStackContainer.Service.DYNAMODB; -import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException; import com.google.common.cache.LoadingCache; +import com.google.common.flogger.FluentLogger; import com.google.gerrit.acceptance.LightweightPluginDaemonTest; import com.google.gerrit.acceptance.TestPlugin; import com.google.gerrit.acceptance.WaitUtil; @@ -35,49 +35,57 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdRef; import org.eclipse.jgit.lib.Ref; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.testcontainers.containers.localstack.LocalStackContainer; import org.testcontainers.utility.DockerImageName; +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; @TestPlugin( name = "aws-dynamodb-refdb", sysModule = "com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.Module") public class DynamoDBRefDatabaseIT extends LightweightPluginDaemonTest { - private static final Duration DYNAMODB_TABLE_CREATION_TIMEOUT = Duration.ofSeconds(10); - + private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private static final int LOCALSTACK_PORT = 4566; - private static final LocalStackContainer localstack = - new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.12.8")) - .withServices(DYNAMODB) - .withExposedPorts(LOCALSTACK_PORT); + private static final Duration DYNAMODB_TABLE_CREATION_TIMEOUT = Duration.ofSeconds(10); + private static LocalStackContainer localstack; + + @BeforeClass + public static void setupLocalStack() { + logger.atFine().log("--- Testcontainers Debug Info ---"); + logger.atFine().log("DOCKER_HOST (env): %s", System.getenv("DOCKER_HOST")); + logger.atFine().log("docker.host (prop): %s", System.getProperty("docker.host")); + logger.atFine().log("---------------------------------"); + + localstack = + new LocalStackContainer(DockerImageName.parse("localstack/localstack").withTag("4.9.2")) + .withServices(DYNAMODB) + .withExposedPorts(LOCALSTACK_PORT); + localstack.start(); + } + + @AfterClass + public static void tearDown() { + localstack.close(); + } @Before @Override public void setUpTestPlugin() throws Exception { - localstack.start(); - System.setProperty("endpoint", localstack.getEndpointOverride(DYNAMODB).toASCIIString()); System.setProperty("region", localstack.getRegion()); - System.setProperty("aws.accessKeyId", localstack.getAccessKey()); - // The secret key property name has changed from aws-sdk 1.11.x and 2.x [1] - // Export both names so that default credential provider chains work regardless - // he underlying library version. - // https: // docs.aws.amazon.com/sdk-for-java/latest/migration-guide/client-credential.html - System.setProperty("aws.secretKey", localstack.getSecretKey()); + // localstack recommends to set both access key id and secret access key to the same value + // it ignores the secret access key + // see https://docs.localstack.cloud/aws/capabilities/config/credentials/ + System.setProperty("aws.accessKeyId", localstack.getSecretKey()); System.setProperty("aws.secretAccessKey", localstack.getSecretKey()); super.setUpTestPlugin(); } - @Override - public void tearDownTestPlugin() { - localstack.close(); - - super.tearDownTestPlugin(); - } - @Test public void shouldEnsureLockTableExists() throws Exception { WaitUtil.waitUntil( @@ -276,8 +284,8 @@ assertThat(dynamoDBRefDatabase().getCurrentVersion(project)).isNull(); } - private AmazonDynamoDB dynamoDBClient() { - return plugin.getSysInjector().getInstance(AmazonDynamoDB.class); + private DynamoDbClient dynamoDBClient() { + return plugin.getSysInjector().getInstance(DynamoDbClient.class); } private DynamoDBRefDatabase dynamoDBRefDatabase() {
diff --git a/src/test/resources/simplelogger.properties b/src/test/resources/simplelogger.properties new file mode 100644 index 0000000..099992b --- /dev/null +++ b/src/test/resources/simplelogger.properties
@@ -0,0 +1,9 @@ +# Set the default log level to TRACE to see everything +org.slf4j.simpleLogger.defaultLogLevel = trace + +# Show thread names +org.slf4j.simpleLogger.showThreadName = true + +# Show date and time +org.slf4j.simpleLogger.showDateTime = true +org.slf4j.simpleLogger.dateTimeFormat = yyyy-MM-dd HH:mm:ss:SSS Z \ No newline at end of file