Inject ProjectVersionRefUpdate as Provider<>

The ProjectVersionRefUpdate relies on the injection of
the GerritInstanceId which could be delayed in the bootstrap
of Gerrit injectors chain at startup.

Starting from v3.5, the GerritInstanceId, an optional injection,
could still be null when the ReplicationStatus instance is created
causing a Guice instantiation failure.

Using a Provider<> resolves the issue and allows the resolution
of the GerritInstanceId at runtime when all the Guice modules
are instantiated.

This change is applied in stable-3.3 for minimizing the conflicts
of the merges up to master, as it is compatible with all branches
even if not necessarily needed on stable-3.{3,4}.

Change-Id: I638988205a004733e6531e6ac4126e2ba652ac06
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/ReplicationStatus.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/ReplicationStatus.java
index c024e67..c45dfa7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/ReplicationStatus.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/ReplicationStatus.java
@@ -25,6 +25,7 @@
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.inject.Inject;
 import com.google.inject.Module;
+import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.google.inject.name.Named;
 import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
@@ -59,14 +60,14 @@
 
   private final Map<String, Long> localVersionPerProject = new HashMap<>();
   private final Cache<String, Long> cache;
-  private final ProjectVersionRefUpdate projectVersionRefUpdate;
+  private final Provider<ProjectVersionRefUpdate> projectVersionRefUpdate;
   private final ProjectVersionLogger verLogger;
   private final ProjectCache projectCache;
 
   @Inject
   public ReplicationStatus(
       @Named(REPLICATION_STATUS_CACHE) Cache<String, Long> cache,
-      ProjectVersionRefUpdate projectVersionRefUpdate,
+      Provider<ProjectVersionRefUpdate> projectVersionRefUpdate,
       ProjectVersionLogger verLogger,
       ProjectCache projectCache) {
     this.cache = cache;
@@ -97,8 +98,9 @@
 
   public void updateReplicationLag(Project.NameKey projectName) {
     Optional<Long> remoteVersion =
-        projectVersionRefUpdate.getProjectRemoteVersion(projectName.get());
-    Optional<Long> localVersion = projectVersionRefUpdate.getProjectLocalVersion(projectName.get());
+        projectVersionRefUpdate.get().getProjectRemoteVersion(projectName.get());
+    Optional<Long> localVersion =
+        projectVersionRefUpdate.get().getProjectLocalVersion(projectName.get());
     if (remoteVersion.isPresent() && localVersion.isPresent()) {
       long lag = remoteVersion.get() - localVersion.get();
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/ReplicationStatusTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/ReplicationStatusTest.java
index beb93dd..dc1a564 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/ReplicationStatusTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/consumer/ReplicationStatusTest.java
@@ -15,6 +15,7 @@
 package com.googlesource.gerrit.plugins.multisite.consumer;
 
 import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.when;
 
 import com.google.common.cache.Cache;
@@ -22,6 +23,7 @@
 import com.google.common.collect.ImmutableSortedSet;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.server.project.ProjectCache;
+import com.google.inject.Provider;
 import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
 import com.googlesource.gerrit.plugins.multisite.validation.ProjectVersionRefUpdate;
 import org.junit.Before;
@@ -35,6 +37,7 @@
 
   @Mock private ProjectVersionLogger verLogger;
   @Mock private ProjectCache projectCache;
+  @Mock private Provider<ProjectVersionRefUpdate> projectVersionRefUpdateProvider;
   @Mock private ProjectVersionRefUpdate projectVersionRefUpdate;
   private ReplicationStatus objectUnderTest;
   private Cache<String, Long> replicationStatusCache;
@@ -47,7 +50,8 @@
     replicationStatusCache = CacheBuilder.newBuilder().build();
     objectUnderTest =
         new ReplicationStatus(
-            replicationStatusCache, projectVersionRefUpdate, verLogger, projectCache);
+            replicationStatusCache, projectVersionRefUpdateProvider, verLogger, projectCache);
+    lenient().when(projectVersionRefUpdateProvider.get()).thenReturn(projectVersionRefUpdate);
   }
 
   @Test
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 f648f6b..6aa2ce6 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
@@ -27,6 +27,7 @@
 import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
 import com.google.gerrit.server.project.ProjectCache;
+import com.google.inject.Provider;
 import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
 import com.googlesource.gerrit.plugins.multisite.validation.ProjectVersionRefUpdate;
 import java.util.Optional;
@@ -48,6 +49,7 @@
   @Mock private MetricMaker metricMaker;
   @Mock private ProjectVersionLogger verLogger;
   @Mock private ProjectCache projectCache;
+  @Mock private Provider<ProjectVersionRefUpdate> projectVersionRefUpdateProvider;
   @Mock private ProjectVersionRefUpdate projectVersionRefUpdate;
   private SubscriberMetrics metrics;
   private EventMessage.Header msgHeader;
@@ -60,9 +62,10 @@
             metricMaker,
             new ReplicationStatus(
                 CacheBuilder.newBuilder().build(),
-                projectVersionRefUpdate,
+                projectVersionRefUpdateProvider,
                 verLogger,
                 projectCache));
+    when(projectVersionRefUpdateProvider.get()).thenReturn(projectVersionRefUpdate);
   }
 
   @Test