Merge branch 'stable-3.2'

* stable-3.2:
  RenameCommand: use ProjectState instead of String project name
  Add REST endpoint to rename operation

Change-Id: I89c18d17133447dde34b842ad0fedb9fa8df5bfb
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/Module.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/Module.java
index 6962811..568a7be 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/Module.java
@@ -14,12 +14,14 @@
 
 package com.googlesource.gerrit.plugins.renameproject;
 
+import static com.google.gerrit.server.project.ProjectResource.PROJECT_KIND;
 import static com.googlesource.gerrit.plugins.renameproject.RenameOwnProjectCapability.RENAME_OWN_PROJECT;
 import static com.googlesource.gerrit.plugins.renameproject.RenameProjectCapability.RENAME_PROJECT;
 
 import com.google.gerrit.extensions.annotations.Exports;
 import com.google.gerrit.extensions.config.CapabilityDefinition;
 import com.google.gerrit.extensions.events.LifecycleListener;
+import com.google.gerrit.extensions.restapi.RestApiModule;
 import com.google.inject.AbstractModule;
 import com.google.inject.internal.UniqueAnnotations;
 import com.googlesource.gerrit.plugins.renameproject.cache.CacheRenameHandler;
@@ -45,5 +47,13 @@
     bind(RenamePreconditions.class);
     bind(IndexUpdateHandler.class);
     bind(RevertRenameProject.class);
+
+    install(
+        new RestApiModule() {
+          @Override
+          protected void configure() {
+            post(PROJECT_KIND, "rename").to(RenameProject.class);
+          }
+        });
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameCommand.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameCommand.java
index ef251db..6a80283 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameCommand.java
@@ -14,14 +14,14 @@
 
 package com.googlesource.gerrit.plugins.renameproject;
 
+import static com.googlesource.gerrit.plugins.renameproject.RenameProject.CANCELLATION_MSG;
 import static com.googlesource.gerrit.plugins.renameproject.RenameProject.WARNING_LIMIT;
 
 import com.google.gerrit.entities.Change;
