Merge branch 'stable-3.4' into stable-3.5

* stable-3.4:
  Fix entrypoint.sh in example-setup with broker
  entrypoint.sh: Fix setting JAVA_OPTS variable
  Make the code build on Java 8
  Run apply-object before the ref-updated stream event
  Add extra logging when replication tasks are merged

Change-Id: I181e9ad8fab92a8086450c88101ca6112ea71aed
diff --git a/example-setup/broker/Dockerfile b/example-setup/broker/Dockerfile
index 1b3038c..8222679 100644
--- a/example-setup/broker/Dockerfile
+++ b/example-setup/broker/Dockerfile
@@ -9,7 +9,10 @@
 COPY --chown=gerrit:gerrit pull-replication.jar /var/gerrit/plugins/pull-replication.jar
 COPY --chown=gerrit:gerrit pull-replication.jar /var/gerrit/lib/pull-replication.jar
 
-COPY --chown=gerrit:gerrit events-kafka.jar /var/gerrit/plugins/events-kafka.jar
+# The message-broker notification needs to be the last in the notification chain
+# hence rename it with a 'z-' prefix because the Gerrit plugin loader starts the
+# plugins in filename alphabetical order.
+COPY --chown=gerrit:gerrit events-kafka.jar /var/gerrit/plugins/z-events-kafka.jar
 COPY --chown=gerrit:gerrit libevents-broker.jar /var/gerrit/lib/libevents-broker.jar
 
 COPY --chown=gerrit:gerrit entrypoint.sh /tmp/
diff --git a/example-setup/broker/configs/replication.config.template b/example-setup/broker/configs/replication.config.template
index d464586..e77edeb 100644
--- a/example-setup/broker/configs/replication.config.template
+++ b/example-setup/broker/configs/replication.config.template
@@ -12,6 +12,7 @@
     maxApiPayloadSize = 40000
 [remote "$REMOTE"]
     url = http://$REMOTE_URL:8080/#{name}#.git
