Merge "Add project initialisation during fetch REST Api call" into stable-3.3
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationApiModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationApiModule.java
index f94f49b..8dc0f0f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationApiModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationApiModule.java
@@ -27,8 +27,10 @@
   protected void configure() {
     bind(FetchAction.class).in(Scopes.SINGLETON);
     bind(ApplyObjectAction.class).in(Scopes.SINGLETON);
+    bind(ProjectDeletionAction.class).in(Scopes.SINGLETON);
     post(PROJECT_KIND, "fetch").to(FetchAction.class);
     post(PROJECT_KIND, "apply-object").to(ApplyObjectAction.class);
+    delete(PROJECT_KIND, "delete-project").to(ProjectDeletionAction.class);
 
     bind(FetchPreconditions.class).in(Scopes.SINGLETON);
     bind(CapabilityDefinition.class)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilter.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilter.java
index 44dd3bb..4af2bf7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationFilter.java
@@ -27,6 +27,7 @@
 
 import com.google.common.base.Splitter;
 import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.api.projects.HeadInput;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.BadRequestException;
@@ -80,6 +81,7 @@
   private ProjectsCollection projectsCollection;
   private Gson gson;
   private Provider<CurrentUser> userProvider;
+  private String pluginName;
 
   @Inject
   public PullReplicationFilter(
@@ -89,7 +91,8 @@
       UpdateHeadAction updateHEADAction,
       ProjectDeletionAction projectDeletionAction,
       ProjectsCollection projectsCollection,
-      Provider<CurrentUser> userProvider) {
+      Provider<CurrentUser> userProvider,
+      @PluginName String pluginName) {
     this.fetchAction = fetchAction;
     this.applyObjectAction = applyObjectAction;
     this.projectInitializationAction = projectInitializationAction;
@@ -97,6 +100,7 @@
     this.projectDeletionAction = projectDeletionAction;
     this.projectsCollection = projectsCollection;
     this.userProvider = userProvider;
+    this.pluginName = pluginName;
     this.gson = OutputFormat.JSON.newGsonBuilder().create();
   }
 
@@ -303,7 +307,7 @@
   }
 
   private boolean isDeleteProjectAction(HttpServletRequest httpRequest) {
-    return httpRequest.getRequestURI().matches("(/a)?/projects/[^/]+$")
+    return httpRequest.getRequestURI().endsWith(String.format("%s~delete-project", pluginName))
         && "DELETE".equals(httpRequest.getMethod());
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClient.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClient.java
index df97609..a7e71af 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClient.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClient.java
@@ -190,7 +190,7 @@
   }
 
   String getProjectDeletionUrl(String projectName) {
-    return String.format("a/projects/%s", Url.encode(projectName));
+    return String.format("a/projects/%s/%s~delete-project", Url.encode(projectName), pluginName);
   }
 
   String getProjectUpdateHeadUrl(String projectName) {
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 c2335e8..c5b1790 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
@@ -15,7 +15,6 @@
 package com.googlesource.gerrit.plugins.replication.pull;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.server.project.ProjectResource.PROJECT_KIND;
 import static java.util.stream.Collectors.toList;
 
 import com.google.common.flogger.FluentLogger;
@@ -38,11 +37,9 @@
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.extensions.restapi.RestApiModule;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.project.ProjectResource;
-import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.replication.AutoReloadConfigDecorator;
@@ -83,28 +80,10 @@
   private FileBasedConfig config;
   private FileBasedConfig secureConfig;
 
-  static FakeDeleteProjectPlugin fakeDeleteProjectPlugin;
-
-  static class FakeDeleteModule extends AbstractModule {
-
-    @Override
-    public void configure() {
-      install(
-          new RestApiModule() {
-            @Override
-            public void configure() {
-              fakeDeleteProjectPlugin = new FakeDeleteProjectPlugin();
-              delete(PROJECT_KIND).toInstance(fakeDeleteProjectPlugin);
-            }
-          });
-    }
-  }
-
   @Override
   public void setUpTestPlugin() throws Exception {
     gitPath = sitePaths.site_path.resolve("git");
 
-    installPlugin("fakeDeleteProjectPlugin", FakeDeleteModule.class, null, null);
     config =
         new FileBasedConfig(sitePaths.etc_dir.resolve("replication.config").toFile(), FS.DETECTED);
     setReplicationSource(
@@ -278,12 +257,11 @@
             return NotifyHandling.NONE;
           }
         };
-
     for (ProjectDeletedListener l : deletedListeners) {
       l.onProjectDeleted(event);
     }
 
-    waitUntil(() -> fakeDeleteProjectPlugin.getDeleteEndpointCalls() == 1);
+    waitUntil(() -> !repoManager.list().contains(project));
   }
 
   @Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/ActionITBase.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/ActionITBase.java
