Extract FetchApiClient interface

Extract FetchApiClient interface from FetchRestApiClient class and use
the new interface instead of the implementation. This allows to add
additional ways to send fetch and apply object messages.

Bug: Issue 15636
Change-Id: I68ec715f1f026ae4b61e05b332aeac8d5ca4c929
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/DeleteProjectTask.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/DeleteProjectTask.java
index ed584b7..44c6556 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/DeleteProjectTask.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/DeleteProjectTask.java
@@ -22,7 +22,7 @@
 import com.google.gerrit.server.util.IdGenerator;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
-import com.googlesource.gerrit.plugins.replication.pull.client.FetchRestApiClient;
+import com.googlesource.gerrit.plugins.replication.pull.client.FetchApiClient;
 import com.googlesource.gerrit.plugins.replication.pull.client.HttpResult;
 import java.io.IOException;
 import java.net.URISyntaxException;
@@ -39,11 +39,11 @@
   private final Source source;
   private final String uri;
   private final Project.NameKey project;
-  private final FetchRestApiClient.Factory fetchClientFactory;
+  private final FetchApiClient.Factory fetchClientFactory;
 
   @Inject
   DeleteProjectTask(
-      FetchRestApiClient.Factory fetchClientFactory,
+      FetchApiClient.Factory fetchClientFactory,
       IdGenerator ig,
       @Assisted Source source,
       @Assisted String uri,
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationModule.java
index 29ec93a..c17d5df 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/PullReplicationModule.java
@@ -43,6 +43,7 @@
 import com.googlesource.gerrit.plugins.replication.ReplicationFileBasedConfig;
 import com.googlesource.gerrit.plugins.replication.StartReplicationCapability;
 import com.googlesource.gerrit.plugins.replication.pull.api.PullReplicationApiModule;
+import com.googlesource.gerrit.plugins.replication.pull.client.FetchApiClient;
 import com.googlesource.gerrit.plugins.replication.pull.client.FetchRestApiClient;
 import com.googlesource.gerrit.plugins.replication.pull.client.HttpClient;
 import com.googlesource.gerrit.plugins.replication.pull.client.SourceHttpClient;
@@ -82,7 +83,10 @@
             .build(SourceHttpClient.Factory.class));
 
     install(new FactoryModuleBuilder().build(Source.Factory.class));
-    install(new FactoryModuleBuilder().build(FetchRestApiClient.Factory.class));
+    install(
+        new FactoryModuleBuilder()
+            .implement(FetchApiClient.class, FetchRestApiClient.class)
+            .build(FetchApiClient.Factory.class));
 
     bind(FetchReplicationMetrics.class).in(Scopes.SINGLETON);
 
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 7449263..cfe01e2 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
@@ -31,7 +31,7 @@
 import com.googlesource.gerrit.plugins.replication.pull.FetchResultProcessing.GitUpdateProcessing;
 import com.googlesource.gerrit.plugins.replication.pull.api.data.RevisionData;
 import com.googlesource.gerrit.plugins.replication.pull.api.exception.MissingParentObjectException;
-import com.googlesource.gerrit.plugins.replication.pull.client.FetchRestApiClient;
+import com.googlesource.gerrit.plugins.replication.pull.client.FetchApiClient;
 import com.googlesource.gerrit.plugins.replication.pull.client.HttpResult;
 import com.googlesource.gerrit.plugins.replication.pull.filter.ExcludedRefsFilter;
 import java.io.IOException;
@@ -71,7 +71,7 @@
   private volatile boolean running;
   private volatile boolean replaying;
   private final Queue<ReferenceUpdatedEvent> beforeStartupEventsQueue;
-  private FetchRestApiClient.Factory fetchClientFactory;
+  private FetchApiClient.Factory fetchClientFactory;
   private Integer fetchCallsTimeout;
   private ExcludedRefsFilter refsFilter;
   private RevisionReader revisionReader;
@@ -82,7 +82,7 @@
       Provider<SourcesCollection> rd,
       DynamicItem<EventDispatcher> dis,
       ReplicationStateListeners sl,