+    apiUrl = http://$REMOTE_URL:8080/
     fetch = +refs/*:refs/*
     mirror = true
     timeout = 60 # In seconds
diff --git a/example-setup/broker/entrypoint.sh b/example-setup/broker/entrypoint.sh
index 1d958e4..33df1d4 100755
--- a/example-setup/broker/entrypoint.sh
+++ b/example-setup/broker/entrypoint.sh
@@ -13,7 +13,7 @@
   cat /var/gerrit/etc/gerrit.config.template | envsubst > /var/gerrit/etc/gerrit.config
 }
 
-ARG JAVA_OPTS='--add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED'
+JAVA_OPTS='--add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED'
 
 echo "Init phase ..."
 java $JAVA_OPTS -jar /var/gerrit/bin/gerrit.war init --batch --install-all-plugins -d /var/gerrit
@@ -25,4 +25,4 @@
 java $JAVA_OPTS -jar /var/gerrit/bin/gerrit.war reindex -d /var/gerrit
 
 echo "Running Gerrit ..."
-exec /var/gerrit/bin/gerrit.sh run
\ No newline at end of file
+exec /var/gerrit/bin/gerrit.sh run
diff --git a/example-setup/http/entrypoint.sh b/example-setup/http/entrypoint.sh
index 1d958e4..33df1d4 100755
--- a/example-setup/http/entrypoint.sh
+++ b/example-setup/http/entrypoint.sh
@@ -13,7 +13,7 @@
   cat /var/gerrit/etc/gerrit.config.template | envsubst > /var/gerrit/etc/gerrit.config
 }
 
-ARG JAVA_OPTS='--add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED'
+JAVA_OPTS='--add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED'
 
 echo "Init phase ..."
 java $JAVA_OPTS -jar /var/gerrit/bin/gerrit.war init --batch --install-all-plugins -d /var/gerrit
@@ -25,4 +25,4 @@
 java $JAVA_OPTS -jar /var/gerrit/bin/gerrit.war reindex -d /var/gerrit
 
 echo "Running Gerrit ..."
-exec /var/gerrit/bin/gerrit.sh run
\ No newline at end of file
+exec /var/gerrit/bin/gerrit.sh run
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationModule.java
index cd19be4..ed3aecb 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationModule.java
@@ -19,12 +19,12 @@
 import com.google.common.eventbus.EventBus;
 import com.google.gerrit.extensions.annotations.Exports;
 import com.google.gerrit.extensions.config.CapabilityDefinition;
-import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import com.google.gerrit.extensions.events.HeadUpdatedListener;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.extensions.events.ProjectDeletedListener;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.server.config.SitePaths;
+import com.google.gerrit.server.events.EventListener;
 import com.google.gerrit.server.events.EventTypes;
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
@@ -123,7 +123,7 @@
         .annotatedWith(UniqueAnnotations.create())
         .to(ReplicationQueue.class);
 
-    DynamicSet.bind(binder(), GitReferenceUpdatedListener.class).to(ReplicationQueue.class);
+    DynamicSet.bind(binder(), EventListener.class).to(ReplicationQueue.class);
 
     bind(ConfigParser.class).to(SourceConfigParser.class).in(Scopes.SINGLETON);
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueue.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueue.java
index 380ac8e..b90969b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueue.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueue.java
@@ -20,13 +20,14 @@
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.entities.Project.NameKey;
 import com.google.gerrit.entities.RefNames;
-import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import com.google.gerrit.extensions.events.HeadUpdatedListener;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.extensions.events.ProjectDeletedListener;
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.metrics.Timer1.Context;
 import com.google.gerrit.server.events.EventDispatcher;
+import com.google.gerrit.server.events.EventListener;
+import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -64,8 +65,8 @@
 
 public class ReplicationQueue
     implements ObservableQueue,
+        EventListener,
         LifecycleListener,
-        GitReferenceUpdatedListener,
         ProjectDeletedListener,
         HeadUpdatedListener {
 
@@ -73,6 +74,8 @@
   static final Logger repLog = LoggerFactory.getLogger(PULL_REPLICATION_LOG_NAME);
 
   private static final Integer DEFAULT_FETCH_CALLS_TIMEOUT = 0;
+  private static final String REF_UDPATED_EVENT_TYPE = new RefUpdatedEvent().type;
+  private static final String ZEROS_OBJECTID = ObjectId.zeroId().getName();
   private final ReplicationStateListener stateLog;
 
   private final WorkQueue workQueue;
@@ -147,20 +150,24 @@
   }
 
   @Override
-  public void onGitReferenceUpdated(GitReferenceUpdatedListener.Event event) {
-    if (isRefToBeReplicated(event.getRefName())) {
-      repLog.info(
-          "Ref event received: {} on project {}:{} - {} => {}",
-          refUpdateType(event),
-          event.getProjectName(),
-          event.getRefName(),
-          event.getOldObjectId(),
-          event.getNewObjectId());
-      fire(
-          event.getProjectName(),
-          ObjectId.fromString(event.getNewObjectId()),
-          event.getRefName(),
-          event.isDelete());
+  public void onEvent(com.google.gerrit.server.events.Event e) {
+    if (e.type.equals(REF_UDPATED_EVENT_TYPE)) {
+      RefUpdatedEvent event = (RefUpdatedEvent) e;
+
+      if (isRefToBeReplicated(event.getRefName())) {
+        repLog.info(
+            "Ref event received: {} on project {}:{} - {} => {}",
+            refUpdateType(event),
+            event.refUpdate.get().project,
+            event.getRefName(),
+            event.refUpdate.get().oldRev,
+            event.refUpdate.get().newRev);
+        fire(
+            event.refUpdate.get().project,
+            ObjectId.fromString(event.refUpdate.get().newRev),
+            event.getRefName(),
+            ZEROS_OBJECTID.equals(event.refUpdate.get().newRev));
+      }
     }
   }
 
@@ -174,14 +181,13 @@
                 source.getApis().forEach(apiUrl -> source.scheduleDeleteProject(apiUrl, project)));
   }
 
-  private static String refUpdateType(GitReferenceUpdatedListener.Event event) {
-    String forcedPrefix = event.isNonFastForward() ? "FORCED " : " ";
-    if (event.isCreate()) {
-      return forcedPrefix + "CREATE";
-    } else if (event.isDelete()) {
-      return forcedPrefix + "DELETE";
+  private static String refUpdateType(RefUpdatedEvent event) {
+    if (ZEROS_OBJECTID.equals(event.refUpdate.get().oldRev)) {
+      return "CREATE";
+    } else if (ZEROS_OBJECTID.equals(event.refUpdate.get().newRev)) {
+      return "DELETE";
     } else {
-      return forcedPrefix + "UPDATE";
+      return "UPDATE";
     }
   }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java
index ff1664e..0ebbf91 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java
@@ -523,6 +523,12 @@
           pendingFetchOp.addStates(fetchOp.getStates());
           fetchOp.removeStates();
 
+          stateLog.warn(
+              String.format(
+                  "[%s] Merging all refs to fetch from [%s] to the already retrying task [%s] for keeping its position into the replication queue",
+                  fetchOp.getTaskIdHex(), fetchOp.getURI(), pendingFetchOp.getTaskIdHex()),
+              fetchOp.getStatesAsArray());
+
         } else {
           // The one pending is one that is NOT retrying, it was just
           // scheduled believing no problem would happen. The one pending
@@ -541,6 +547,12 @@
           fetchOp.addRefs(pendingFetchOp.getRefs());
           fetchOp.addStates(pendingFetchOp.getStates());
           pendingFetchOp.removeStates();
+
+          stateLog.warn(
+              String.format(
+                  "[%s] Merging the pending fetch from [%s] with task [%s] and rescheduling",
+                  pendingFetchOp.getTaskIdHex(), pendingFetchOp.getURI(), fetchOp.getTaskIdHex()),
+              pendingFetchOp.getStatesAsArray());
         }
       }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/auth/PullReplicationGroupBackend.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/auth/PullReplicationGroupBackend.java
index ffd3c1f..c61d4d9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/auth/PullReplicationGroupBackend.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/auth/PullReplicationGroupBackend.java
@@ -28,7 +28,6 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 
 /** Backend to expose the pull-replication internal user group membership. */
 @Singleton
