Merge branch 'stable-3.0' into stable-3.1
* stable-3.0:
Fix NPE when the replicated refs is not found locally
Change-Id: I18c813f283517f520ed26a59ef3c3ccd6dceb88c
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
index c8ddc87..a0972c6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
@@ -32,7 +32,7 @@
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
-import com.googlesource.gerrit.plugins.replication.RefReplicatedEvent;
+import com.googlesource.gerrit.plugins.replication.RefReplicationDoneEvent;
import java.io.IOException;
import java.util.Optional;
import java.util.Set;
@@ -46,7 +46,6 @@
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.transport.RemoteRefUpdate;
@Singleton
public class ProjectVersionRefUpdate implements EventListener {
@@ -76,27 +75,21 @@
updateProducerProjectVersionUpdate((RefUpdatedEvent) event);
}
- // Consumers of the Event use RefReplicatedEvent to trigger the version update
- if (Context.isForwardedEvent() && event instanceof RefReplicatedEvent) {
- updateConsumerProjectVersion((RefReplicatedEvent) event);
+ // Consumers of the Event use RefReplicationDoneEvent to trigger the version update
+ if (Context.isForwardedEvent() && event instanceof RefReplicationDoneEvent) {
+ updateConsumerProjectVersion((RefReplicationDoneEvent) event);
}
}
- private void updateConsumerProjectVersion(RefReplicatedEvent refReplicatedEvent) {
- Project.NameKey projectNameKey = refReplicatedEvent.getProjectNameKey();
- if (!refReplicatedEvent.refStatus.equals(RemoteRefUpdate.Status.OK)) {
- logger.atFine().log(
- String.format(
- "Skipping version update for %s. RefReplicatedEvent failed with %s",
- projectNameKey.get(), refReplicatedEvent.refStatus));
- return;
- }
- if (refReplicatedEvent.getRefName().startsWith(SEQUENCE_REF_PREFIX)) {
+ private void updateConsumerProjectVersion(RefReplicationDoneEvent refReplicationDoneEvent) {
+ Project.NameKey projectNameKey = refReplicationDoneEvent.getProjectNameKey();
+
+ if (refReplicationDoneEvent.getRefName().startsWith(SEQUENCE_REF_PREFIX)) {
logger.atFine().log("Found Sequence ref, skipping update for " + projectNameKey.get());
return;
}
try {
- updateLocalProjectVersion(projectNameKey, refReplicatedEvent.getRefName());
+ updateLocalProjectVersion(projectNameKey, refReplicationDoneEvent.getRefName());
} catch (LocalProjectVersionUpdateException e) {
logger.atSevere().withCause(e).log(
"Issue encountered when updating version for project " + projectNameKey);
@@ -112,10 +105,17 @@
try {
Project.NameKey projectNameKey = refUpdatedEvent.getProjectNameKey();
Ref currentProjectVersionRef = getLocalProjectVersionRef(refUpdatedEvent.getProjectNameKey());
- ObjectId newProjectVersionObjectId =
+ Optional<ObjectId> newProjectVersionObjectId =
updateLocalProjectVersion(projectNameKey, refUpdatedEvent.getRefName());
- updateSharedProjectVersion(
- projectNameKey, currentProjectVersionRef, newProjectVersionObjectId);
+
+ if (newProjectVersionObjectId.isPresent()) {
+ updateSharedProjectVersion(
+ projectNameKey, currentProjectVersionRef, newProjectVersionObjectId.get());
+ } else {
+ logger.atWarning().log(
+ "Ref %s not found on projet %s: skipping project version update",
+ refUpdatedEvent.getRefName(), projectNameKey);
+ }
} catch (LocalProjectVersionUpdateException | SharedProjectVersionUpdateException e) {
logger.atSevere().withCause(e).log(
"Issue encountered when updating version for project "
@@ -151,16 +151,20 @@
}
}
- private Long getLastRefUpdatedTimestamp(Project.NameKey projectNameKey, String refName)
+ private Optional<Long> getLastRefUpdatedTimestamp(Project.NameKey projectNameKey, String refName)
throws LocalProjectVersionUpdateException {
logger.atFine().log(
String.format(
"Getting last ref updated time for project %s, ref %s", projectNameKey.get(), refName));
try (Repository repository = gitRepositoryManager.openRepository(projectNameKey)) {
Ref ref = repository.findRef(refName);
+ if (ref == null) {
+ logger.atWarning().log("Unable to find ref " + refName + " in project " + projectNameKey);
+ return Optional.empty();
+ }
try (RevWalk walk = new RevWalk(repository)) {
RevCommit commit = walk.parseCommit(ref.getObjectId());
- return Integer.toUnsignedLong(commit.getCommitTime());
+ return Optional.of(Integer.toUnsignedLong(commit.getCommitTime()));
}
} catch (IOException ioe) {
String message =
@@ -252,22 +256,26 @@
}
}
- private ObjectId updateLocalProjectVersion(Project.NameKey projectNameKey, String refName)
- throws LocalProjectVersionUpdateException {
- Long lastRefUpdatedTimestamp = getLastRefUpdatedTimestamp(projectNameKey, refName);
+ private Optional<ObjectId> updateLocalProjectVersion(
+ Project.NameKey projectNameKey, String refName) throws LocalProjectVersionUpdateException {
+ Optional<Long> lastRefUpdatedTimestamp = getLastRefUpdatedTimestamp(projectNameKey, refName);
+ if (!lastRefUpdatedTimestamp.isPresent()) {
+ return Optional.empty();
+ }
+
logger.atFine().log("Updating local version for project " + projectNameKey.get());
try (Repository repository = gitRepositoryManager.openRepository(projectNameKey)) {
- RefUpdate refUpdate = getProjectVersionRefUpdate(repository, lastRefUpdatedTimestamp);
+ RefUpdate refUpdate = getProjectVersionRefUpdate(repository, lastRefUpdatedTimestamp.get());
RefUpdate.Result result = refUpdate.update();
if (!isSuccessful(result)) {
String message =
String.format(
"RefUpdate failed with result %s for: project=%s, version=%d",
- result.name(), projectNameKey.get(), lastRefUpdatedTimestamp);
+ result.name(), projectNameKey.get(), lastRefUpdatedTimestamp.get());
logger.atSevere().log(message);
throw new LocalProjectVersionUpdateException(message);
}
- return refUpdate.getNewObjectId();
+ return Optional.of(refUpdate.getNewObjectId());
} catch (IOException e) {
String message = "Cannot create versioning command for " + projectNameKey.get();
logger.atSevere().withCause(e).log(message);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
index 776fec8..63415e0 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
@@ -29,6 +29,7 @@
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
import com.googlesource.gerrit.plugins.replication.RefReplicatedEvent;
+import com.googlesource.gerrit.plugins.replication.RefReplicationDoneEvent;
import com.googlesource.gerrit.plugins.replication.ReplicationState;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@@ -126,15 +127,10 @@
}
@Test
- public void consumerShouldUpdateProjectVersionUponRefReplicatedEvent() throws IOException {
+ public void consumerShouldUpdateProjectVersionUponRefReplicationDoneEvent() throws IOException {
Context.setForwardedEvent(true);
- RefReplicatedEvent refReplicatedEvent =
- new RefReplicatedEvent(
- A_TEST_PROJECT_NAME,
- A_TEST_REF_NAME,
- "targetNode",
- ReplicationState.RefPushResult.SUCCEEDED,
- RemoteRefUpdate.Status.OK);
+ RefReplicationDoneEvent refReplicatedEvent =
+ new RefReplicationDoneEvent(A_TEST_PROJECT_NAME, A_TEST_REF_NAME, 1);
new ProjectVersionRefUpdate(repoManager, sharedRefDb).onEvent(refReplicatedEvent);
@@ -205,6 +201,7 @@
public void getLocalProjectVersionShouldReturnCorrectValue() throws IOException {
updateLocalVersion();
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
+ assertThat(ref).isNotNull();
Optional<Long> version =
new ProjectVersionRefUpdate(repoManager, sharedRefDb)
@@ -216,13 +213,8 @@
private void updateLocalVersion() {
Context.setForwardedEvent(true);
- RefReplicatedEvent refReplicatedEvent =
- new RefReplicatedEvent(
- A_TEST_PROJECT_NAME,
- A_TEST_REF_NAME,
- "targetNode",
- ReplicationState.RefPushResult.SUCCEEDED,
- RemoteRefUpdate.Status.OK);
+ RefReplicationDoneEvent refReplicatedEvent =
+ new RefReplicationDoneEvent(A_TEST_PROJECT_NAME, A_TEST_REF_NAME, 1);
new ProjectVersionRefUpdate(repoManager, sharedRefDb).onEvent(refReplicatedEvent);
}
}