index 343ce66..34aaf8b 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/ActionITBase.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/ActionITBase.java
@@ -127,7 +127,6 @@
 
   protected HttpDelete createDeleteRequest() {
     HttpDelete delete = new HttpDelete(url);
-    delete.addHeader(new BasicHeader("Content-Type", "application/json"));
     return delete;
   }
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/ProjectDeletionActionIT.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/ProjectDeletionActionIT.java
index 4c09266..f5c8d4c 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/ProjectDeletionActionIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/api/ProjectDeletionActionIT.java
@@ -31,6 +31,64 @@
   @Inject private ProjectOperations projectOperations;
 
   @Test
+  public void shouldReturnUnauthorizedForUserWithoutPermissions() throws Exception {
+    httpClientFactory
+        .create(source)
+        .execute(
+            createDeleteRequest(),
+            assertHttpResponseCode(HttpServletResponse.SC_UNAUTHORIZED),
+            getAnonymousContext());
+  }
+
+  @Test
+  public void shouldDeleteRepositoryWhenUserHasProjectDeletionCapabilities() throws Exception {
+    String testProjectName = project.get();
+    url = getURL(testProjectName);
+    httpClientFactory
+        .create(source)
+        .execute(
+            createDeleteRequest(),
+            assertHttpResponseCode(HttpServletResponse.SC_FORBIDDEN),
+            getUserContext());
+
+    projectOperations
+        .project(allProjects)
+        .forUpdate()
+        .add(allowCapability(DELETE_PROJECT_PERMISSION).group(SystemGroupBackend.REGISTERED_USERS))
+        .update();
+
+    httpClientFactory
+        .create(source)
+        .execute(
+            createDeleteRequest(),
+            assertHttpResponseCode(HttpServletResponse.SC_OK),
+            getUserContext());
+  }
+
+  @Test
+  public void shouldReturnOKWhenProjectIsDeleted() throws Exception {
+    String testProjectName = project.get();
+    url = getURL(testProjectName);
+
+    httpClientFactory
+        .create(source)
+        .execute(
+            createDeleteRequest(), assertHttpResponseCode(HttpServletResponse.SC_OK), getContext());
+  }
+
+  @Test
+  public void shouldReturnInternalServerErrorIfProjectCannotBeDeleted() throws Exception {
+    url = getURL(INVALID_TEST_PROJECT_NAME);
+
+    httpClientFactory
+        .create(source)
+        .execute(
+            createDeleteRequest(),
+            assertHttpResponseCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR),
+            getContext());
+  }
+
+  @Test
   @GerritConfig(name = "container.replica", value = "true")
   public void shouldReturnUnauthorizedForUserWithoutPermissionsOnReplica() throws Exception {
     httpClientFactory
@@ -96,6 +154,8 @@
 
   @Override
   protected String getURL(String projectName) {
-    return String.format("%s/a/projects/%s", adminRestSession.url(), Url.encode(projectName));
+    return String.format(
+        "%s/a/projects/%s/pull-replication~delete-project",
+        adminRestSession.url(), Url.encode(projectName));
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClientTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClientTest.java
index ed1eef4..17df2df 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClientTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchRestApiClientTest.java
@@ -376,7 +376,8 @@
 
     HttpDelete httpDelete = httpDeleteCaptor.getValue();
     assertThat(httpDelete.getURI().getHost()).isEqualTo("gerrit-host");
-    assertThat(httpDelete.getURI().getPath()).isEqualTo("/a/projects/test_repo");
+    assertThat(httpDelete.getURI().getPath())
+        .isEqualTo("/a/projects/test_repo/pull-replication~delete-project");
   }
 
   @Test