@@ -84,7 +83,7 @@
   @Override
   public Collection<GroupReference> suggest(String name, ProjectState project) {
     return NAME_PREFIX.contains(name.toLowerCase())
-        ? List.of(GroupReference.create(INTERNAL_GROUP_UUID, INTERNAL_GROUP_NAME))
+        ? Arrays.asList(GroupReference.create(INTERNAL_GROUP_UUID, INTERNAL_GROUP_NAME))
         : Collections.emptyList();
   }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/fetch/InexistentRefTransportException.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/fetch/InexistentRefTransportException.java
index 7c2e637..f97f648 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/fetch/InexistentRefTransportException.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/fetch/InexistentRefTransportException.java
@@ -40,8 +40,11 @@
   }
 
   public static Optional<TransportException> getOptionalPermanentFailure(TransportException e) {
-    return wrapException(JGIT_INEXISTENT_REF_PATTERN, e)
-        .or(() -> wrapException(CGIT_INEXISTENT_REF_PATTERN, e));
+    Optional<TransportException> jgitEx = wrapException(JGIT_INEXISTENT_REF_PATTERN, e);
+    if (jgitEx.isPresent()) {
+      return jgitEx;
+    }
+    return wrapException(CGIT_INEXISTENT_REF_PATTERN, e);
   }
 
   private static Optional<TransportException> wrapException(
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/FakeGitReferenceUpdatedEvent.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/FakeGitReferenceUpdatedEvent.java
index 43331dc..47c00c7 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/FakeGitReferenceUpdatedEvent.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/FakeGitReferenceUpdatedEvent.java
@@ -14,81 +14,19 @@
 
 package com.googlesource.gerrit.plugins.replication.pull;
 
+import com.google.common.base.Suppliers;
 import com.google.gerrit.entities.Project;
-import com.google.gerrit.extensions.api.changes.NotifyHandling;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
-import org.eclipse.jgit.transport.ReceiveCommand;
+import com.google.gerrit.server.data.RefUpdateAttribute;
+import com.google.gerrit.server.events.RefUpdatedEvent;
 
-public class FakeGitReferenceUpdatedEvent implements GitReferenceUpdatedListener.Event {
-  private final String projectName;
-  private final String ref;
-  private final String oldObjectId;
-  private final String newObjectId;
-  private final ReceiveCommand.Type type;
-
+public class FakeGitReferenceUpdatedEvent extends RefUpdatedEvent {
   FakeGitReferenceUpdatedEvent(
-      Project.NameKey project,
-      String ref,
-      String oldObjectId,
-      String newObjectId,
-      ReceiveCommand.Type type) {
-    this.projectName = project.get();
-    this.ref = ref;
-    this.oldObjectId = oldObjectId;
-    this.newObjectId = newObjectId;
-    this.type = type;
-  }
-
-  @Override
-  public String getProjectName() {
-    return projectName;
-  }
-
-  @Override
-  public String getRefName() {
-    return ref;
-  }
-
-  @Override
-  public String getOldObjectId() {
-    return oldObjectId;
-  }
-
-  @Override
-  public String getNewObjectId() {
-    return newObjectId;
-  }
-
-  @Override
-  public boolean isCreate() {
-    return type == ReceiveCommand.Type.CREATE;
-  }
-
-  @Override
-  public boolean isDelete() {
-    return type == ReceiveCommand.Type.DELETE;
-  }
-
-  @Override
-  public boolean isNonFastForward() {
-    return type == ReceiveCommand.Type.UPDATE_NONFASTFORWARD;
-  }
-
-  @Override
-  public AccountInfo getUpdater() {
-    return null;
-  }
-
-  @Override
-  public String toString() {
-    return String.format(
-        "%s[%s,%s: %s -> %s]",
-        getClass().getSimpleName(), projectName, ref, oldObjectId, newObjectId);
-  }
-
-  @Override
-  public NotifyHandling getNotify() {
-    return NotifyHandling.ALL;
+      Project.NameKey project, String ref, String oldObjectId, String newObjectId) {
+    RefUpdateAttribute upd = new RefUpdateAttribute();
+    upd.newRev = newObjectId;
+    upd.oldRev = oldObjectId;
+    upd.project = project.get();
+    upd.refName = ref;
+    this.refUpdate = Suppliers.ofInstance(upd);
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationFanoutConfigIT.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationFanoutConfigIT.java
index ee5876f..1aaf434 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationFanoutConfigIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationFanoutConfigIT.java
@@ -27,7 +27,6 @@
 import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.api.projects.BranchInput;
-import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.replication.AutoReloadConfigDecorator;
@@ -44,7 +43,6 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.storage.file.FileBasedConfig;
-import org.eclipse.jgit.transport.ReceiveCommand;
 import org.eclipse.jgit.util.FS;
 import org.junit.Test;
 
@@ -105,14 +103,10 @@
     String sourceRef = pushResult.getPatchSet().refName();
 
     ReplicationQueue pullReplicationQueue = getInstance(ReplicationQueue.class);
-    GitReferenceUpdatedListener.Event event =
+    FakeGitReferenceUpdatedEvent event =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            sourceRef,
-            ObjectId.zeroId().getName(),
-            sourceCommit.getId().getName(),
-            ReceiveCommand.Type.CREATE);
-    pullReplicationQueue.onGitReferenceUpdated(event);
+            project, sourceRef, ObjectId.zeroId().getName(), sourceCommit.getId().getName());
+    pullReplicationQueue.onEvent(event);
 
     try (Repository repo = repoManager.openRepository(project)) {
       waitUntil(() -> checkedGetRef(repo, sourceRef) != null);
@@ -141,14 +135,10 @@
     RevCommit sourceCommit = pushResult.getCommit();
     final String sourceRef = pushResult.getPatchSet().refName();
     ReplicationQueue pullReplicationQueue = getInstance(ReplicationQueue.class);
-    GitReferenceUpdatedListener.Event event =
+    FakeGitReferenceUpdatedEvent event =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            sourceRef,
-            ObjectId.zeroId().getName(),
-            sourceCommit.getId().getName(),
-            ReceiveCommand.Type.CREATE);
-    pullReplicationQueue.onGitReferenceUpdated(event);
+            project, sourceRef, ObjectId.zeroId().getName(), sourceCommit.getId().getName());
+    pullReplicationQueue.onEvent(event);
 
     try (Repository repo = repoManager.openRepository(project)) {
       waitUntil(() -> checkedGetRef(repo, sourceRef) != null);
@@ -174,14 +164,10 @@
 
     ReplicationQueue pullReplicationQueue =
         plugin.getSysInjector().getInstance(ReplicationQueue.class);
-    GitReferenceUpdatedListener.Event event =
+    FakeGitReferenceUpdatedEvent event =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            newBranch,
-            ObjectId.zeroId().getName(),
-            branchRevision,
-            ReceiveCommand.Type.CREATE);
-    pullReplicationQueue.onGitReferenceUpdated(event);
+            project, newBranch, ObjectId.zeroId().getName(), branchRevision);
+    pullReplicationQueue.onEvent(event);
 
     try (Repository repo = repoManager.openRepository(project);
         Repository sourceRepo = repoManager.openRepository(project)) {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationIT.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationIT.java
index f3c62c5..180094d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationIT.java
@@ -30,7 +30,6 @@
 import com.google.gerrit.entities.RefNames;
 import com.google.gerrit.extensions.api.changes.NotifyHandling;
 import com.google.gerrit.extensions.api.projects.BranchInput;
-import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import com.google.gerrit.extensions.events.HeadUpdatedListener;
 import com.google.gerrit.extensions.events.ProjectDeletedListener;
 import com.google.gerrit.extensions.restapi.RestApiException;
@@ -47,7 +46,6 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.transport.PushResult;
-import org.eclipse.jgit.transport.ReceiveCommand;
 import org.eclipse.jgit.transport.RemoteRefUpdate;
 import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
 import org.junit.Test;
@@ -91,14 +89,10 @@
     String sourceRef = pushResult.getPatchSet().refName();
 
     ReplicationQueue pullReplicationQueue = getInstance(ReplicationQueue.class);
-    GitReferenceUpdatedListener.Event event =
+    FakeGitReferenceUpdatedEvent event =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            sourceRef,
-            ObjectId.zeroId().getName(),
-            sourceCommit.getId().getName(),
-            ReceiveCommand.Type.CREATE);
-    pullReplicationQueue.onGitReferenceUpdated(event);
+            project, sourceRef, ObjectId.zeroId().getName(), sourceCommit.getId().getName());
+    pullReplicationQueue.onEvent(event);
 
     try (Repository repo = repoManager.openRepository(project)) {
       waitUntil(() -> checkedGetRef(repo, sourceRef) != null);
@@ -124,14 +118,10 @@
 
     ReplicationQueue pullReplicationQueue =
         plugin.getSysInjector().getInstance(ReplicationQueue.class);
-    GitReferenceUpdatedListener.Event event =
+    FakeGitReferenceUpdatedEvent event =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            newBranch,
-            ObjectId.zeroId().getName(),
-            branchRevision,
-            ReceiveCommand.Type.CREATE);
-    pullReplicationQueue.onGitReferenceUpdated(event);
+            project, newBranch, ObjectId.zeroId().getName(), branchRevision);
+    pullReplicationQueue.onEvent(event);
 
     try (Repository repo = repoManager.openRepository(project);
         Repository sourceRepo = repoManager.openRepository(project)) {
@@ -167,14 +157,10 @@
 
     ReplicationQueue pullReplicationQueue =
         plugin.getSysInjector().getInstance(ReplicationQueue.class);
-    GitReferenceUpdatedListener.Event event =
+    FakeGitReferenceUpdatedEvent event =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            newBranch,
-            ObjectId.zeroId().getName(),
-            branchRevision,
-            ReceiveCommand.Type.CREATE);
-    pullReplicationQueue.onGitReferenceUpdated(event);
+            project, newBranch, ObjectId.zeroId().getName(), branchRevision);
+    pullReplicationQueue.onEvent(event);
 
     try (Repository repo = repoManager.openRepository(project)) {
       waitUntil(() -> checkedGetRef(repo, newBranch) != null);
@@ -193,14 +179,10 @@
     assertThat(pushedRefs).hasSize(1);
     assertThat(pushedRefs.iterator().next().getStatus()).isEqualTo(Status.OK);
 
-    GitReferenceUpdatedListener.Event forcedPushEvent =
+    FakeGitReferenceUpdatedEvent forcedPushEvent =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            newBranch,
-            branchRevision,
-            amendedCommit.getId().getName(),
-            ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
-    pullReplicationQueue.onGitReferenceUpdated(forcedPushEvent);
+            project, newBranch, branchRevision, amendedCommit.getId().getName());
+    pullReplicationQueue.onEvent(forcedPushEvent);
 
     try (Repository repo = repoManager.openRepository(project);
         Repository sourceRepo = repoManager.openRepository(project)) {
@@ -232,14 +214,10 @@
     String sourceRef = pushResult.getPatchSet().refName();
 
     ReplicationQueue pullReplicationQueue = getInstance(ReplicationQueue.class);
-    GitReferenceUpdatedListener.Event event =
+    FakeGitReferenceUpdatedEvent event =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            sourceRef,
-            ObjectId.zeroId().getName(),
-            sourceCommit.getId().getName(),
-            ReceiveCommand.Type.CREATE);
-    pullReplicationQueue.onGitReferenceUpdated(event);
+            project, sourceRef, ObjectId.zeroId().getName(), sourceCommit.getId().getName());
+    pullReplicationQueue.onEvent(event);
 
     try (Repository repo = repoManager.openRepository(project)) {
       waitUntil(() -> checkedGetRef(repo, sourceRef) != null);
@@ -273,14 +251,10 @@
 
     ReplicationQueue pullReplicationQueue =
         plugin.getSysInjector().getInstance(ReplicationQueue.class);
-    GitReferenceUpdatedListener.Event event =
+    FakeGitReferenceUpdatedEvent event =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            newBranch,
-            ObjectId.zeroId().getName(),
-            branchRevision,
-            ReceiveCommand.Type.CREATE);
-    pullReplicationQueue.onGitReferenceUpdated(event);
+            project, newBranch, ObjectId.zeroId().getName(), branchRevision);
+    pullReplicationQueue.onEvent(event);
 
     try (Repository repo = repoManager.openRepository(project);
         Repository sourceRepo = repoManager.openRepository(project)) {
@@ -365,14 +339,10 @@
     String sourceRef = pushResult.getPatchSet().refName();
 
     ReplicationQueue pullReplicationQueue = getInstance(ReplicationQueue.class);
-    GitReferenceUpdatedListener.Event event =
+    FakeGitReferenceUpdatedEvent event =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            sourceRef,
-            ObjectId.zeroId().getName(),
-            sourceCommit.getId().getName(),
-            ReceiveCommand.Type.CREATE);
-    pullReplicationQueue.onGitReferenceUpdated(event);
+            project, sourceRef, ObjectId.zeroId().getName(), sourceCommit.getId().getName());
+    pullReplicationQueue.onEvent(event);
 
     try (Repository repo = repoManager.openRepository(project)) {
       waitUntil(() -> checkedGetRef(repo, sourceRef) != null);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationWithGitHttpTransportProtocolIT.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationWithGitHttpTransportProtocolIT.java
index d8e5947..40a9d03 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationWithGitHttpTransportProtocolIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationWithGitHttpTransportProtocolIT.java
@@ -21,7 +21,6 @@
 import com.google.gerrit.acceptance.TestPlugin;
 import com.google.gerrit.acceptance.UseLocalDisk;
 import com.google.gerrit.acceptance.config.GerritConfig;
-import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import java.io.IOException;
 import java.util.List;
 import java.util.Optional;
@@ -29,7 +28,6 @@
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.transport.ReceiveCommand;
 import org.junit.Test;
 
 @SkipProjectClone
@@ -82,14 +80,10 @@
     String sourceRef = pushResult.getPatchSet().refName();
 
     ReplicationQueue pullReplicationQueue = getInstance(ReplicationQueue.class);
-    GitReferenceUpdatedListener.Event event =
+    FakeGitReferenceUpdatedEvent event =
         new FakeGitReferenceUpdatedEvent(
-            project,
-            sourceRef,
-            ObjectId.zeroId().getName(),
-            sourceCommit.getId().getName(),
-            ReceiveCommand.Type.CREATE);
-    pullReplicationQueue.onGitReferenceUpdated(event);
+            project, sourceRef, ObjectId.zeroId().getName(), sourceCommit.getId().getName());
+    pullReplicationQueue.onEvent(event);
 
     try (Repository repo = repoManager.openRepository(project)) {
       waitUntil(() -> checkedGetRef(repo, sourceRef) != null);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueueTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueueTest.java
index 0743cb9..dc6e429 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueueTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueueTest.java
@@ -28,18 +28,20 @@
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
+import com.google.common.base.Suppliers;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.api.changes.NotifyHandling;
 import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
-import com.google.gerrit.extensions.events.GitReferenceUpdatedListener.Event;
 import com.google.gerrit.extensions.events.ProjectDeletedListener;
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.metrics.DisabledMetricMaker;
 import com.google.gerrit.server.config.SitePaths;
+import com.google.gerrit.server.data.RefUpdateAttribute;
+import com.google.gerrit.server.events.Event;
 import com.google.gerrit.server.events.EventDispatcher;
+import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.inject.Provider;
 import com.googlesource.gerrit.plugins.replication.ReplicationConfig;
@@ -164,7 +166,7 @@
   public void shouldCallSendObjectWhenMetaRef() throws ClientProtocolException, IOException {
     Event event = new TestEvent("refs/changes/01/1/meta");
     objectUnderTest.start();
-    objectUnderTest.onGitReferenceUpdated(event);
+    objectUnderTest.onEvent(event);
 
     verify(fetchRestApiClient).callSendObjects(any(), anyString(), any(), any());
   }
@@ -177,7 +179,7 @@
     when(source.isCreateMissingRepositories()).thenReturn(true);
 
     objectUnderTest.start();
-    objectUnderTest.onGitReferenceUpdated(event);
+    objectUnderTest.onEvent(event);
 
     verify(fetchRestApiClient).initProject(any(), any());
   }
