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;