-import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectResource;
+import com.google.gerrit.server.project.ProjectState;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
@@ -33,6 +33,7 @@
 import java.io.InputStreamReader;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Optional;
 import org.kohsuke.args4j.Argument;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,23 +41,18 @@
 @CommandMetaData(name = "rename", description = "Rename project")
 public final class RenameCommand extends SshCommand {
   @Argument(index = 0, required = true, metaVar = "OLDPROJECT", usage = "project to rename")
-  private String projectControl;
+  private ProjectState projectState;
 
   @Argument(index = 1, required = true, metaVar = "NEWNAME", usage = "new name for the project")
   private String newProjectName;
 
   private static final Logger log = LoggerFactory.getLogger(RenameCommand.class);
   private final RenameProject renameProject;
-  private final Provider<ProjectCache> projectCacheProvider;
   private final Provider<CurrentUser> self;
 
   @Inject
-  protected RenameCommand(
-      RenameProject renameProject,
-      Provider<ProjectCache> projectCacheProvider,
-      Provider<CurrentUser> self) {
+  protected RenameCommand(RenameProject renameProject, Provider<CurrentUser> self) {
     this.renameProject = renameProject;
-    this.projectCacheProvider = projectCacheProvider;
     this.self = self;
   }
 
@@ -65,18 +61,15 @@
     try {
       RenameProject.Input input = new RenameProject.Input();
       input.name = newProjectName;
-      ProjectResource rsrc =
-          new ProjectResource(
-              projectCacheProvider.get().get(Project.nameKey(projectControl)).get(), self.get());
+      ProjectResource rsrc = new ProjectResource(projectState, self.get());
       try (CommandProgressMonitor monitor = new CommandProgressMonitor(stdout)) {
-        renameProject.assertCanRename(rsrc, input, monitor);
-        List<Change.Id> changeIds = renameProject.getChanges(rsrc, monitor);
+        renameProject.assertCanRename(rsrc, input, Optional.of(monitor));
+        List<Change.Id> changeIds = renameProject.getChanges(rsrc, Optional.of(monitor));
         if (continueRename(changeIds, monitor)) {
-          renameProject.doRename(changeIds, rsrc, input, monitor);
+          renameProject.doRename(changeIds, rsrc, input, Optional.of(monitor));
         } else {
-          String cancellationMsg = "Rename operation was cancelled by user.";
-          log.debug(cancellationMsg);
-          stdout.println(cancellationMsg);
+          log.debug(CANCELLATION_MSG);
+          stdout.println(CANCELLATION_MSG);
           stdout.flush();
         }
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java
index 41b68a6..3104491 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java
@@ -21,12 +21,15 @@
 import com.google.common.base.Strings;
 import com.google.common.cache.Cache;
 import com.google.gerrit.entities.Change;
+import com.google.gerrit.entities.Change.Id;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.api.access.PluginPermission;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.Response;
+import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.extensions.events.PluginEvent;
@@ -39,6 +42,7 @@
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.google.inject.name.Named;
+import com.googlesource.gerrit.plugins.renameproject.RenameProject.Input;
 import com.googlesource.gerrit.plugins.renameproject.cache.CacheRenameHandler;
 import com.googlesource.gerrit.plugins.renameproject.conditions.RenamePreconditions;
 import com.googlesource.gerrit.plugins.renameproject.database.DatabaseRenameHandler;
@@ -48,18 +52,39 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class RenameProject {
+public class RenameProject implements RestModifyView<ProjectResource, Input> {
+
+  @Override
+  public Response<?> apply(ProjectResource resource, Input input)
+      throws IOException, AuthException, BadRequestException, ResourceConflictException,
+          InterruptedException, ConfigInvalidException, RenameRevertException {
+    assertCanRename(resource, input, Optional.empty());
+    List<Id> changeIds = getChanges(resource, Optional.empty());
+
+    if (changeIds == null || changeIds.size() <= WARNING_LIMIT || input.continueWithRename) {
+      doRename(changeIds, resource, input, Optional.empty());
+    } else {
+      log.debug(CANCELLATION_MSG);
+      return Response.none();
+    }
+    return Response.ok("");
+  }
 
   static class Input {
     String name;
+    boolean continueWithRename;
   }
 
   static final int WARNING_LIMIT = 5000;
+  static final String CANCELLATION_MSG =
+      "Rename cancelled due to number of changes exceeding warning limit and user's will to not continue";
+
   private static final Logger log = LoggerFactory.getLogger(RenameProject.class);
   private static final String CACHE_NAME = "changeid_project";
 
@@ -146,10 +171,11 @@
     return true;
   }
 
-  void assertCanRename(ProjectResource rsrc, Input input, ProgressMonitor pm)
+  void assertCanRename(ProjectResource rsrc, Input input, Optional<ProgressMonitor> pm)
       throws ResourceConflictException, BadRequestException, AuthException {
     try {
-      pm.beginTask("Checking preconditions");
+      pm.ifPresent(progressMonitor -> progressMonitor.beginTask("Checking preconditions"));
+
       assertNewNameNotNull(input);
       assertRenamePermission(rsrc);
       renamePreconditions.assertCanRename(rsrc, Project.nameKey(input.name));
@@ -159,7 +185,8 @@
     }
   }
 
-  void doRename(List<Change.Id> changeIds, ProjectResource rsrc, Input input, ProgressMonitor pm)
+  void doRename(
+      List<Change.Id> changeIds, ProjectResource rsrc, Input input, Optional<ProgressMonitor> pm)
       throws InterruptedException, ConfigInvalidException, IOException, RenameRevertException {
     Project.NameKey oldProjectKey = rsrc.getNameKey();
     Project.NameKey newProjectKey = Project.nameKey(input.name);
@@ -211,7 +238,7 @@
   }
 
   void fsRenameStep(
-      Project.NameKey oldProjectKey, Project.NameKey newProjectKey, ProgressMonitor pm)
+      Project.NameKey oldProjectKey, Project.NameKey newProjectKey, Optional<ProgressMonitor> pm)
       throws IOException {
     fsHandler.rename(oldProjectKey, newProjectKey, pm);
     logPerformedStep(Step.FILESYSTEM, newProjectKey, oldProjectKey);
@@ -227,7 +254,7 @@
       List<Change.Id> changeIds,
       Project.NameKey oldProjectKey,
       Project.NameKey newProjectKey,
-      ProgressMonitor pm)
+      Optional<ProgressMonitor> pm)
       throws IOException, ConfigInvalidException, RenameRevertException {
     List<Change.Id> updatedChangeIds = dbHandler.rename(changeIds, newProjectKey, pm);
     logPerformedStep(Step.DATABASE, newProjectKey, oldProjectKey);
@@ -238,7 +265,7 @@
       List<Change.Id> updatedChangeIds,
       Project.NameKey oldProjectKey,
       Project.NameKey newProjectKey,
-      ProgressMonitor pm)
+      Optional<ProgressMonitor> pm)
       throws InterruptedException {
     indexHandler.updateIndex(updatedChangeIds, newProjectKey, pm);
     logPerformedStep(Step.INDEX, newProjectKey, oldProjectKey);
@@ -274,8 +301,9 @@
     return stepsPerformed;
   }
 
-  List<Change.Id> getChanges(ProjectResource rsrc, ProgressMonitor pm) throws IOException {
-    pm.beginTask("Retrieving the list of changes from DB");
+  List<Change.Id> getChanges(ProjectResource rsrc, Optional<ProgressMonitor> opm)
+      throws IOException {
+    opm.ifPresent(pm -> pm.beginTask("Retrieving the list of changes from DB"));
     Project.NameKey oldProjectKey = rsrc.getNameKey();
     return dbHandler.getChangeIds(oldProjectKey);
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProject.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProject.java
index 72ef4fd..484492a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProject.java
@@ -27,6 +27,7 @@
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -56,13 +57,13 @@
       List<Id> changeIds,
       Project.NameKey oldProjectKey,
       Project.NameKey newProjectKey,
-      ProgressMonitor pm)
+      Optional<ProgressMonitor> opm)
       throws IOException, RenameRevertException, ConfigInvalidException {
-    pm.beginTask("Reverting the rename procedure.");
+    opm.ifPresent(pm -> pm.beginTask("Reverting the rename procedure."));
     List<Change.Id> updatedChangeIds = Collections.emptyList();
     if (stepsPerformed.contains(Step.FILESYSTEM)) {
       try {
-        fsHandler.rename(newProjectKey, oldProjectKey, pm);
+        fsHandler.rename(newProjectKey, oldProjectKey, opm);
         log.debug("Reverted the git repo name to {} successfully.", oldProjectKey.get());
       } catch (IOException e) {
         log.error(
@@ -76,7 +77,7 @@
     }
     if (stepsPerformed.contains(Step.DATABASE)) {
       try {
-        updatedChangeIds = dbHandler.rename(changeIds, newProjectKey, pm);
+        updatedChangeIds = dbHandler.rename(changeIds, newProjectKey, opm);
         log.debug(
             "Reverted the changes in DB successfully from project {} to project {}.",
             newProjectKey.get(),
@@ -91,7 +92,7 @@
     }
     if (stepsPerformed.contains(Step.INDEX)) {
       try {
-        indexHandler.updateIndex(updatedChangeIds, oldProjectKey, pm);
+        indexHandler.updateIndex(updatedChangeIds, oldProjectKey, opm);
         log.debug(
             "Reverted the secondary index successfully from project {} to project {}.",
             newProjectKey.get(),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java
index 79275e3..7afbf11 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java
@@ -39,6 +39,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Stream;
 import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -89,9 +90,9 @@
   }
 
   public List<Change.Id> rename(
-      List<Change.Id> changes, Project.NameKey newProjectKey, ProgressMonitor pm)
+      List<Change.Id> changes, Project.NameKey newProjectKey, Optional<ProgressMonitor> opm)
       throws RenameRevertException, IOException, ConfigInvalidException {
-    pm.beginTask("Updating changes in the database");
+    opm.ifPresent(pm -> pm.beginTask("Updating changes in the database"));
     log.debug("Updating the changes in noteDb related to project {}", oldProjectKey.get());
     try {
       updateWatchEntries(newProjectKey);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/IndexUpdateHandler.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/IndexUpdateHandler.java
index 5b01391..81fa156 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/IndexUpdateHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/IndexUpdateHandler.java
@@ -24,6 +24,7 @@
 import com.googlesource.gerrit.plugins.renameproject.monitor.ProgressMonitor;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -46,17 +47,17 @@
   }
 
   public void updateIndex(
-      List<Change.Id> changeIds, Project.NameKey newProjectKey, ProgressMonitor pm)
+      List<Change.Id> changeIds, Project.NameKey newProjectKey, Optional<ProgressMonitor> opm)
       throws InterruptedException {
     log.debug("Starting to index {} change(s).", changeIds.size());
     ExecutorService executor =
         Executors.newFixedThreadPool(
             config.getIndexThreads(),
             new ThreadFactoryBuilder().setNameFormat("Rename-Index-%d").build());
-    pm.beginTask("Indexing changes", changeIds.size());
+    opm.ifPresent(pm -> pm.beginTask("Indexing changes", changeIds.size()));
     List<Callable<Boolean>> callableTasks = new ArrayList<>(changeIds.size());
     for (Change.Id id : changeIds) {
-      callableTasks.add(new IndexTask(id, newProjectKey, pm));
+      callableTasks.add(new IndexTask(id, newProjectKey, opm));
     }
     List<Future<Boolean>> tasksCompleted = executor.invokeAll(callableTasks);
     executor.shutdown();
@@ -83,9 +84,10 @@
 
     private Change.Id changeId;
     private Project.NameKey newProjectKey;
-    private ProgressMonitor monitor;
+    private Optional<ProgressMonitor> monitor;
 
-    IndexTask(Change.Id changeId, Project.NameKey newProjectKey, ProgressMonitor monitor) {
+    IndexTask(
+        Change.Id changeId, Project.NameKey newProjectKey, Optional<ProgressMonitor> monitor) {
       this.changeId = changeId;
       this.newProjectKey = newProjectKey;
       this.monitor = monitor;
@@ -94,7 +96,7 @@
     @Override
     public Boolean call() throws Exception {
       indexer.index(newProjectKey, changeId);
-      monitor.update(1);
+      monitor.ifPresent(monitor -> monitor.update(1));
       return Boolean.TRUE;
     }
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/fs/FilesystemRenameHandler.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/fs/FilesystemRenameHandler.java
index 9294392..a1ea2b1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/fs/FilesystemRenameHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/fs/FilesystemRenameHandler.java
@@ -26,6 +26,7 @@
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
 import java.util.Comparator;
+import java.util.Optional;
 import java.util.stream.Stream;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.lib.Repository;
@@ -45,12 +46,12 @@
   }
 
   public void rename(
-      Project.NameKey oldProjectKey, Project.NameKey newProjectKey, ProgressMonitor pm)
+      Project.NameKey oldProjectKey, Project.NameKey newProjectKey, Optional<ProgressMonitor> opm)
       throws IOException, RepositoryNotFoundException {
     Repository repository = repoManager.openRepository(oldProjectKey);
     File repoFile = repository.getDirectory();
     RepositoryCache.close(repository);
-    pm.beginTask("Renaming git repository");
+    opm.ifPresent(pm -> pm.beginTask("Renaming git repository"));
     renameGitRepository(repoFile, newProjectKey, oldProjectKey);
   }
 
diff --git a/src/main/resources/Documentation/rest-api-rename.md b/src/main/resources/Documentation/rest-api-rename.md
new file mode 100644
index 0000000..70ecf15
--- /dev/null
+++ b/src/main/resources/Documentation/rest-api-rename.md
@@ -0,0 +1,55 @@
+@PLUGIN@ - /@PLUGIN@/ REST API
+===================================
+
+This page describes the REST endpoint that is added by the @PLUGIN@
+plugin.
+
+Please also take note of the general information on the
+[REST API](../../../Documentation/rest-api.html).
+
+This API implements a REST equivalent of the Ssh rename-project command.
+For more information, refer to:
+* [Ssh rename-project command](cmd-rename.md)
+------------------------------------------
+
+REQUEST
+-------
+```
+POST /projects/project-1/@PLUGIN@~rename HTTP/1.1
+  {
+    "name" : "project-2",
+  }
+```
+to rename project-1 to project-2.
+
+By default, if project-1 has more than 5000 changes, the rename procedure will be cancelled as it
+can take longer time and can degrade in performance in that time frame.
+
+To rename a project with more than 5000 changes, the following request is needed:
+```
+POST /projects/project-1/@PLUGIN@~rename HTTP/1.1
+  {
+    "name" : "project-2",
+    "continueWithRename" : "true"
+  }
+```
+
+RESPONSE
+--------
+If rename succeeded:
+
+```
+HTTP/1.1 200 OK
+```
+
+If rename was cancelled due to user's intent to not proceed when the number of changes exceeds the
+warning limit of 5000 changes:
+
+```
+HTTP/1.1 204 No Content
+```
+
+ACCESS
+------
+Same as ssh version of the command, caller must be a member of a group that is granted the
+'Rename Project' (provided by this plugin) or 'Administrate Server' capabilities.
diff --git a/src/test/java/com/googlesource/gerrit/plugins/renameproject/RenameIT.java b/src/test/java/com/googlesource/gerrit/plugins/renameproject/RenameIT.java
index 6a450e9..967f5eb 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/renameproject/RenameIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/renameproject/RenameIT.java
@@ -19,15 +19,18 @@
 import com.google.common.cache.Cache;
 import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
 import com.google.gerrit.acceptance.PushOneCommit.Result;
+import com.google.gerrit.acceptance.RestResponse;
 import com.google.gerrit.acceptance.TestPlugin;
 import com.google.gerrit.acceptance.UseLocalDisk;
 import com.google.gerrit.acceptance.UseSsh;
+import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
 import com.google.gerrit.entities.Change.Id;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.entities.Project.NameKey;
 import com.google.gerrit.extensions.client.ProjectWatchInfo;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.renameproject.RenameProject.Input;
 import java.util.List;
 import java.util.Optional;
 import javax.inject.Named;
@@ -45,6 +48,8 @@
   private static final String NEW_PROJECT_NAME = "newProject";
   private static final String CACHE_NAME = "changeid_project";
 
+  @Inject private RequestScopeOperations requestScopeOperations;
+
   @Inject
   @Named(CACHE_NAME)
   private Cache<Id, String> changeIdProjectCache;
@@ -147,4 +152,39 @@
 
     assertThat(changeIdProjectCache.getIfPresent(changeID)).isNull();
   }
+
+  @Test
+  @UseLocalDisk
+  public void testRenameViaHttpSuccessful() throws Exception {
+    createChange();
+    RestResponse r = renameProjectTo(NEW_PROJECT_NAME);
+    r.assertOK();
+
+    Optional<ProjectState> projectState = projectCache.get(Project.nameKey(NEW_PROJECT_NAME));
+    assertThat(projectState.isPresent()).isTrue();
+    assertThat(queryProvider.get().byProject(project)).isEmpty();
+    assertThat(queryProvider.get().byProject(Project.nameKey(NEW_PROJECT_NAME))).isNotEmpty();
+  }
+
+  @Test
+  @UseLocalDisk
+  public void testRenameViaHttpWithEmptyNewName() throws Exception {
+    createChange();
+    String newProjectName = "";
+    RestResponse r = renameProjectTo(newProjectName);
+    r.assertBadRequest();
+
+    Optional<ProjectState> projectState = projectCache.get(Project.nameKey(newProjectName));
+    assertThat(projectState.isPresent()).isFalse();
+  }
+
+  private RestResponse renameProjectTo(String newName) throws Exception {
+    requestScopeOperations.setApiUser(user.id());
+    sender.clear();
+    String endPoint = "/projects/" + project.get() + "/" + PLUGIN_NAME + "~rename";
+    Input i = new Input();
+    i.name = newName;
+    i.continueWithRename = true;
+    return adminRestSession.post(endPoint, i);
+  }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProjectTest.java b/src/test/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProjectTest.java
index b7d4ebd..8330748 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProjectTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/renameproject/RevertRenameProjectTest.java
@@ -46,7 +46,7 @@
   private RevertRenameProject revertRenameProject;
   private Project.NameKey oldProjectKey;
   private Project.NameKey newProjectKey;
-  private ProgressMonitor pm;
+  private Optional<ProgressMonitor> pm;
   private ProjectResource oldRsrc;
 
   @Before
@@ -57,7 +57,7 @@
     oldProjectKey = project;
     newProjectKey = Project.nameKey(NEW_PROJECT_NAME);
 
-    pm = Mockito.mock(ProgressMonitor.class);
+    pm = Optional.of(Mockito.mock(ProgressMonitor.class));
 
     oldRsrc = Mockito.mock(ProjectResource.class);
     when(oldRsrc.getNameKey()).thenReturn(oldProjectKey);