@@ -190,7 +192,7 @@
     when(source.isCreateMissingRepositories()).thenReturn(false);
 
     objectUnderTest.start();
-    objectUnderTest.onGitReferenceUpdated(event);
+    objectUnderTest.onEvent(event);
 
     verify(fetchRestApiClient, never()).initProject(any(), any());
   }
@@ -199,7 +201,7 @@
   public void shouldCallSendObjectWhenPatchSetRef() throws ClientProtocolException, IOException {
     Event event = new TestEvent("refs/changes/01/1/1");
     objectUnderTest.start();
-    objectUnderTest.onGitReferenceUpdated(event);
+    objectUnderTest.onEvent(event);
 
     verify(fetchRestApiClient).callSendObjects(any(), anyString(), any(), any());
   }
@@ -212,7 +214,7 @@
 
     when(revReader.read(any(), any(), anyString(), anyInt())).thenThrow(IOException.class);
 
-    objectUnderTest.onGitReferenceUpdated(event);
+    objectUnderTest.onEvent(event);
 
     verify(fetchRestApiClient).callFetch(any(), anyString(), any());
   }
@@ -225,7 +227,7 @@
 
     when(revReader.read(any(), any(), anyString(), anyInt())).thenReturn(Optional.empty());
 
-    objectUnderTest.onGitReferenceUpdated(event);
+    objectUnderTest.onEvent(event);
 
     verify(fetchRestApiClient).callFetch(any(), anyString(), any());
   }
