Merge "Use `ProjectCache.onCreateProject` after project creation" into stable-3.9
diff --git a/example-setup/broker/Dockerfile b/example-setup/broker/Dockerfile
index d615273..9ed7944 100644
--- a/example-setup/broker/Dockerfile
+++ b/example-setup/broker/Dockerfile
@@ -1,4 +1,4 @@
-FROM gerritcodereview/gerrit:3.8.1-almalinux9
+FROM gerritcodereview/gerrit:3.9.0-rc4-almalinux9
 
 USER root
 
diff --git a/example-setup/broker/configs/replication.config.template b/example-setup/broker/configs/replication.config.template
index e77edeb..92047f8 100644
--- a/example-setup/broker/configs/replication.config.template
+++ b/example-setup/broker/configs/replication.config.template
@@ -14,7 +14,7 @@
     url = http://$REMOTE_URL:8080/#{name}#.git
     apiUrl = http://$REMOTE_URL:8080/
     fetch = +refs/*:refs/*
-    mirror = true
+    mirror = $MIRROR
     timeout = 60 # In seconds
     connectionTimeout = 120000 # In mseconds
     rescheduleDelay = 15
diff --git a/example-setup/broker/docker-compose.yaml b/example-setup/broker/docker-compose.yaml
index 705aea6..5d2e68a 100644
--- a/example-setup/broker/docker-compose.yaml
+++ b/example-setup/broker/docker-compose.yaml
@@ -11,6 +11,7 @@
       - BROKER_HOST=broker
       - BROKER_PORT=9092
       - REPLICATE_ON_STARTUP=false
+      - MIRROR=true
     ports:
       - "8080:8080"
       - "29418:29418"
@@ -28,6 +29,7 @@
       - BROKER_HOST=broker
       - BROKER_PORT=9092
       - REPLICATE_ON_STARTUP=true
+      - MIRROR=true
     ports:
       - "8081:8080"
       - "29419:29418"
diff --git a/example-setup/http/Dockerfile b/example-setup/http/Dockerfile
index 6f1d1f9..32a475e 100644
--- a/example-setup/http/Dockerfile
+++ b/example-setup/http/Dockerfile
@@ -1,4 +1,4 @@
-FROM gerritcodereview/gerrit:3.8.1-almalinux9
+FROM gerritcodereview/gerrit:3.9.0-rc4-almalinux9
 
 USER root
 
diff --git a/example-setup/http/configs/replication.config.template b/example-setup/http/configs/replication.config.template
index 6768146..53809ca 100644
--- a/example-setup/http/configs/replication.config.template
+++ b/example-setup/http/configs/replication.config.template
@@ -13,7 +13,7 @@
     url = http://$REMOTE_URL:8080/#{name}#.git
     apiUrl = http://$REMOTE_URL:8080
     fetch = +refs/*:refs/*
-    mirror = true
+    mirror = $MIRROR
     timeout = 60 # In seconds
     connectionTimeout = 120000 # In mseconds
     rescheduleDelay = 15
diff --git a/example-setup/http/docker-compose.yaml b/example-setup/http/docker-compose.yaml
index ccb6b86..62fed3c 100644
--- a/example-setup/http/docker-compose.yaml
+++ b/example-setup/http/docker-compose.yaml
@@ -9,6 +9,7 @@
       - REMOTE_URL=gerrit2
       - DEBUG_PORT=5005
       - REPLICATE_ON_STARTUP=false
+      - MIRROR=true
     ports:
       - "8080:8080"
       - "29418:29418"
@@ -22,6 +23,7 @@
       - REMOTE_URL=gerrit1
       - DEBUG_PORT=5006
       - REPLICATE_ON_STARTUP=true
+      - MIRROR=true
     ports:
       - "8081:8080"
       - "29419:29418"
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 31057ca..8fb6b0d 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
@@ -763,7 +763,8 @@
 
   private void fireBeforeStartupEvents() {
     Set<String> eventsReplayed = new HashSet<>();
-    for (ReferenceBatchUpdatedEvent event : beforeStartupEventsQueue) {
+    ReferenceBatchUpdatedEvent event;
+    while ((event = beforeStartupEventsQueue.poll()) != null) {
       String eventKey =
           String.format(
               "%s:%s",
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 0f7af40..9984a03 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
@@ -906,6 +906,10 @@
     return config.replicateProjectDeletions();
   }
 
+  public boolean isMirror() {
+    return config.getRemoteConfig().isMirror();
+  }
+
   public boolean enableBatchedRefs() {
     return config.enableBatchedRefs();
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommand.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommand.java
index f204f89..3150fe1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommand.java
@@ -68,6 +68,18 @@
 
   public void deleteRef(Project.NameKey name, String refName, String sourceLabel)
       throws IOException, RestApiException {
+    Source source =
+        sourcesCollection
+            .getByRemoteName(sourceLabel)
+            .orElseThrow(
+                () ->
+                    new IllegalStateException(
+                        String.format("Could not find URI for %s remote", sourceLabel)));
+    if (!source.isMirror()) {
+      repLog.info(
+          "Ignoring ref {} deletion from project {}, as mirror option is false", refName, name);
+      return;
+    }
     try {
       repLog.info("Delete ref from {} for project {}, ref name {}", sourceLabel, name, refName);
       Optional<ProjectState> projectState = projectCache.get(name);
@@ -81,13 +93,6 @@
         return;
       }
 
-      Source source =
-          sourcesCollection
-              .getByRemoteName(sourceLabel)
-              .orElseThrow(
-                  () ->
-                      new IllegalStateException(
-                          String.format("Could not find URI for %s remote", sourceLabel)));
       URIish sourceUri = source.getURI(name);
 
       try {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/fetch/ApplyObject.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/fetch/ApplyObject.java
index 5a4c92f..dc90c7f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/fetch/ApplyObject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/fetch/ApplyObject.java
@@ -94,7 +94,7 @@
         return new RefUpdateState(refSpec.getSource(), result);
       }
     } catch (RepositoryNotFoundException e) {
-      throw new ResourceNotFoundException(IdString.fromDecoded(name.get()));
+      throw new ResourceNotFoundException(IdString.fromDecoded(name.get()), e);
     }
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommandTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommandTest.java
index 6e40226..9c9c689 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommandTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/DeleteRefCommandTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
 
 import com.google.gerrit.entities.Project;
@@ -106,6 +107,8 @@
 
   @Test
   public void shouldSendEventWhenDeletingRef() throws Exception {
+    when(source.isMirror()).thenReturn(true);
+
     objectUnderTest.deleteRef(TEST_PROJECT_NAME, TEST_REF_NAME, TEST_SOURCE_LABEL);
 
     verify(eventDispatcher).postEvent(eventCaptor.capture());
@@ -117,7 +120,17 @@
   }
 
   @Test
+  public void shouldNotSendNotSendEventWhenMirroringIsDisabled() throws Exception {
+    when(source.isMirror()).thenReturn(false);
+
+    objectUnderTest.deleteRef(TEST_PROJECT_NAME, TEST_REF_NAME, TEST_SOURCE_LABEL);
+
+    verifyNoInteractions(eventDispatcher);
+  }
+
+  @Test
   public void shouldHandleNonExistingRef() throws Exception {
+    when(source.isMirror()).thenReturn(true);
     when(refDb.exactRef(anyString())).thenReturn(null);
 
     objectUnderTest.deleteRef(TEST_PROJECT_NAME, NON_EXISTING_REF_NAME, TEST_SOURCE_LABEL);