Make DynamoDBRefDatebase class implement ExtendedGlobalRefDatabase
ExtendedGlobalRefDatabase provides `put` function to update item
in the DynamoDB. Opposite to compareAndPut this method is not
checking current global-refdb value. `put` method should be used
to update value when atomicity doesn't have to be ensured.
Bug: Issue 297440085
Change-Id: Ic50b07d5aac0f533fd81d019b606848a522b2ed5
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 f6bdddc..933fd3f 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
@@ -18,17 +18,20 @@
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.GlobalRefDatabase;
+import com.gerritforge.gerrit.globalrefdb.ExtendedGlobalRefDatabase;
import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
import com.google.common.collect.ImmutableMap;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.Project.NameKey;
import com.google.inject.Inject;
import java.util.Optional;
import javax.inject.Singleton;
@@ -36,7 +39,7 @@
import org.eclipse.jgit.lib.Ref;
@Singleton
-public class DynamoDBRefDatabase implements GlobalRefDatabase {
+public class DynamoDBRefDatabase implements ExtendedGlobalRefDatabase {
public static final String REF_DB_PRIMARY_KEY = "refPath";
public static final String REF_DB_VALUE_KEY = "refValue";
@@ -146,6 +149,29 @@
}
@Override
+ public <T> void put(NameKey project, String refName, T value) throws GlobalRefDbSystemError {
+ String refPath = pathFor(project, refName);
+ String refValue =
+ Optional.ofNullable(value).map(Object::toString).orElse(ObjectId.zeroId().getName());
+ 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)));
+ logger.atFine().log(
+ "Updated path for project %s, path %s, value: %s", project.get(), refPath, refValue);
+ } catch (Exception e) {
+ throw new GlobalRefDbSystemError(
+ String.format(
+ "Error updating path for project %s, path %s. value: %s",
+ project.get(), refPath, refValue),
+ e);
+ }
+ }
+
+ @Override
public AutoCloseable lockRef(Project.NameKey project, String refName)
throws GlobalRefDbLockException {
String refPath = pathFor(project, refName);
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 b750c31..38b6dc8 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
@@ -18,15 +18,9 @@
import static com.google.common.truth.Truth8.assertThat;
import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.Configuration.DEFAULT_LOCKS_TABLE_NAME;
import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.Configuration.DEFAULT_REFS_DB_TABLE_NAME;
-import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.DynamoDBRefDatabase.REF_DB_PRIMARY_KEY;
-import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.DynamoDBRefDatabase.REF_DB_VALUE_KEY;
-import static com.googlesource.gerrit.plugins.validation.dfsrefdb.dynamodb.DynamoDBRefDatabase.pathFor;
import static org.testcontainers.containers.localstack.LocalStackContainer.Service.DYNAMODB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
-import com.amazonaws.services.dynamodbv2.model.AttributeValue;
-import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
-import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.WaitUtil;
@@ -167,6 +161,39 @@
}
@Test
+ public void putShouldBeSuccessfulWhenNoPreviousValueForRefExists() {
+ String refName = "refs/changes/01/01/meta";
+ String newRefValue = "533d3ccf8a650fb26380faa732921a2c74924d5c";
+
+ dynamoDBRefDatabase().put(project, refName, newRefValue);
+ Optional<String> result = dynamoDBRefDatabase().get(project, refName, String.class);
+ assertThat(result).hasValue(newRefValue);
+ }
+
+ @Test
+ public void putShouldSuccessfullyUpdateRemovedRef() {
+ String refName = "refs/changes/01/01/meta";
+ String newRefValue = null;
+
+ dynamoDBRefDatabase().put(project, refName, newRefValue);
+ Optional<String> result = dynamoDBRefDatabase().get(project, refName, String.class);
+ assertThat(result).hasValue(ObjectId.zeroId().getName());
+ }
+
+ @Test
+ public void putShouldBeSuccessfulWhenUpdatingRef() {
+ String refName = "refs/changes/01/01/meta";
+ String oldValue = "123";
+ String newValue = "345";
+ dynamoDBRefDatabase().put(project, refName, oldValue);
+
+ dynamoDBRefDatabase().put(project, refName, newValue);
+
+ Optional<String> result = dynamoDBRefDatabase().get(project, refName, String.class);
+ assertThat(result).hasValue(newValue);
+ }
+
+ @Test
public void compareAndPutShouldSuccessfullyUpdateRemovedRef() throws Exception {
String refName = "refs/changes/01/01/meta";
String currentRefValue = "533d3ccf8a650fb26380faa732921a2c74924d5c";
@@ -223,16 +250,7 @@
}
private void createRefInDynamoDB(Project.NameKey project, String refPath, String refValue) {
- dynamoDBClient()
- .putItem(
- new PutItemRequest()
- .withTableName(DEFAULT_REFS_DB_TABLE_NAME)
- .withItem(
- ImmutableMap.of(
- REF_DB_PRIMARY_KEY,
- new AttributeValue(pathFor(project, refPath)),
- REF_DB_VALUE_KEY,
- new AttributeValue(refValue))));
+ dynamoDBRefDatabase().put(project, refPath, refValue);
}
private Ref refOf(String refName, @Nullable String objectIdSha1) {