@@ -241,7 +243,7 @@
     when(fetchRestApiClient.callSendObjects(any(), anyString(), any(), any()))
         .thenReturn(httpResult);
 
-    objectUnderTest.onGitReferenceUpdated(event);
+    objectUnderTest.onEvent(event);
 
     verify(fetchRestApiClient).callFetch(any(), anyString(), any());
   }
@@ -257,7 +259,7 @@
     when(fetchRestApiClient.callSendObjects(any(), anyString(), any(), any()))
         .thenReturn(httpResult);
 
-    objectUnderTest.onGitReferenceUpdated(event);
+    objectUnderTest.onEvent(event);
 
     verify(fetchRestApiClient, times(2))
         .callSendObjects(any(), anyString(), revisionsDataCaptor.capture(), any());
@@ -293,7 +295,7 @@
             applyObjectMetrics,
             fetchMetrics);
     Event event = new TestEvent("refs/multi-site/version");
-    objectUnderTest.onGitReferenceUpdated(event);
+    objectUnderTest.onEvent(event);
 
     verifyZeroInteractions(wq, rd, dis, sl, fetchClientFactory, accountInfo);
   }
@@ -301,7 +303,7 @@
   @Test
   public void shouldSkipEventWhenStarredChangesRef() {
     Event event = new TestEvent("refs/starred-changes/41/2941/1000000");
-    objectUnderTest.onGitReferenceUpdated(event);
+    objectUnderTest.onEvent(event);
 
     verifyZeroInteractions(wq, rd, dis, sl, fetchClientFactory, accountInfo);
   }
