Allow creation of new projects

This change [1] introduced a regression when creating a new project.

Project creation is skipped since the Source#shouldReplicate
check for projects existance in the cache [2], hence the method
should NOT be invoked for new projects.

Check the source configuration, but skipping the cache.
As part of the source configuration check, the
`remote.NAME.createMissingRepositories` flag is checked as well.

Note that the logic is not taking into consideration if a project
is  hidden.
A project could potentially be created on the remote and be
visible until the correct 'refs/meta/config' isn't replicated
from the source.

The same is currently happening for push-replication, hence there
is no regression between the two solutions.

[1]: https://gerrit-review.googlesource.com/c/plugins/pull-replication/+/363004
[2]: https://gerrit.googlesource.com/plugins/pull-replication/+/refs/heads/stable-3.4/src/main/java/com/googlesource/gerrit/plugins/replication/pull/Source.java#376

Bug: Issue 16790
Change-Id: Idd1bd88b8c46d31993896640fd9f9ae071ee034d
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 6bf4c21..db7728b 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
@@ -624,6 +624,10 @@
     return configSettingsAllowReplication(project);
   }
 
+  public boolean wouldCreateProject(Project.NameKey project) {
+    return configSettingsAllowReplication(project);
+  }
+
   private boolean configSettingsAllowReplication(Project.NameKey project) {
     // by default fetch all projects
     List<String> projects = config.getProjects();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListener.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListener.java
index 6aabcd5..2ea8a33 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListener.java
@@ -34,6 +34,7 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.googlesource.gerrit.plugins.replication.pull.FetchOne;
+import com.googlesource.gerrit.plugins.replication.pull.Source;
 import com.googlesource.gerrit.plugins.replication.pull.SourcesCollection;
 import com.googlesource.gerrit.plugins.replication.pull.api.DeleteRefCommand;
 import com.googlesource.gerrit.plugins.replication.pull.api.FetchAction;
@@ -43,6 +44,7 @@
 import com.googlesource.gerrit.plugins.replication.pull.api.PullReplicationApiRequestMetrics;
 import com.googlesource.gerrit.plugins.replication.pull.filter.ExcludedRefsFilter;
 import java.io.IOException;
+import java.util.Optional;
 import org.eclipse.jgit.lib.ObjectId;
 
 public class StreamEventListener implements EventListener {
@@ -162,12 +164,25 @@
       return false;
     }
 
+    Optional<Source> maybeSource =
+        sources.getAll().stream()
+            .filter(s -> s.getRemoteConfigName().equals(event.instanceId))
+            .findFirst();
+
+    if (!maybeSource.isPresent()) {
+      return false;
+    }
+
+    Source source = maybeSource.get();
+    if (event instanceof ProjectCreatedEvent) {
+      ProjectCreatedEvent projectCreatedEvent = (ProjectCreatedEvent) event;
+
+      return source.isCreateMissingRepositories()
+          && source.wouldCreateProject(projectCreatedEvent.getProjectNameKey());
+    }
+
     ProjectEvent projectEvent = (ProjectEvent) event;
-    return sources.getAll().stream()
-        .filter(s -> s.getRemoteConfigName().equals(projectEvent.instanceId))
-        .findFirst()
-        .map(s -> s.wouldFetchProject(projectEvent.getProjectNameKey()))
-        .orElse(false);
+    return source.wouldFetchProject(projectEvent.getProjectNameKey());
   }
 
   private boolean isRefDelete(RefUpdatedEvent event) {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListenerTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListenerTest.java
index 3e71530..92314a4 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListenerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/event/StreamEventListenerTest.java
@@ -82,6 +82,8 @@
         .thenReturn(fetchJob);
     when(sources.getAll()).thenReturn(Lists.newArrayList(source));
     when(source.wouldFetchProject(any())).thenReturn(true);
+    when(source.wouldCreateProject(any())).thenReturn(true);
+    when(source.isCreateMissingRepositories()).thenReturn(true);
     when(source.getRemoteConfigName()).thenReturn(REMOTE_INSTANCE_ID);
     when(refsFilter.match(any())).thenReturn(false);
     objectUnderTest =
@@ -212,6 +214,34 @@
   }
 
   @Test
+  public void shouldNotCreateProjectWhenCreateMissingRepositoriesNotSet()
+      throws AuthException, PermissionBackendException {
+    when(source.isCreateMissingRepositories()).thenReturn(false);
+
+    ProjectCreatedEvent event = new ProjectCreatedEvent();
+    event.instanceId = REMOTE_INSTANCE_ID;
+    event.projectName = TEST_PROJECT;
+
+    objectUnderTest.onEvent(event);
+
+    verify(projectInitializationAction, never()).initProject(any());
+  }
+
+  @Test
+  public void shouldNotCreateProjectWhenReplicationNotAllowed()
+      throws AuthException, PermissionBackendException {
+    when(source.isCreateMissingRepositories()).thenReturn(false);
+
+    ProjectCreatedEvent event = new ProjectCreatedEvent();
+    event.instanceId = REMOTE_INSTANCE_ID;
+    event.projectName = TEST_PROJECT;
+
+    objectUnderTest.onEvent(event);
+
+    verify(projectInitializationAction, never()).initProject(any());
+  }
+
+  @Test
   public void shouldScheduleAllRefsFetchForProjectCreatedEvent() {
     ProjectCreatedEvent event = new ProjectCreatedEvent();
     event.instanceId = REMOTE_INSTANCE_ID;