-      FetchRestApiClient.Factory fetchClientFactory,
+      FetchApiClient.Factory fetchClientFactory,
       ExcludedRefsFilter refsFilter,
       RevisionReader revReader) {
     workQueue = wq;
@@ -273,7 +273,7 @@
       for (String apiUrl : source.getApis()) {
         try {
           URIish uri = new URIish(apiUrl);
-          FetchRestApiClient fetchClient = fetchClientFactory.create(source);
+          FetchApiClient fetchClient = fetchClientFactory.create(source);
 
           HttpResult result = fetchClient.callSendObject(project, refName, isDelete, revision, uri);
           if (isProjectMissing(result, project) && source.isCreateMissingRepositories()) {
@@ -309,7 +309,7 @@
       for (String apiUrl : source.getApis()) {
         try {
           URIish uri = new URIish(apiUrl);
-          FetchRestApiClient fetchClient = fetchClientFactory.create(source);
+          FetchApiClient fetchClient = fetchClientFactory.create(source);
           HttpResult result = fetchClient.callFetch(project, refName, uri);
           if (isProjectMissing(result, project) && source.isCreateMissingRepositories()) {
             result = initProject(project, uri, fetchClient, result);
@@ -344,7 +344,7 @@
   }
 
   private HttpResult initProject(
-      Project.NameKey project, URIish uri, FetchRestApiClient fetchClient, HttpResult result)
+      Project.NameKey project, URIish uri, FetchApiClient fetchClient, HttpResult result)
       throws IOException, ClientProtocolException {
     HttpResult initProjectResult = fetchClient.initProject(project, uri);
     if (initProjectResult.isSuccessful()) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/UpdateHeadTask.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/UpdateHeadTask.java
index 943ea92..bded7d1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/UpdateHeadTask.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/UpdateHeadTask.java
@@ -22,14 +22,14 @@
 import com.google.gerrit.server.util.IdGenerator;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
-import com.googlesource.gerrit.plugins.replication.pull.client.FetchRestApiClient;
+import com.googlesource.gerrit.plugins.replication.pull.client.FetchApiClient;
 import com.googlesource.gerrit.plugins.replication.pull.client.HttpResult;
 import java.io.IOException;
 import org.eclipse.jgit.transport.URIish;
 
 public class UpdateHeadTask implements Runnable {
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-  private final FetchRestApiClient.Factory fetchClientFactory;
+  private final FetchApiClient.Factory fetchClientFactory;
   private final Source source;
   private final URIish apiURI;
   private final Project.NameKey project;
@@ -42,7 +42,7 @@
 
   @Inject
   UpdateHeadTask(
-      FetchRestApiClient.Factory fetchClientFactory,
+      FetchApiClient.Factory fetchClientFactory,
       IdGenerator ig,
       @Assisted Source source,
       @Assisted URIish apiURI,
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchApiClient.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchApiClient.java
new file mode 100644
index 0000000..476a35b
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchApiClient.java
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.replication.pull.client;
+
+import com.google.gerrit.entities.Project;
+import com.googlesource.gerrit.plugins.replication.pull.Source;
+import com.googlesource.gerrit.plugins.replication.pull.api.data.RevisionData;
+import java.io.IOException;
+import org.apache.http.client.ClientProtocolException;
+import org.eclipse.jgit.transport.URIish;
+
+public interface FetchApiClient {
+
+  public interface Factory {
+    FetchApiClient create(Source source);
+  }
+
+  HttpResult callFetch(Project.NameKey project, String refName, URIish targetUri)
+      throws ClientProtocolException, IOException;
+
+  HttpResult initProject(Project.NameKey project, URIish uri) throws IOException;
+
+  HttpResult deleteProject(Project.NameKey project, URIish apiUri) throws IOException;
+
+  HttpResult updateHead(Project.NameKey project, String newHead, URIish apiUri) throws IOException;
+
+  HttpResult callSendObject(
+      Project.NameKey project,
+      String refName,
+      boolean isDelete,
+      RevisionData revisionData,
+      URIish targetUri)
+      throws ClientProtocolException, IOException;
+}
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 ab3d3c5..f2f57cd 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
@@ -56,17 +56,13 @@
 import org.eclipse.jgit.transport.CredentialItem;
 import org.eclipse.jgit.transport.URIish;
 
-public class FetchRestApiClient implements ResponseHandler<HttpResult> {
+public class FetchRestApiClient implements FetchApiClient, ResponseHandler<HttpResult> {
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
   static String GERRIT_ADMIN_PROTOCOL_PREFIX = "gerrit+";
 
   private static final Gson GSON =
       new GsonBuilder().setFieldNamingPolicy(LOWER_CASE_WITH_UNDERSCORES).create();
 
-  public interface Factory {
-    FetchRestApiClient create(Source source);
-  }
-
   private final CredentialsFactory credentials;
   private final SourceHttpClient.Factory httpClientFactory;
   private final Source source;
@@ -95,6 +91,10 @@
         Strings.emptyToNull(instanceLabel), "replication.instanceLabel cannot be null or empty");
   }
 
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.replication.pull.client.FetchApiClient#callFetch(com.google.gerrit.entities.Project.NameKey, java.lang.String, org.eclipse.jgit.transport.URIish)
+   */
+  @Override
   public HttpResult callFetch(Project.NameKey project, String refName, URIish targetUri)
       throws ClientProtocolException, IOException {
     String url =
@@ -113,6 +113,10 @@
     return httpClientFactory.create(source).execute(post, this, getContext(targetUri));
   }
 
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.replication.pull.client.FetchApiClient#initProject(com.google.gerrit.entities.Project.NameKey, org.eclipse.jgit.transport.URIish)
+   */
+  @Override
   public HttpResult initProject(Project.NameKey project, URIish uri) throws IOException {
     String url =
         String.format(
@@ -123,6 +127,10 @@
     return httpClientFactory.create(source).execute(put, this, getContext(uri));
   }
 
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.replication.pull.client.FetchApiClient#deleteProject(com.google.gerrit.entities.Project.NameKey, org.eclipse.jgit.transport.URIish)
+   */
+  @Override
   public HttpResult deleteProject(Project.NameKey project, URIish apiUri) throws IOException {
     String url =
         String.format("%s/%s", apiUri.toASCIIString(), getProjectDeletionUrl(project.get()));
@@ -130,6 +138,10 @@
     return httpClientFactory.create(source).execute(delete, this, getContext(apiUri));
   }
 
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.replication.pull.client.FetchApiClient#updateHead(com.google.gerrit.entities.Project.NameKey, java.lang.String, org.eclipse.jgit.transport.URIish)
+   */
+  @Override
   public HttpResult updateHead(Project.NameKey project, String newHead, URIish apiUri)
       throws IOException {
     logger.atFine().log("Updating head of %s on %s", project.get(), newHead);
@@ -142,6 +154,10 @@
     return httpClientFactory.create(source).execute(req, this, getContext(apiUri));
   }
 
+  /* (non-Javadoc)
+   * @see com.googlesource.gerrit.plugins.replication.pull.client.FetchApiClient#callSendObject(com.google.gerrit.entities.Project.NameKey, java.lang.String, boolean, com.googlesource.gerrit.plugins.replication.pull.api.data.RevisionData, org.eclipse.jgit.transport.URIish)
+   */
+  @Override
   public HttpResult callSendObject(
       Project.NameKey project,
       String refName,
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueueTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueueTest.java
index 82dc2b8..4e831bc 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueueTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/pull/ReplicationQueueTest.java
@@ -43,6 +43,7 @@
 import com.googlesource.gerrit.plugins.replication.ReplicationFileBasedConfig;
 import com.googlesource.gerrit.plugins.replication.pull.api.data.RevisionData;
 import com.googlesource.gerrit.plugins.replication.pull.api.exception.RefUpdateException;
+import com.googlesource.gerrit.plugins.replication.pull.client.FetchApiClient;
 import com.googlesource.gerrit.plugins.replication.pull.client.FetchRestApiClient;
 import com.googlesource.gerrit.plugins.replication.pull.client.HttpResult;
 import com.googlesource.gerrit.plugins.replication.pull.filter.ExcludedRefsFilter;
@@ -73,7 +74,7 @@
   @Mock private DynamicItem<EventDispatcher> dis;
   @Mock ReplicationStateListeners sl;
   @Mock FetchRestApiClient fetchRestApiClient;
-  @Mock FetchRestApiClient.Factory fetchClientFactory;
+  @Mock FetchApiClient.Factory fetchClientFactory;
   @Mock AccountInfo accountInfo;
   @Mock RevisionReader revReader;
   @Mock RevisionData revisionData;
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 394a4a4..a1c2172 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
@@ -135,7 +135,7 @@
           + "  ]\n"
           + "}";
 
-  FetchRestApiClient objectUnderTest;
+  FetchApiClient objectUnderTest;
 
   @Before
   public void setup() throws ClientProtocolException, IOException {