Decouple replication-api.jar from the main replication plugin

The Change Ib7a04eea5 made the whole replication plugin an ApiModule
which becomes the base injector for all plugins and forbids reloads,
(see the  Iac2851022ea for enforcing it at Gerrit level)
even when there is no intention to use th extension points.

All plugins that expose an ApiModule have the following limitations:
- Cannot add extra dependencies
- Cannot be reloaded
- Are the base injectors for all plugins

The above limitations aren't acceptable for the whole replication
plugin when used standalone without extensions.

Define a new replication-api target that generates the sole ApiModule
needed for extending the replication plugin functionality.
All the classes that are part of the replication-api are moved
into a separate c.g.g.p.replication.api package so that can be
included in the replication-api.jar plugin.

The gerrit.war will continue to include only the replication.jar which
will still work out of the box. Anyone willing to customise its behaviour
through the API will have to build the replication-api target.
Also fix the MergedConfigResource that was assuming that the ApiModule
was always installed and was binding DynamicItem<ReplicationConfigOverrides>.

Bug: Issue 324462734
Release-Notes: Decouple replication-api.jar from the main replication plugin
Change-Id: Ic432fc77daf1162368abd65f64c463e4ef4f5d6d
diff --git a/BUILD b/BUILD
index 04b470b..9c209ed 100644
--- a/BUILD
+++ b/BUILD
@@ -9,12 +9,28 @@
         "Implementation-Title: Replication plugin",
         "Implementation-URL: https://gerrit-review.googlesource.com/#/admin/projects/plugins/replication",
         "Gerrit-PluginName: replication",
-        "Gerrit-ApiModule: com.googlesource.gerrit.plugins.replication.ApiModule",
         "Gerrit-InitStep: com.googlesource.gerrit.plugins.replication.Init",
         "Gerrit-Module: com.googlesource.gerrit.plugins.replication.ReplicationModule",
         "Gerrit-SshModule: com.googlesource.gerrit.plugins.replication.SshModule",
     ],
     resources = glob(["src/main/resources/**/*"]),
