Merge branch 'stable-3.12'

* stable-3.12:
  Do not fail reindexing changes when the patch-sets aren't replicated yet
  Set GERRIT_BRANCH to stable-3.12 for local E2E test environment
  Set GERRIT_BRANCH to stable-3.11 for local E2E test environment

Change-Id: I33231eceb492cd18b12b6b782b879673d77648d7
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
index 1be09aa..7d76807 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
@@ -22,6 +22,7 @@
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
 import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
 import com.google.common.collect.ImmutableList;
 import com.google.gerrit.server.config.ConfigUtil;
 import com.google.gerrit.server.config.SitePaths;
@@ -83,8 +84,8 @@
   private final Config multiSiteConfig;
   private final Supplier<Duration> replicationLagRefreshInterval;
   private final Supplier<Boolean> replicationLagEnabled;
-  private final Supplier<Boolean> pushReplicationFilterEnabled;
-  private final Supplier<Boolean> pullReplicationFilterEnabled;
+  private Supplier<Boolean> pushReplicationFilterEnabled;
+  private Supplier<Boolean> pullReplicationFilterEnabled;
   private final Supplier<Long> localRefLockTimeoutMsec;
 
   @Inject
@@ -122,10 +123,10 @@
     replicationLagEnabled =
         memoize(
             () ->
-                lazyMultiSiteCfg
-                    .get()
-                    .getBoolean(REF_DATABASE, null, REPLICATION_LAG_ENABLED, true));
-
+                !pullReplicationFilterEnabled.get()
+                    && lazyMultiSiteCfg
+                        .get()
+                        .getBoolean(REF_DATABASE, null, REPLICATION_LAG_ENABLED, true));
     pushReplicationFilterEnabled =
         memoize(
             () ->
@@ -194,10 +195,18 @@
     return pushReplicationFilterEnabled.get();
   }
 
