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