+    deps = [
+        "//plugins/replication:replication-api",
+    ],
+)
+
+gerrit_plugin(
+    name = "replication-api",
+    srcs = glob(
+        ["src/main/java/com/googlesource/gerrit/plugins/replication/api/*.java"],
+    ),
+    dir_name = "replication",
+    manifest_entries = [
+        "Implementation-Title: Replication plugin API",
+        "Implementation-URL: https://gerrit-review.googlesource.com/#/admin/projects/plugins/replication",
+        "Gerrit-PluginName: replication-api",
+        "Gerrit-ApiModule: com.googlesource.gerrit.plugins.replication.api.ApiModule",
+    ],
 )
 
 junit_tests(
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
index 9d0c978..9c658e0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
@@ -21,6 +21,7 @@
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
 import java.nio.file.Path;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadRunnable.java b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadRunnable.java
index ae07760..e9198b2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadRunnable.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadRunnable.java
@@ -18,6 +18,7 @@
 import com.google.common.flogger.FluentLogger;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
 import java.util.List;
 
 public class AutoReloadRunnable implements Runnable {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadSecureCredentialsFactoryDecorator.java b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadSecureCredentialsFactoryDecorator.java
index 5bae0af..e9409a6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadSecureCredentialsFactoryDecorator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadSecureCredentialsFactoryDecorator.java
@@ -19,6 +19,7 @@
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.util.concurrent.atomic.AtomicReference;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/CreateProjectTask.java b/src/main/java/com/googlesource/gerrit/plugins/replication/CreateProjectTask.java
index 2436fee..00f8baf 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/CreateProjectTask.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/CreateProjectTask.java
@@ -20,7 +20,7 @@
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
-import com.googlesource.gerrit.plugins.replication.ReplicationConfig.FilterType;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig.FilterType;
 import java.util.Optional;
 import org.eclipse.jgit.transport.RemoteConfig;
 import org.eclipse.jgit.transport.URIish;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationsCollection.java b/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationsCollection.java
index 3854801..8a41945 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationsCollection.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationsCollection.java
@@ -35,7 +35,8 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.replication.ReplicationConfig.FilterType;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig.FilterType;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/FileConfigResource.java b/src/main/java/com/googlesource/gerrit/plugins/replication/FileConfigResource.java
index 7e19d2c..7a14cd1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/FileConfigResource.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/FileConfigResource.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.common.UsedAt.Project;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.replication.api.ConfigResource;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.List;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ListCommand.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ListCommand.java
index 9264d9b..8f4e0a1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ListCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ListCommand.java
@@ -23,7 +23,7 @@
 import com.google.gson.JsonObject;
 import com.google.gson.JsonPrimitive;
 import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.replication.ReplicationConfig.FilterType;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig.FilterType;
 import java.util.Collection;
 import java.util.List;
 import org.kohsuke.args4j.Option;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/MergedConfigResource.java b/src/main/java/com/googlesource/gerrit/plugins/replication/MergedConfigResource.java
index 399096a..5e8100b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/MergedConfigResource.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/MergedConfigResource.java
@@ -23,6 +23,8 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.util.Providers;
+import com.googlesource.gerrit.plugins.replication.api.ConfigResource;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfigOverrides;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Config;
 
@@ -30,20 +32,18 @@
   @VisibleForTesting
   @UsedAt(Project.PLUGIN_PULL_REPLICATION)
   public static MergedConfigResource withBaseOnly(ConfigResource base) {
-    return new MergedConfigResource(Providers.of(base), null);
+    MergedConfigResource mergedConfigResource = new MergedConfigResource();
+    mergedConfigResource.base = Providers.of(base);
+    return mergedConfigResource;
   }
 
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
-  private final Provider<ConfigResource> base;
-  @Nullable private final DynamicItem<ReplicationConfigOverrides> overrides;
+  @Inject private Provider<ConfigResource> base;
 
-  @Inject
-  MergedConfigResource(
-      Provider<ConfigResource> base, @Nullable DynamicItem<ReplicationConfigOverrides> overrides) {
-    this.base = base;
-    this.overrides = overrides;
-  }
+  @Inject(optional = true)
+  @Nullable
+  private DynamicItem<ReplicationConfigOverrides> overrides;
 
   public Config getConfig() {
     Config config = base.get().getConfig();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/OnStartStop.java b/src/main/java/com/googlesource/gerrit/plugins/replication/OnStartStop.java
index 8b0aa3d..fc80781 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/OnStartStop.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/OnStartStop.java
@@ -21,6 +21,7 @@
 import com.google.gerrit.server.events.EventDispatcher;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.replication.PushResultProcessing.GitUpdateProcessing;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
index a9f8154..9d152f6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/PushOne.java
@@ -54,6 +54,8 @@
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import com.googlesource.gerrit.plugins.replication.ReplicationState.RefPushResult;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationPushFilter;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigImpl.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigImpl.java
index 4f2def8..854ca6a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigImpl.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigImpl.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.server.config.ConfigUtil;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
 import java.nio.file.Path;
 import org.eclipse.jgit.lib.Config;
 
@@ -77,7 +78,7 @@
 
   /**
    * See {@link
-   * com.googlesource.gerrit.plugins.replication.ReplicationConfig#isReplicateAllOnPluginStart()}
+   * com.googlesource.gerrit.plugins.replication.api.ReplicationConfig#isReplicateAllOnPluginStart()}
    */
   @Override
   public boolean isReplicateAllOnPluginStart() {
@@ -86,7 +87,7 @@
 
   /**
    * See {@link
-   * com.googlesource.gerrit.plugins.replication.ReplicationConfig#isDefaultForceUpdate()}
+   * com.googlesource.gerrit.plugins.replication.api.ReplicationConfig#isDefaultForceUpdate()}
    */
   @Override
   public boolean isDefaultForceUpdate() {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigModule.java
index 3e37976..6a97432 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigModule.java
@@ -25,6 +25,8 @@
 import com.google.inject.Scopes;
 import com.google.inject.assistedinject.FactoryModuleBuilder;
 import com.google.inject.internal.UniqueAnnotations;
+import com.googlesource.gerrit.plugins.replication.api.ConfigResource;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
 import com.googlesource.gerrit.plugins.replication.events.ProjectDeletionState;
 import java.io.File;
 import java.io.IOException;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationDestinations.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationDestinations.java
index 78c1a35..bcc07e5 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationDestinations.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationDestinations.java
@@ -17,7 +17,7 @@
 import com.google.common.collect.Multimap;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.server.git.WorkQueue;
-import com.googlesource.gerrit.plugins.replication.ReplicationConfig.FilterType;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig.FilterType;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationExtensionPointModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationExtensionPointModule.java
index 29e254c..afbb54f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationExtensionPointModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationExtensionPointModule.java
@@ -15,6 +15,7 @@
 package com.googlesource.gerrit.plugins.replication;
 
 import com.google.inject.AbstractModule;
+import com.googlesource.gerrit.plugins.replication.api.ApiModule;
 
 /**
  * Gerrit libModule for applying a ref-filter for outgoing replications.
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
index 29c4950..666eb64 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
@@ -33,8 +33,9 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.googlesource.gerrit.plugins.replication.PushResultProcessing.GitUpdateProcessing;
-import com.googlesource.gerrit.plugins.replication.ReplicationConfig.FilterType;
 import com.googlesource.gerrit.plugins.replication.ReplicationTasksStorage.ReplicateRefUpdate;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig.FilterType;
 import com.googlesource.gerrit.plugins.replication.events.ProjectDeletionState;
 import java.net.URISyntaxException;
 import java.util.Collection;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationRemotesUpdater.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationRemotesUpdater.java
index 8c27ff6..a5e84d9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationRemotesUpdater.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationRemotesUpdater.java
@@ -23,6 +23,8 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.replication.api.ConfigResource;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfigOverrides;
 import java.io.IOException;
 import java.util.List;
 import org.eclipse.jgit.lib.Config;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorage.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorage.java
index 3f92983..aa711b6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorage.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationTasksStorage.java
@@ -33,6 +33,7 @@
 import com.google.inject.Inject;
 import com.google.inject.ProvisionException;
 import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.nio.file.Files;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/SshHelper.java b/src/main/java/com/googlesource/gerrit/plugins/replication/SshHelper.java
index d73c101..6f5ba1e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/SshHelper.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/SshHelper.java
@@ -16,6 +16,7 @@
 
 import com.google.inject.Inject;
 import com.google.inject.Provider;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
 import java.io.IOException;
 import java.io.OutputStream;
 import org.eclipse.jgit.errors.TransportException;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ApiModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/api/ApiModule.java
similarity index 94%
rename from src/main/java/com/googlesource/gerrit/plugins/replication/ApiModule.java
rename to src/main/java/com/googlesource/gerrit/plugins/replication/api/ApiModule.java
index b66e95e..3764ede 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ApiModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/api/ApiModule.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.googlesource.gerrit.plugins.replication;
+package com.googlesource.gerrit.plugins.replication.api;
 
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.inject.AbstractModule;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ConfigResource.java b/src/main/java/com/googlesource/gerrit/plugins/replication/api/ConfigResource.java
similarity index 97%
rename from src/main/java/com/googlesource/gerrit/plugins/replication/ConfigResource.java
rename to src/main/java/com/googlesource/gerrit/plugins/replication/api/ConfigResource.java
index c0a5a7d..68d59f6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ConfigResource.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/api/ConfigResource.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.googlesource.gerrit.plugins.replication;
+package com.googlesource.gerrit.plugins.replication.api;
 
 import java.io.IOException;
 import org.eclipse.jgit.lib.Config;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfig.java b/src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationConfig.java
similarity index 97%
rename from src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfig.java
rename to src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationConfig.java
index ec75450..8ef4e2b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationConfig.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.googlesource.gerrit.plugins.replication;
+package com.googlesource.gerrit.plugins.replication.api;
 
 import java.nio.file.Path;
 import org.eclipse.jgit.lib.Config;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigOverrides.java b/src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationConfigOverrides.java
similarity index 93%
rename from src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigOverrides.java
rename to src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationConfigOverrides.java
index 97a77bf..b6fbc1a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigOverrides.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationConfigOverrides.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.googlesource.gerrit.plugins.replication;
+package com.googlesource.gerrit.plugins.replication.api;
 
 /**
  * Provide a way to override or extend replication configuration from other sources, like git
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationPushFilter.java b/src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationPushFilter.java
similarity index 94%
rename from src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationPushFilter.java
rename to src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationPushFilter.java
index eb6ba90..afbdff6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationPushFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/api/ReplicationPushFilter.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.googlesource.gerrit.plugins.replication;
+package com.googlesource.gerrit.plugins.replication.api;
 
 import com.google.gerrit.extensions.annotations.ExtensionPoint;
 import java.util.List;
diff --git a/src/main/resources/Documentation/extension-point.md b/src/main/resources/Documentation/extension-point.md
index 8498829..fab5fbc 100644
--- a/src/main/resources/Documentation/extension-point.md
+++ b/src/main/resources/Documentation/extension-point.md
@@ -44,7 +44,25 @@
 ===================================
 
 The @PLUGIN@ plugin exposes _ApiModule_ that allows to provide _Cross Plugin
-Communication_.
+Communication_.  Extension points can be defined from the replication plugin when it is loaded
+as [ApiModule](../../../Documentation/dev-plugins.html#_cross_plugin_communication) and
+implemented by another plugin by declaring a `provided` dependency from the replication plugin api.
+
+Build the @plugin@'s API jar
+----------------------------
+
+The replication plugin's extension points are defined in the `c.g.g.p.r.a.ApiModule`
+that needs to be built from source and loaded in Gerrit as ApiModule.
+
+```
+$ bazelisk build plugins/replication:replication-api
+$ cp bazel-bin/plugins/replication/replication-api.jar $GERRIT_SITE/plugins
+```
+
+> **NOTE**: Use and configuration of the replication-api as ApiModule is compatible with
+> Gerrit v3.9 onwards and requires a Gerrit server restart; it does not support hot plugin install
+> or upgrade.
+
 
 Setup
 -----
@@ -62,7 +80,7 @@
 Exposed API
 -----------
 
-* `com.googlesource.gerrit.plugins.replication.ReplicationConfigOverrides`
+* `com.googlesource.gerrit.plugins.replication.api.ReplicationConfigOverrides`
 
   Override current replication configuration from external source (eg. git
   repository, ZooKeeper).
@@ -78,7 +96,7 @@
   DynamicItem.bind(binder(), ReplicationConfigOverrides.class).to(ReplicationConfigOverridesImpl.class);
   ```
 
-* `com.googlesource.gerrit.plugins.replication.ReplicationPushFilter`
+* `com.googlesource.gerrit.plugins.replication.api.ReplicationPushFilter`
 
   Filter out the ref updates pushed to a remote instance.
   Only one filter at a time is supported. Filter implementation needs to bind a `DynamicItem`.
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/AbstractConfigTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/AbstractConfigTest.java
index b2ea97a..b8bbc08 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/AbstractConfigTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/AbstractConfigTest.java
@@ -27,6 +27,8 @@
 import com.google.inject.Injector;
 import com.google.inject.Module;
 import com.google.inject.util.Providers;
+import com.googlesource.gerrit.plugins.replication.api.ConfigResource;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.List;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecoratorTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecoratorTest.java
index aa0d5f3..6facf25 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecoratorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecoratorTest.java
@@ -18,7 +18,8 @@
 
 import com.google.inject.Provider;
 import com.google.inject.util.Providers;
-import com.googlesource.gerrit.plugins.replication.ReplicationConfig.FilterType;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig.FilterType;
 import java.io.IOException;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/FanoutConfigResourceTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/FanoutConfigResourceTest.java
index 1cbe9a3..a622170 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/FanoutConfigResourceTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/FanoutConfigResourceTest.java
@@ -19,7 +19,7 @@
 import static com.googlesource.gerrit.plugins.replication.FanoutConfigResource.CONFIG_DIR;
 
 import com.google.common.io.MoreFiles;
-import com.googlesource.gerrit.plugins.replication.ReplicationConfig.FilterType;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig.FilterType;
 import java.io.File;
 import java.io.IOException;
 import java.util.List;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/FileConfigResourceTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/FileConfigResourceTest.java
index 9e8d36c..92bf58d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/FileConfigResourceTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/FileConfigResourceTest.java
@@ -19,6 +19,7 @@
 
 import com.google.common.io.MoreFiles;
 import com.google.gerrit.server.config.SitePaths;
+import com.googlesource.gerrit.plugins.replication.api.ConfigResource;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import org.eclipse.jgit.lib.Config;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/MergedConfigResourceTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/MergedConfigResourceTest.java
index c9ce2c5..cae78e3 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/MergedConfigResourceTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/MergedConfigResourceTest.java
@@ -19,6 +19,9 @@
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
+import com.googlesource.gerrit.plugins.replication.api.ApiModule;
+import com.googlesource.gerrit.plugins.replication.api.ConfigResource;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfigOverrides;
 import org.apache.commons.lang3.NotImplementedException;
 import org.eclipse.jgit.lib.Config;
 import org.junit.Test;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java
index 8664adc..4670dff 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/PushOneTest.java
@@ -39,6 +39,8 @@
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.gerrit.server.util.IdGenerator;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationPushFilter;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigImplTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigImplTest.java
index 068e5ff..993e408 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigImplTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationConfigImplTest.java
@@ -16,7 +16,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import com.googlesource.gerrit.plugins.replication.ReplicationConfig.FilterType;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig.FilterType;
 import java.io.IOException;
 import java.util.List;
 import org.eclipse.jgit.storage.file.FileBasedConfig;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationRemotesUpdaterTest.java b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationRemotesUpdaterTest.java
index 6e57ba7..bf566f2 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationRemotesUpdaterTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationRemotesUpdaterTest.java
@@ -27,6 +27,7 @@
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.securestore.SecureStore;
 import com.google.inject.util.Providers;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfigOverrides;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationStorageDaemon.java b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationStorageDaemon.java
index b6d14e8..a6ca305 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationStorageDaemon.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationStorageDaemon.java
@@ -16,6 +16,7 @@
 
 import static java.util.stream.Collectors.toList;
 
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationStorageIT.java b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationStorageIT.java
index 60fd708..e800cff 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationStorageIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/ReplicationStorageIT.java
@@ -23,8 +23,8 @@
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.api.projects.BranchInput;
 import com.googlesource.gerrit.plugins.replication.Destination.QueueInfo;
-import com.googlesource.gerrit.plugins.replication.ReplicationConfig.FilterType;
 import com.googlesource.gerrit.plugins.replication.ReplicationTasksStorage.ReplicateRefUpdate;
+import com.googlesource.gerrit.plugins.replication.api.ReplicationConfig.FilterType;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.nio.file.Files;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/replication/TestReplicationModule.java b/src/test/java/com/googlesource/gerrit/plugins/replication/TestReplicationModule.java
index ae2940e..a01a2cf 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/replication/TestReplicationModule.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/replication/TestReplicationModule.java
@@ -16,6 +16,7 @@
 
 import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.replication.api.ApiModule;
 
 public class TestReplicationModule extends AbstractModule {
   private final ReplicationModule replicationModule;