-  public boolean pullRepllicationFilterEnabled() {
+  public void disablePushReplicationFilter() {
+    pushReplicationFilterEnabled = Suppliers.ofInstance(false);
+  }
+
+  public boolean pullReplicationFilterEnabled() {
     return pullReplicationFilterEnabled.get();
   }
 
+  public void disablePullReplicationFilter() {
+    pullReplicationFilterEnabled = Suppliers.ofInstance(false);
+  }
+
   public long localRefLockTimeoutMsec() {
     return localRefLockTimeoutMsec.get();
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
index 3ced8c6..c77b057 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
@@ -86,16 +86,20 @@
     ImmutableList.Builder<AbstractModule> filterModulesBuilder = ImmutableList.builder();
 
     if (config.pushReplicationFilterEnabled()) {
-      bindReplicationFilterClass(PUSH_REPLICATION_FILTER_MODULE, filterModulesBuilder);
+      if (!bindReplicationFilterClass(PUSH_REPLICATION_FILTER_MODULE, filterModulesBuilder)) {
+        config.disablePushReplicationFilter();
+      }
     }
-    if (config.pullRepllicationFilterEnabled()) {
-      bindReplicationFilterClass(PULL_REPLICATION_FILTER_MODULE, filterModulesBuilder);
+    if (config.pullReplicationFilterEnabled()) {
+      if (!bindReplicationFilterClass(PULL_REPLICATION_FILTER_MODULE, filterModulesBuilder)) {
+        config.disablePullReplicationFilter();
+      }
     }
 
     return filterModulesBuilder.build();
   }
 
-  private void bindReplicationFilterClass(
+  private boolean bindReplicationFilterClass(
       String filterClassName, ImmutableList.Builder<AbstractModule> filterModulesBuilder) {
     try {
       @SuppressWarnings("unchecked")
@@ -106,9 +110,11 @@
       parentInjector.createChildInjector(filterModule);
 
       filterModulesBuilder.add(filterModule);
+      return true;
     } catch (NoClassDefFoundError | ClassNotFoundException e) {
       log.atWarning().withCause(e).log(
           "Not loading %s because of missing the associated replication plugin", filterClassName);
+      return false;
     } catch (Exception e) {
       throw new ProvisionException(
           "Unable to instantiate replication filter " + filterClassName, e);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
index 958f265..963c7a8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
@@ -26,9 +26,9 @@
 import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbRefUpdate;
 import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbRepository;
 import com.gerritforge.gerrit.globalrefdb.validation.SharedRefLogger;
-import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.CustomSharedRefEnforcementByProject;
-import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.SharedRefEnforcement;
+import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.LegacyCustomSharedRefEnforcementByProject;
+import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.LegacyDefaultSharedRefEnforcement;
+import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.LegacySharedRefEnforcement;
 import com.google.common.collect.ImmutableSet;
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.gerrit.extensions.registration.DynamicSet;
@@ -70,10 +70,12 @@
     install(new RepositoryManagerModule(repoConfig));
 
     if (cfg.getSharedRefDbConfiguration().getSharedRefDb().getEnforcementRules().isEmpty()) {
-      bind(SharedRefEnforcement.class).to(DefaultSharedRefEnforcement.class).in(Scopes.SINGLETON);
+      bind(LegacySharedRefEnforcement.class)
+          .to(LegacyDefaultSharedRefEnforcement.class)
+          .in(Scopes.SINGLETON);
     } else {
-      bind(SharedRefEnforcement.class)
-          .to(CustomSharedRefEnforcementByProject.class)
+      bind(LegacySharedRefEnforcement.class)
+          .to(LegacyCustomSharedRefEnforcementByProject.class)
           .in(Scopes.SINGLETON);
     }
 
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index ed72405..75fc55b 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -95,12 +95,12 @@
 :   Enable the use of a shared ref-database
     Defaults: true
 
-```ref-database.pushReplicationFilterClassEnabled```
+```ref-database.pushReplicationFilterEnabled```
 :   Enable the filtering of push replication events checking their
     up-to-date status with the global-refdb.
     Defaults: true
 
-```ref-database.pullReplicationFilterClassEnabled```
+```ref-database.pullReplicationFilterEnabled```
 :   Enable the filtering of pull replication events checking their
     up-to-date status with the global-refdb.
     Defaults: true
@@ -115,7 +115,8 @@
     updating the `refs/multi-site/version/*` to the _epoch_ timestamp in
     milliseconds. Please note that the `replication-lag` REST-API is also
     disabled if this setting is false.
-    Defaults: true
+    Defaults: true unless `pullReplicationFilterEnabled` is enabled and the pull-replication plugin
+    is available, in which case replicationLag is always disabled.
 
 ```ref-database.replicationLagRefreshInterval```
 :   Enable the auto-refresh of the metrics to trace the auto-replication
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberMetricsTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberMetricsTest.java
index 6a03a6c..191d7fd 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberMetricsTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberMetricsTest.java
@@ -57,6 +57,8 @@
 
   @Before
   public void setup() throws Exception {
+    Config multiSiteConfig = new Config();
+    multiSiteConfig.setBoolean("ref-database", null, "pullReplicationFilterEnabled", false);
     replicationStatus =
         new ReplicationStatus(
             CacheBuilder.newBuilder().build(),
@@ -64,7 +66,8 @@
             verLogger,
             projectCache,
             Executors.newScheduledThreadPool(1),
-            new com.googlesource.gerrit.plugins.multisite.Configuration(new Config(), new Config()),
+            new com.googlesource.gerrit.plugins.multisite.Configuration(
+                multiSiteConfig, new Config()),
             new DisabledMetricMaker());
     metrics = new SubscriberMetrics(metricMaker, replicationStatus);
   }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/http/ReplicationStatusServletIT.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/http/ReplicationStatusServletIT.java
index f940fc4..80c3d8a 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/http/ReplicationStatusServletIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/http/ReplicationStatusServletIT.java
@@ -17,6 +17,7 @@
 import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
 import static com.google.common.truth.Truth.assertThat;
 import static com.googlesource.gerrit.plugins.multisite.http.HttpModule.LAG_ENDPOINT_SEGMENT;
+import static org.junit.Assume.assumeTrue;
 
 import com.gerritforge.gerrit.globalrefdb.validation.Log4jSharedRefLogger;
 import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbConfiguration;
@@ -32,6 +33,7 @@
 import com.google.inject.Inject;
 import com.google.inject.Scopes;
 import com.google.inject.multibindings.OptionalBinder;
+import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.Log4jProjectVersionLogger;
 import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
 import com.googlesource.gerrit.plugins.multisite.cache.CacheModule;
@@ -57,6 +59,7 @@
   private static final String LAG_ENDPOINT =
       String.format("/plugins/multi-site/%s", LAG_ENDPOINT_SEGMENT);
   private ReplicationStatus replicationStatus;
+  private Configuration multiSiteConfig;
 
   public static class TestModule extends AbstractModule {
     @Inject WorkQueue workQueue;
@@ -83,11 +86,13 @@
   @Before
   public void setUp() throws IOException {
     replicationStatus = plugin.getSysInjector().getInstance(ReplicationStatus.class);
+    multiSiteConfig = plugin.getSysInjector().getInstance(Configuration.class);
   }
 
   @Test
   @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId")
   public void shouldSucceedForAdminUsers() throws Exception {
+    assumeReplicationLagEnabled();
     RestResponse result = adminRestSession.get(LAG_ENDPOINT);
 
     result.assertOK();
@@ -97,6 +102,7 @@
   @Test
   @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId")
   public void shouldFailWhenUserHasNoAdminServerCapability() throws Exception {
+    assumeReplicationLagEnabled();
     RestResponse result = userRestSession.get(LAG_ENDPOINT);
     result.assertForbidden();
     assertThat(result.getEntityContent()).contains("not permitted");
@@ -105,6 +111,7 @@
   @Test
   @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId")
   public void shouldReturnCurrentProjectLag() throws Exception {
+    assumeReplicationLagEnabled();
     replicationStatus.doUpdateLag(Project.nameKey("foo"), 123L);
 
     RestResponse result = adminRestSession.get(LAG_ENDPOINT);
@@ -116,6 +123,7 @@
   @Test
   @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId")
   public void shouldReturnProjectsOrderedDescendinglyByLag() throws Exception {
+    assumeReplicationLagEnabled();
     replicationStatus.doUpdateLag(Project.nameKey("bar"), 123L);
     replicationStatus.doUpdateLag(Project.nameKey("foo"), 3L);
     replicationStatus.doUpdateLag(Project.nameKey("baz"), 52300L);
@@ -129,6 +137,7 @@
   @Test
   @GerritConfig(name = "gerrit.instanceId", value = "testInstanceId")
   public void shouldHonourTheLimitParameter() throws Exception {
+    assumeReplicationLagEnabled();
     replicationStatus.doUpdateLag(Project.nameKey("bar"), 1L);
     replicationStatus.doUpdateLag(Project.nameKey("foo"), 2L);
     replicationStatus.doUpdateLag(Project.nameKey("baz"), 3L);
@@ -142,4 +151,10 @@
   private String contentWithoutMagicJson(RestResponse response) throws IOException {
     return response.getEntityContent().substring(RestApiServlet.JSON_MAGIC.length);
   }
+
+  private void assumeReplicationLagEnabled() {
+    assumeTrue(
+        "Replication status skipped as replication lag is disabled",
+        multiSiteConfig.replicationLagEnabled());
+  }
 }