Fix NPE when migrating from v3.1.x to v3.2.0
The migration process goes through the init command
that does not load all plugins needed by multi-site to
function properly.
Use a Noop implementation for the global-refdb implementation
when there are no plugins implementation loaded. This avoids
the NPE during the init step and allows the upgrade to proceed.
Bug: Issue 12821
Change-Id: If439d2e222bcc9ef8e629b084d4dcd4b4d501d0e
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
index b56f2ea..ddf9d84 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
@@ -21,11 +21,13 @@
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.NoopSharedRefDatabase;
import java.util.Optional;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
public class SharedRefDatabaseWrapper implements GlobalRefDatabase {
+ private static final GlobalRefDatabase NOOP_REFDB = new NoopSharedRefDatabase();
@Inject(optional = true)
private DynamicItem<GlobalRefDatabase> sharedRefDbDynamicItem;
@@ -95,6 +97,6 @@
}
private GlobalRefDatabase sharedRefDb() {
- return sharedRefDbDynamicItem.get();
+ return Optional.ofNullable(sharedRefDbDynamicItem).map(di -> di.get()).orElse(NOOP_REFDB);
}
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
index eefb685..de93545 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
@@ -23,6 +23,7 @@
import com.google.gerrit.entities.Project;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
+import com.googlesource.gerrit.plugins.multisite.SharedRefLogger;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedDbSplitBrainException;
@@ -44,6 +45,8 @@
@Mock SharedRefDatabaseWrapper sharedRefDb;
+ @Mock SharedRefLogger sharedRefLogger;
+
@Mock RefDatabase localRefDb;
@Mock ValidationMetrics validationMetrics;
@@ -71,14 +74,17 @@
doReturn(refName).when(refUpdate).getName();
lenient().doReturn(oldUpdateRef.getObjectId()).when(refUpdate).getOldObjectId();
- refUpdateValidator =
- new RefUpdateValidator(
- sharedRefDb,
- validationMetrics,
- defaultRefEnforcement,
- new DummyLockWrapper(),
- A_TEST_PROJECT_NAME,
- localRefDb);
+ refUpdateValidator = newRefUpdateValidator(sharedRefDb);
+ }
+
+ @Test
+ public void validationShouldSucceedWhenSharedRefDbIsNoop() throws Exception {
+ SharedRefDatabaseWrapper noopSharedRefDbWrapper = new SharedRefDatabaseWrapper(sharedRefLogger);
+
+ Result result =
+ newRefUpdateValidator(noopSharedRefDbWrapper)
+ .executeRefUpdate(refUpdate, () -> RefUpdate.Result.NEW);
+ assertThat(result).isEqualTo(RefUpdate.Result.NEW);
}
@Test
@@ -186,4 +192,14 @@
.compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
assertThat(result).isEqualTo(RefUpdate.Result.LOCK_FAILURE);
}
+
+ private RefUpdateValidator newRefUpdateValidator(SharedRefDatabaseWrapper refDbWrapper) {
+ return new RefUpdateValidator(
+ refDbWrapper,
+ validationMetrics,
+ defaultRefEnforcement,
+ new DummyLockWrapper(),
+ A_TEST_PROJECT_NAME,
+ localRefDb);
+ }
}