@@ -366,64 +368,21 @@
     return createTempDirectory(prefix);
   }
 
-  private class TestEvent implements GitReferenceUpdatedListener.Event {
-    private String refName;
-    private String projectName;
-    private ObjectId newObjectId;
-
+  private class TestEvent extends RefUpdatedEvent {
     public TestEvent(String refName) {
-      this(refName, "defaultProject", ObjectId.zeroId());
+      this(
+          refName,
+          "defaultProject",
+          ObjectId.fromString("3c1ddc050d7906adb0e29bc3bc46af8749b2f63b"));
     }
 
     public TestEvent(String refName, String projectName, ObjectId newObjectId) {
-      this.refName = refName;
-      this.projectName = projectName;
-      this.newObjectId = newObjectId;
-    }
-
-    @Override
-    public String getRefName() {
-      return refName;
-    }
-
-    @Override
-    public String getProjectName() {
-      return projectName;
-    }
-
-    @Override
-    public NotifyHandling getNotify() {
-      return null;
-    }
-
-    @Override
-    public String getOldObjectId() {
-      return ObjectId.zeroId().getName();
-    }
-
-    @Override
-    public String getNewObjectId() {
-      return newObjectId.getName();
-    }
-
-    @Override
-    public boolean isCreate() {
-      return false;
-    }
-
-    @Override
-    public boolean isDelete() {
-      return false;
-    }
-
-    @Override
-    public boolean isNonFastForward() {
-      return false;
-    }
-
-    @Override
-    public AccountInfo getUpdater() {
-      return null;
+      RefUpdateAttribute upd = new RefUpdateAttribute();
+      upd.newRev = newObjectId.getName();
+      upd.oldRev = ObjectId.zeroId().getName();
+      upd.project = projectName;
+      upd.refName = refName;
+      this.refUpdate = Suppliers.ofInstance(upd);
     }
   }