Merge branch 'stable-2.16' into stable-3.0

* stable-2.16:
  Fix NPE when removing refs

Change-Id: I008818c839a48a68e05b40879a444bb14a332b8f
diff --git a/BUILD b/BUILD
index 47182ab..99a5344 100644
--- a/BUILD
+++ b/BUILD
@@ -17,11 +17,9 @@
     ],
     resources = glob(["src/main/resources/**/*"]),
     deps = [
-        "@curator-client//jar",
-        "@curator-framework//jar",
-        "@curator-recipes//jar",
         "@kafka-client//jar",
-        "@zookeeper//jar",
+        "@global-refdb//jar",
+        "@events-broker//jar",
         "//plugins/replication",
     ],
 )
@@ -45,12 +43,11 @@
     visibility = ["//visibility:public"],
     exports = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
         ":multi-site__plugin",
-        "@curator-client//jar",
-        "@curator-framework//jar",
-        "@curator-test//jar",
-        "@mockito//jar",
-        "@testcontainers-kafka//jar",
         "@wiremock//jar",
+        "@kafka-client//jar",
+        "@testcontainers-kafka//jar",
         "//lib/testcontainers",
+        "@global-refdb//jar",
+        "@events-broker//jar",
     ],
 )
diff --git a/README.md b/README.md
index 49e96df..effcb75 100644
--- a/README.md
+++ b/README.md
@@ -78,6 +78,7 @@
 
 ```
 [gerrit]
+  installDbModule = com.googlesource.gerrit.plugins.multisite.GitModule
   installModule = com.googlesource.gerrit.plugins.multisite.Module
 ```
 
@@ -88,12 +89,6 @@
 [kafka]
   bootstrapServers = <kafka-host>:<kafka-port>
 
-[kafka "publisher"]
-  enabled = true
-
-[kafka "subscriber"]
-  enabled = true
-
 [ref-database]
   enabled = true
 
diff --git a/dockerised_local_env/gerrit-common/multi-site.config b/dockerised_local_env/gerrit-common/multi-site.config
index 04b9c2c..deec00f 100644
--- a/dockerised_local_env/gerrit-common/multi-site.config
+++ b/dockerised_local_env/gerrit-common/multi-site.config
@@ -12,14 +12,10 @@
 	cacheEventTopic = gerrit_cache_eviction
 
 [kafka "subscriber"]
-	enabled = true
 	pollingIntervalMs = 1000
 	KafkaProp-enableAutoCommit = true
 	KafkaProp-autoCommitIntervalMs = 1000
 	KafkaProp-autoOffsetReset = latest
 
-[kafka "publisher"]
-	enabled = true
-
 [ref-database "zookeeper"]
 	connectString = "zookeeper:2181"
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 369f6e0..6b60626 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -8,37 +8,6 @@
     )
 
     maven_jar(
-        name = "mockito",
-        artifact = "org.mockito:mockito-core:2.27.0",
-        sha1 = "835fc3283b481f4758b8ef464cd560c649c08b00",
-        deps = [
-            "@byte-buddy//jar",
-            "@byte-buddy-agent//jar",
-            "@objenesis//jar",
-        ],
-    )
-
-    BYTE_BUDDY_VER = "1.9.10"
-
-    maven_jar(
-        name = "byte-buddy",
-        artifact = "net.bytebuddy:byte-buddy:" + BYTE_BUDDY_VER,
-        sha1 = "211a2b4d3df1eeef2a6cacf78d74a1f725e7a840",
-    )
-
-    maven_jar(
-        name = "byte-buddy-agent",
-        artifact = "net.bytebuddy:byte-buddy-agent:" + BYTE_BUDDY_VER,
-        sha1 = "9674aba5ee793e54b864952b001166848da0f26b",
-    )
-
-    maven_jar(
-        name = "objenesis",
-        artifact = "org.objenesis:objenesis:2.6",
-        sha1 = "639033469776fd37c08358c6b92a4761feb2af4b",
-    )
-
-    maven_jar(
         name = "kafka-client",
         artifact = "org.apache.kafka:kafka-clients:2.1.0",
         sha1 = "34d9983705c953b97abb01e1cd04647f47272fe5",
@@ -50,34 +19,14 @@
         sha1 = "932d1baa2541f218b1b44a0546ae83d530011468",
     )
 
-    CURATOR_VER = "4.2.0"
-
     maven_jar(
-        name = "curator-test",
-        artifact = "org.apache.curator:curator-test:" + CURATOR_VER,
-        sha1 = "98ac2dd69b8c07dcaab5e5473f93fdb9e320cd73",
+        name = "global-refdb",
+        artifact = "com.gerritforge:global-refdb:0.1.1",
+        sha1 = "d6ab59906db7b20a52c8994502780b2a6ab23872",
     )
 
     maven_jar(
-        name = "curator-framework",
-        artifact = "org.apache.curator:curator-framework:" + CURATOR_VER,
-        sha1 = "5b1cc87e17b8fe4219b057f6025662a693538861",
-    )
-
-    maven_jar(
-        name = "curator-recipes",
-        artifact = "org.apache.curator:curator-recipes:" + CURATOR_VER,
-        sha1 = "7f775be5a7062c2477c51533b9d008f70411ba8e",
-    )
-
-    maven_jar(
-        name = "curator-client",
-        artifact = "org.apache.curator:curator-client:" + CURATOR_VER,
-        sha1 = "d5d50930b8dd189f92c40258a6ba97675fea3e15",
-    )
-
-    maven_jar(
-        name = "zookeeper",
-        artifact = "org.apache.zookeeper:zookeeper:3.4.14",
-        sha1 = "c114c1e1c8172a7cd3f6ae39209a635f7a06c1a1",
+        name = "events-broker",
+        artifact = "com.gerritforge:events-broker:3.0.0",
+        sha1 = "8957403a97df5400cf9bd49b3979049dde4b3435",
     )
diff --git a/setup_local_env/configs/gerrit.config b/setup_local_env/configs/gerrit.config
index 18eeca4..f0f56dc 100644
--- a/setup_local_env/configs/gerrit.config
+++ b/setup_local_env/configs/gerrit.config
@@ -3,7 +3,7 @@
     serverId = 69ec38f0-350e-4d9c-96d4-bc956f2faaac
     canonicalWebUrl = $GERRIT_CANONICAL_WEB_URL
     installModule = com.googlesource.gerrit.plugins.multisite.Module # multi-site needs to be a gerrit lib
-
+    installDbModule = com.googlesource.gerrit.plugins.multisite.GitModule
 [database]
     type = h2
     database = $LOCATION_TEST_SITE/db/ReviewDB
@@ -36,4 +36,4 @@
 [plugins]
     allowRemoteAdmin = true
 [plugin "websession-flatfile"]
-    directory = $FAKE_NFS
+    directory = $FAKE_NFS
\ No newline at end of file
diff --git a/setup_local_env/configs/multi-site.config b/setup_local_env/configs/multi-site.config
index ed9e6ad..5287f61 100644
--- a/setup_local_env/configs/multi-site.config
+++ b/setup_local_env/configs/multi-site.config
@@ -9,12 +9,9 @@
 	projectListEventTopic = gerrit_list_project
 	cacheEventTopic = gerrit_cache_eviction
 [kafka "subscriber"]
-	enabled = true
 	pollingIntervalMs = 1000
 	KafkaProp-enableAutoCommit = true
 	KafkaProp-autoCommitIntervalMs = 1000
 	KafkaProp-autoOffsetReset = latest
-[kafka "publisher"]
-	enabled = true
 [ref-database "zookeeper"]
 	connectString = localhost:$ZK_PORT
diff --git a/setup_local_env/configs/zookeeper.config b/setup_local_env/configs/zookeeper.config
new file mode 100644
index 0000000..2c84a05
--- /dev/null
+++ b/setup_local_env/configs/zookeeper.config
@@ -0,0 +1,2 @@
+[ref-database "zookeeper"]
+	connectString = localhost:$ZK_PORT
\ No newline at end of file
diff --git a/setup_local_env/setup.sh b/setup_local_env/setup.sh
index 23176fa..0b124a1 100755
--- a/setup_local_env/setup.sh
+++ b/setup_local_env/setup.sh
@@ -317,17 +317,22 @@
 	cp -f $MULTISITE_LIB_LOCATION $DEPLOYMENT_LOCATION/multi-site.jar  >/dev/null 2>&1 || { echo >&2 "$MULTISITE_LIB_LOCATION: Not able to copy the file. Aborting"; exit 1; }
 fi
 if [ $DOWNLOAD_WEBSESSION_FLATFILE = "true" ];then
-	echo "Downloading websession-flatfile plugin stable 2.16"
-	wget https://gerrit-ci.gerritforge.com/view/Plugins-stable-2.16/job/plugin-websession-flatfile-bazel-master-stable-2.16/lastSuccessfulBuild/artifact/bazel-bin/plugins/websession-flatfile/websession-flatfile.jar \
+	echo "Downloading websession-flatfile plugin stable 3.0"
+	wget https://gerrit-ci.gerritforge.com/view/Plugins-stable-3.0/job/plugin-websession-flatfile-bazel-master-stable-3.0/lastSuccessfulBuild/artifact/bazel-bin/plugins/websession-flatfile/websession-flatfile.jar \
 	-O $DEPLOYMENT_LOCATION/websession-flatfile.jar || { echo >&2 "Cannot download websession-flatfile plugin: Check internet connection. Abort\
 ing"; exit 1; }
-	wget https://gerrit-ci.gerritforge.com/view/Plugins-stable-2.16/job/plugin-healthcheck-bazel-stable-2.16/lastSuccessfulBuild/artifact/bazel-bin/plugins/healthcheck/healthcheck.jar \
+	wget https://gerrit-ci.gerritforge.com/view/Plugins-stable-3.0/job/plugin-healthcheck-bazel-stable-3.0/lastSuccessfulBuild/artifact/bazel-bin/plugins/healthcheck/healthcheck.jar \
 	-O $DEPLOYMENT_LOCATION/healthcheck.jar || { echo >&2 "Cannot download healthcheck plugin: Check internet connection. Abort\
 ing"; exit 1; }
 else
 	echo "Without the websession-flatfile; user login via haproxy will fail."
 fi
 
+echo "Downloading zookeeper plugin stable 3.0"
+	wget https://gerrit-ci.gerritforge.com/view/Plugins-stable-3.0/job/plugin-zookeeper-gh-bazel-stable-3.0/lastSuccessfulBuild/artifact/bazel-bin/plugins/zookeeper/zookeeper.jar \
+	-O $DEPLOYMENT_LOCATION/zookeeper.jar || { echo >&2 "Cannot download zookeeper plugin: Check internet connection. Abort\
+ing"; exit 1; }
+
 if [ "$REPLICATION_TYPE" = "ssh" ];then
 	echo "Using 'SSH' replication type"
 	echo "Make sure ~/.ssh/authorized_keys and ~/.ssh/known_hosts are configured correctly"
@@ -364,6 +369,9 @@
 	echo "Copy healthcheck plugin"
 	cp -f $DEPLOYMENT_LOCATION/healthcheck.jar $LOCATION_TEST_SITE_1/plugins/healthcheck.jar
 
+	echo "Copy zookeeper plugin"
+	cp -f $DEPLOYMENT_LOCATION/zookeeper.jar $LOCATION_TEST_SITE_1/plugins/zookeeper.jar
+
 	echo "Re-indexing"
 	java -jar $DEPLOYMENT_LOCATION/gerrit.war reindex -d $LOCATION_TEST_SITE_1
 	# Replicating environment
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
index ca01471..14c6be6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
@@ -49,7 +49,6 @@
   static final String INSTANCE_ID_FILE = "instanceId.data";
   static final String THREAD_POOL_SIZE_KEY = "threadPoolSize";
   static final int DEFAULT_THREAD_POOL_SIZE = 4;
-  static final String ENABLE_KEY = "enabled";
 
   private static final String REPLICATION_CONFIG = "replication.config";
   // common parameters to cache and index sections
@@ -162,6 +161,7 @@
 
   public static class SharedRefDatabase {
     public static final String SECTION = "ref-database";
+    public static final String ENABLE_KEY = "enabled";
     public static final String SUBSECTION_ENFORCEMENT_RULES = "enforcementRules";
 
     private final boolean enabled;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/GerritNoteDbStatus.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java
similarity index 64%
rename from src/main/java/com/googlesource/gerrit/plugins/multisite/GerritNoteDbStatus.java
rename to src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java
index ff932da..4f7205d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/GerritNoteDbStatus.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/GitModule.java
@@ -14,21 +14,22 @@
 
 package com.googlesource.gerrit.plugins.multisite;
 
-import com.google.gerrit.server.notedb.NotesMigration;
+import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
-import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.multisite.validation.ValidationModule;
 
-@Singleton
-public class GerritNoteDbStatus implements NoteDbStatus {
-  private final NotesMigration notesMigration;
+public class GitModule extends AbstractModule {
+  private final Configuration config;
 
   @Inject
-  public GerritNoteDbStatus(NotesMigration notesMigration) {
-    this.notesMigration = notesMigration;
+  public GitModule(Configuration config) {
+    this.config = config;
   }
 
   @Override
-  public boolean enabled() {
-    return notesMigration.commitChangeWrites();
+  protected void configure() {
+    if (config.getSharedRefDb().isEnabled()) {
+      install(new ValidationModule(config));
+    }
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jMessageLogger.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jMessageLogger.java
index db7dd63..8e94a51 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jMessageLogger.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jMessageLogger.java
@@ -14,12 +14,12 @@
 
 package com.googlesource.gerrit.plugins.multisite;
 
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.gerrit.extensions.systemstatus.ServerInformation;
 import com.google.gerrit.server.util.PluginLogFile;
 import com.google.gerrit.server.util.SystemLog;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
 import org.apache.log4j.PatternLayout;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jSharedRefLogger.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jSharedRefLogger.java
index 8830e19..4a844f7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jSharedRefLogger.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jSharedRefLogger.java
@@ -20,9 +20,9 @@
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.extensions.common.GitPerson;
+import com.google.gerrit.json.OutputFormat;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.CommonConverters;
-import com.google.gerrit.server.OutputFormat;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.util.SystemLog;
 import com.google.gson.Gson;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/MessageLogger.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/MessageLogger.java
index 8b07115..560d6f6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/MessageLogger.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/MessageLogger.java
@@ -14,7 +14,7 @@
 
 package com.googlesource.gerrit.plugins.multisite;
 
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 
 public interface MessageLogger {
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
index 5f4f635..9a8c4c4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
@@ -14,14 +14,15 @@
 
 package com.googlesource.gerrit.plugins.multisite;
 
-import com.google.common.annotations.VisibleForTesting;
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase;
+import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.lifecycle.LifecycleModule;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gson.Gson;
 import com.google.inject.CreationException;
 import com.google.inject.Inject;
 import com.google.inject.Provides;
-import com.google.inject.ProvisionException;
+import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.spi.Message;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerGson;
@@ -32,7 +33,7 @@
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderModule;
 import com.googlesource.gerrit.plugins.multisite.forwarder.router.RouterModule;
 import com.googlesource.gerrit.plugins.multisite.index.IndexModule;
-import com.googlesource.gerrit.plugins.multisite.validation.ValidationModule;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.NoopSharedRefDatabase;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.IOException;
@@ -47,44 +48,28 @@
 public class Module extends LifecycleModule {
   private static final Logger log = LoggerFactory.getLogger(Module.class);
   private Configuration config;
-  private NoteDbStatus noteDb;
   private BrokerModule brokerModule;
-  private final boolean disableGitRepositoryValidation;
 
   @Inject
-  public Module(Configuration config, NoteDbStatus noteDb, BrokerModule brokerModule) {
-    this(config, noteDb, brokerModule, false);
-  }
-
-  // TODO: It is not possible to properly test the libModules in Gerrit.
-  // Disable the Git repository validation during integration test and then build the necessary
-  // support
-  // in Gerrit for it.
-  @VisibleForTesting
-  public Module(
-      Configuration config,
-      NoteDbStatus noteDb,
-      BrokerModule brokerModule,
-      boolean disableGitRepositoryValidation) {
+  public Module(Configuration config, BrokerModule brokerModule) {
     this.config = config;
-    this.noteDb = noteDb;
     this.brokerModule = brokerModule;
-    this.disableGitRepositoryValidation = disableGitRepositoryValidation;
   }
 
   @Override
   protected void configure() {
-    if (!noteDb.enabled()) {
-      throw new ProvisionException(
-          "Gerrit is still running on ReviewDb: please migrate to NoteDb "
-              + "and then reload the multi-site plugin.");
-    }
 
     Collection<Message> validationErrors = config.validate();
     if (!validationErrors.isEmpty()) {
       throw new CreationException(validationErrors);
     }
 
+    DynamicItem.itemOf(binder(), GlobalRefDatabase.class);
+    DynamicItem.bind(binder(), GlobalRefDatabase.class)
+        .to(NoopSharedRefDatabase.class)
+        .in(Scopes.SINGLETON);
+    log.info("Shared ref-db engine: none");
+
     listener().to(Log4jMessageLogger.class);
     bind(MessageLogger.class).to(Log4jMessageLogger.class);
 
@@ -104,10 +89,6 @@
 
     install(new RouterModule());
 
-    install(
-        new ValidationModule(
-            config, disableGitRepositoryValidation || !config.getSharedRefDb().isEnabled()));
-
     bind(Gson.class)
         .annotatedWith(BrokerGson.class)
         .toProvider(GsonProvider.class)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/NoteDbStatus.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/NoteDbStatus.java
deleted file mode 100644
index f47e503..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/NoteDbStatus.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2019 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.multisite;
-
-import com.google.inject.ImplementedBy;
-
-/** Returns the status of changes migration. */
-@ImplementedBy(GerritNoteDbStatus.class)
-public interface NoteDbStatus {
-
-  /**
-   * Status of NoteDb migration.
-   *
-   * @return true if Gerrit has been migrated to NoteDb
-   */
-  boolean enabled();
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
index d445251..045c11e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2015 The Android Open Source Project
+// Copyright (C) 2019 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.
@@ -14,43 +14,36 @@
 
 package com.googlesource.gerrit.plugins.multisite;
 
-import com.google.common.flogger.FluentLogger;
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
+import com.google.gerrit.extensions.events.ProjectDeletedListener;
 import com.google.gerrit.extensions.registration.DynamicItem;
+import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.lifecycle.LifecycleModule;
 import com.google.inject.Inject;
 import com.google.inject.Scopes;
-import com.googlesource.gerrit.plugins.multisite.broker.BrokerApi;
 import com.googlesource.gerrit.plugins.multisite.kafka.KafkaBrokerApi;
 import com.googlesource.gerrit.plugins.multisite.kafka.KafkaBrokerModule;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.ZkValidationModule;
+import com.googlesource.gerrit.plugins.multisite.validation.ProjectDeletedSharedDbCleanup;
 
 public class PluginModule extends LifecycleModule {
-  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
   private Configuration config;
-  private ZkValidationModule zkValidationModule;
   private KafkaBrokerModule kafkaBrokerModule;
 
   @Inject
-  public PluginModule(
-      Configuration config,
-      ZkValidationModule zkValidationModule,
-      KafkaBrokerModule kafkaBrokerModule) {
+  public PluginModule(Configuration config, KafkaBrokerModule kafkaBrokerModule) {
     this.config = config;
-    this.zkValidationModule = zkValidationModule;
     this.kafkaBrokerModule = kafkaBrokerModule;
   }
 
   @Override
   protected void configure() {
     if (config.getSharedRefDb().isEnabled()) {
-      logger.atInfo().log("Shared ref-db engine: Zookeeper");
-      install(zkValidationModule);
+      listener().to(PluginStartup.class);
+      DynamicSet.bind(binder(), ProjectDeletedListener.class)
+          .to(ProjectDeletedSharedDbCleanup.class);
     }
-
     DynamicItem.bind(binder(), BrokerApi.class).to(KafkaBrokerApi.class).in(Scopes.SINGLETON);
     listener().to(KafkaBrokerApi.class);
-
     install(kafkaBrokerModule);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/GerritNoteDbStatus.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginStartup.java
similarity index 60%
copy from src/main/java/com/googlesource/gerrit/plugins/multisite/GerritNoteDbStatus.java
copy to src/main/java/com/googlesource/gerrit/plugins/multisite/PluginStartup.java
index ff932da..33b54d2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/GerritNoteDbStatus.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginStartup.java
@@ -14,21 +14,25 @@
 
 package com.googlesource.gerrit.plugins.multisite;
 
-import com.google.gerrit.server.notedb.NotesMigration;
+import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.inject.Inject;
-import com.google.inject.Singleton;
+import com.google.inject.Injector;
 
-@Singleton
-public class GerritNoteDbStatus implements NoteDbStatus {
-  private final NotesMigration notesMigration;
+public class PluginStartup implements LifecycleListener {
+  private SharedRefDatabaseWrapper sharedRefDb;
+  private Injector injector;
 
   @Inject
-  public GerritNoteDbStatus(NotesMigration notesMigration) {
-    this.notesMigration = notesMigration;
+  public PluginStartup(SharedRefDatabaseWrapper sharedRefDb, Injector injector) {
+    this.sharedRefDb = sharedRefDb;
+    this.injector = injector;
   }
 
   @Override
-  public boolean enabled() {
-    return notesMigration.commitChangeWrites();
+  public void start() {
+    injector.injectMembers(sharedRefDb);
   }
+
+  @Override
+  public void stop() {}
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
index e6ebc08..9d55e43 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
@@ -14,60 +14,70 @@
 
 package com.googlesource.gerrit.plugins.multisite;
 
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase;
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
+import com.google.common.annotations.VisibleForTesting;
 import com.google.gerrit.extensions.registration.DynamicItem;
+import com.google.gerrit.reviewdb.client.Project;
 import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedLockException;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
-import java.io.IOException;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Ref;
 
-public class SharedRefDatabaseWrapper implements SharedRefDatabase {
+public class SharedRefDatabaseWrapper implements GlobalRefDatabase {
 
-  private final DynamicItem<SharedRefDatabase> sharedRefDbDynamicItem;
+  @Inject(optional = true)
+  private DynamicItem<GlobalRefDatabase> sharedRefDbDynamicItem;
+
   private final SharedRefLogger sharedRefLogger;
 
   @Inject
-  public SharedRefDatabaseWrapper(
-      DynamicItem<SharedRefDatabase> sharedRefDbDynamicItem, SharedRefLogger sharedRefLogger) {
-    this.sharedRefDbDynamicItem = sharedRefDbDynamicItem;
+  public SharedRefDatabaseWrapper(SharedRefLogger sharedRefLogger) {
     this.sharedRefLogger = sharedRefLogger;
   }
 
+  @VisibleForTesting
+  public SharedRefDatabaseWrapper(
+      DynamicItem<GlobalRefDatabase> sharedRefDbDynamicItem, SharedRefLogger sharedRefLogger) {
+    this.sharedRefLogger = sharedRefLogger;
+    this.sharedRefDbDynamicItem = sharedRefDbDynamicItem;
+  }
+
   @Override
-  public boolean isUpToDate(String project, Ref ref) throws SharedLockException {
+  public boolean isUpToDate(Project.NameKey project, Ref ref) throws GlobalRefDbLockException {
     return sharedRefDb().isUpToDate(project, ref);
   }
 
   @Override
-  public boolean compareAndPut(String project, Ref currRef, ObjectId newRefValue)
-      throws IOException {
+  public boolean compareAndPut(Project.NameKey project, Ref currRef, ObjectId newRefValue)
+      throws GlobalRefDbSystemError {
     boolean succeeded = sharedRefDb().compareAndPut(project, currRef, newRefValue);
     if (succeeded) {
-      sharedRefLogger.logRefUpdate(project, currRef, newRefValue);
+      sharedRefLogger.logRefUpdate(project.get(), currRef, newRefValue);
     }
     return succeeded;
   }
 
   @Override
-  public AutoCloseable lockRef(String project, String refName) throws SharedLockException {
+  public AutoCloseable lockRef(Project.NameKey project, String refName)
+      throws GlobalRefDbLockException {
     AutoCloseable locker = sharedRefDb().lockRef(project, refName);
-    sharedRefLogger.logLockAcquisition(project, refName);
+    sharedRefLogger.logLockAcquisition(project.get(), refName);
     return locker;
   }
 
   @Override
-  public boolean exists(String project, String refName) {
+  public boolean exists(Project.NameKey project, String refName) {
     return sharedRefDb().exists(project, refName);
   }
 
   @Override
-  public void removeProject(String project) throws IOException {
-    sharedRefDb().removeProject(project);
-    sharedRefLogger.logProjectDelete(project);
+  public void remove(Project.NameKey project) throws GlobalRefDbSystemError {
+    sharedRefDb().remove(project);
+    sharedRefLogger.logProjectDelete(project.get());
   }
 
-  private SharedRefDatabase sharedRefDb() {
+  private GlobalRefDatabase sharedRefDb() {
     return sharedRefDbDynamicItem.get();
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/ZookeeperConfig.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/ZookeeperConfig.java
deleted file mode 100644
index 35471fa..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/ZookeeperConfig.java
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright (C) 2019 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.multisite;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Suppliers.memoize;
-import static com.google.common.base.Suppliers.ofInstance;
-
-import com.google.common.base.Strings;
-import com.google.common.base.Supplier;
-import com.google.gerrit.server.config.SitePaths;
-import java.io.IOException;
-import org.apache.commons.lang.StringUtils;
-import org.apache.curator.RetryPolicy;
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.CuratorFrameworkFactory;
-import org.apache.curator.retry.BoundedExponentialBackoffRetry;
-import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
-import org.eclipse.jgit.util.FS;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ZookeeperConfig {
-  private static final Logger log = LoggerFactory.getLogger(ZookeeperConfig.class);
-  public static final int defaultSessionTimeoutMs;
-  public static final int defaultConnectionTimeoutMs;
-  public static final String DEFAULT_ZK_CONNECT = "localhost:2181";
-  private final int DEFAULT_RETRY_POLICY_BASE_SLEEP_TIME_MS = 1000;
-  private final int DEFAULT_RETRY_POLICY_MAX_SLEEP_TIME_MS = 3000;
-  private final int DEFAULT_RETRY_POLICY_MAX_RETRIES = 3;
-  private final int DEFAULT_CAS_RETRY_POLICY_BASE_SLEEP_TIME_MS = 100;
-  private final int DEFAULT_CAS_RETRY_POLICY_MAX_SLEEP_TIME_MS = 300;
-  private final int DEFAULT_CAS_RETRY_POLICY_MAX_RETRIES = 3;
-  private final int DEFAULT_TRANSACTION_LOCK_TIMEOUT = 1000;
-
-  static {
-    CuratorFrameworkFactory.Builder b = CuratorFrameworkFactory.builder();
-    defaultSessionTimeoutMs = b.getSessionTimeoutMs();
-    defaultConnectionTimeoutMs = b.getConnectionTimeoutMs();
-  }
-
-  public static final String SUBSECTION = "zookeeper";
-  public static final String KEY_CONNECT_STRING = "connectString";
-  public static final String KEY_SESSION_TIMEOUT_MS = "sessionTimeoutMs";
-  public static final String KEY_CONNECTION_TIMEOUT_MS = "connectionTimeoutMs";
-  public static final String KEY_RETRY_POLICY_BASE_SLEEP_TIME_MS = "retryPolicyBaseSleepTimeMs";
-  public static final String KEY_RETRY_POLICY_MAX_SLEEP_TIME_MS = "retryPolicyMaxSleepTimeMs";
-  public static final String KEY_RETRY_POLICY_MAX_RETRIES = "retryPolicyMaxRetries";
-  public static final String KEY_ROOT_NODE = "rootNode";
-  public final String KEY_CAS_RETRY_POLICY_BASE_SLEEP_TIME_MS = "casRetryPolicyBaseSleepTimeMs";
-  public final String KEY_CAS_RETRY_POLICY_MAX_SLEEP_TIME_MS = "casRetryPolicyMaxSleepTimeMs";
-  public final String KEY_CAS_RETRY_POLICY_MAX_RETRIES = "casRetryPolicyMaxRetries";
-  public final String TRANSACTION_LOCK_TIMEOUT_KEY = "transactionLockTimeoutMs";
-
-  private final String connectionString;
-  private final String root;
-  private final int sessionTimeoutMs;
-  private final int connectionTimeoutMs;
-  private final int baseSleepTimeMs;
-  private final int maxSleepTimeMs;
-  private final int maxRetries;
-  private final int casBaseSleepTimeMs;
-  private final int casMaxSleepTimeMs;
-  private final int casMaxRetries;
-
-  public static final String SECTION = "ref-database";
-  private final Long transactionLockTimeOut;
-
-  private CuratorFramework build;
-
-  public ZookeeperConfig(Config zkCfg) {
-    Supplier<Config> lazyZkConfig = lazyLoad(zkCfg);
-    connectionString =
-        getString(lazyZkConfig, SECTION, SUBSECTION, KEY_CONNECT_STRING, DEFAULT_ZK_CONNECT);
-    root = getString(lazyZkConfig, SECTION, SUBSECTION, KEY_ROOT_NODE, "gerrit/multi-site");
-    sessionTimeoutMs =
-        getInt(lazyZkConfig, SECTION, SUBSECTION, KEY_SESSION_TIMEOUT_MS, defaultSessionTimeoutMs);
-    connectionTimeoutMs =
-        getInt(
-            lazyZkConfig,
-            SECTION,
-            SUBSECTION,
-            KEY_CONNECTION_TIMEOUT_MS,
-            defaultConnectionTimeoutMs);
-
-    baseSleepTimeMs =
-        getInt(
-            lazyZkConfig,
-            SECTION,
-            SUBSECTION,
-            KEY_RETRY_POLICY_BASE_SLEEP_TIME_MS,
-            DEFAULT_RETRY_POLICY_BASE_SLEEP_TIME_MS);
-
-    maxSleepTimeMs =
-        getInt(
-            lazyZkConfig,
-            SECTION,
-            SUBSECTION,
-            KEY_RETRY_POLICY_MAX_SLEEP_TIME_MS,
-            DEFAULT_RETRY_POLICY_MAX_SLEEP_TIME_MS);
-
-    maxRetries =
-        getInt(
-            lazyZkConfig,
-            SECTION,
-            SUBSECTION,
-            KEY_RETRY_POLICY_MAX_RETRIES,
-            DEFAULT_RETRY_POLICY_MAX_RETRIES);
-
-    casBaseSleepTimeMs =
-        getInt(
-            lazyZkConfig,
-            SECTION,
-            SUBSECTION,
-            KEY_CAS_RETRY_POLICY_BASE_SLEEP_TIME_MS,
-            DEFAULT_CAS_RETRY_POLICY_BASE_SLEEP_TIME_MS);
-
-    casMaxSleepTimeMs =
-        getInt(
-            lazyZkConfig,
-            SECTION,
-            SUBSECTION,
-            KEY_CAS_RETRY_POLICY_MAX_SLEEP_TIME_MS,
-            DEFAULT_CAS_RETRY_POLICY_MAX_SLEEP_TIME_MS);
-
-    casMaxRetries =
-        getInt(
-            lazyZkConfig,
-            SECTION,
-            SUBSECTION,
-            KEY_CAS_RETRY_POLICY_MAX_RETRIES,
-            DEFAULT_CAS_RETRY_POLICY_MAX_RETRIES);
-
-    transactionLockTimeOut =
-        getLong(
-            lazyZkConfig,
-            SECTION,
-            SUBSECTION,
-            TRANSACTION_LOCK_TIMEOUT_KEY,
-            DEFAULT_TRANSACTION_LOCK_TIMEOUT);
-
-    checkArgument(StringUtils.isNotEmpty(connectionString), "zookeeper.%s contains no servers");
-  }
-
-  public CuratorFramework buildCurator() {
-    if (build == null) {
-      this.build =
-          CuratorFrameworkFactory.builder()
-              .connectString(connectionString)
-              .sessionTimeoutMs(sessionTimeoutMs)
-              .connectionTimeoutMs(connectionTimeoutMs)
-              .retryPolicy(
-                  new BoundedExponentialBackoffRetry(baseSleepTimeMs, maxSleepTimeMs, maxRetries))
-              .namespace(root)
-              .build();
-      this.build.start();
-    }
-
-    return this.build;
-  }
-
-  public Long getZkInterProcessLockTimeOut() {
-    return transactionLockTimeOut;
-  }
-
-  public RetryPolicy buildCasRetryPolicy() {
-    return new BoundedExponentialBackoffRetry(casBaseSleepTimeMs, casMaxSleepTimeMs, casMaxRetries);
-  }
-
-  private static FileBasedConfig getConfigFile(SitePaths sitePaths, String configFileName) {
-    return new FileBasedConfig(sitePaths.etc_dir.resolve(configFileName).toFile(), FS.DETECTED);
-  }
-
-  private long getLong(
-      Supplier<Config> cfg, String section, String subSection, String name, long defaultValue) {
-    try {
-      return cfg.get().getLong(section, subSection, name, defaultValue);
-    } catch (IllegalArgumentException e) {
-      log.error("invalid value for {}; using default value {}", name, defaultValue);
-      log.debug("Failed to retrieve long value: {}", e.getMessage(), e);
-      return defaultValue;
-    }
-  }
-
-  private int getInt(
-      Supplier<Config> cfg, String section, String subSection, String name, int defaultValue) {
-    try {
-      return cfg.get().getInt(section, subSection, name, defaultValue);
-    } catch (IllegalArgumentException e) {
-      log.error("invalid value for {}; using default value {}", name, defaultValue);
-      log.debug("Failed to retrieve integer value: {}", e.getMessage(), e);
-      return defaultValue;
-    }
-  }
-
-  private Supplier<Config> lazyLoad(Config config) {
-    if (config instanceof FileBasedConfig) {
-      return memoize(
-          () -> {
-            FileBasedConfig fileConfig = (FileBasedConfig) config;
-            String fileConfigFileName = fileConfig.getFile().getPath();
-            try {
-              log.info("Loading configuration from {}", fileConfigFileName);
-              fileConfig.load();
-            } catch (IOException | ConfigInvalidException e) {
-              log.error("Unable to load configuration from " + fileConfigFileName, e);
-            }
-            return fileConfig;
-          });
-    }
-    return ofInstance(config);
-  }
-
-  private boolean getBoolean(
-      Supplier<Config> cfg, String section, String subsection, String name, boolean defaultValue) {
-    try {
-      return cfg.get().getBoolean(section, subsection, name, defaultValue);
-    } catch (IllegalArgumentException e) {
-      log.error("invalid value for {}; using default value {}", name, defaultValue);
-      log.debug("Failed to retrieve boolean value: {}", e.getMessage(), e);
-      return defaultValue;
-    }
-  }
-
-  private String getString(
-      Supplier<Config> cfg, String section, String subsection, String name, String defaultValue) {
-    String value = cfg.get().getString(section, subsection, name);
-    if (!Strings.isNullOrEmpty(value)) {
-      return value;
-    }
-    return defaultValue;
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApi.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApi.java
deleted file mode 100644
index 35350e9..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApi.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (C) 2019 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.multisite.broker;
-
-import com.google.gerrit.server.events.Event;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
-import java.util.function.Consumer;
-
-/** API for sending/receiving events through a message Broker. */
-public interface BrokerApi {
-
-  /**
-   * Send an event to a topic.
-   *
-   * @param topic
-   * @param event
-   * @return true if the event was successfully sent. False otherwise.
-   */
-  boolean send(String topic, Event event);
-
-  /**
-   * Receive asynchronously events from a topic.
-   *
-   * @param topic
-   * @param eventConsumer
-   */
-  void receiveAync(String topic, Consumer<SourceAwareEventWrapper> eventConsumer);
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiNoOp.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiNoOp.java
index 19cf0f7..d7a0429 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiNoOp.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiNoOp.java
@@ -14,8 +14,9 @@
 
 package com.googlesource.gerrit.plugins.multisite.broker;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.gerrit.server.events.Event;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
 import java.util.function.Consumer;
 
 public class BrokerApiNoOp implements BrokerApi {
@@ -26,5 +27,5 @@
   }
 
   @Override
-  public void receiveAync(String topic, Consumer<SourceAwareEventWrapper> eventConsumer) {}
+  public void receiveAsync(String topic, Consumer<SourceAwareEventWrapper> eventConsumer) {}
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiWrapper.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiWrapper.java
index e83fe53..9b84629 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiWrapper.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiWrapper.java
@@ -14,10 +14,11 @@
 
 package com.googlesource.gerrit.plugins.multisite.broker;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.server.events.Event;
 import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
 import java.util.function.Consumer;
 
 public class BrokerApiWrapper implements BrokerApi {
@@ -46,7 +47,7 @@
   }
 
   @Override
-  public void receiveAync(String topic, Consumer<SourceAwareEventWrapper> eventConsumer) {
-    apiDelegate.get().receiveAync(topic, eventConsumer);
+  public void receiveAsync(String topic, Consumer<SourceAwareEventWrapper> eventConsumer) {
+    apiDelegate.get().receiveAsync(topic, eventConsumer);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerModule.java
index 6983984..093b920 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerModule.java
@@ -14,6 +14,7 @@
 
 package com.googlesource.gerrit.plugins.multisite.broker;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.inject.AbstractModule;
 import com.google.inject.Scopes;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/kafka/BrokerPublisher.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/kafka/BrokerPublisher.java
index ba5b532..e1c8bf9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/kafka/BrokerPublisher.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/kafka/BrokerPublisher.java
@@ -14,6 +14,7 @@
 
 package com.googlesource.gerrit.plugins.multisite.broker.kafka;
 
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.server.events.Event;
@@ -26,7 +27,6 @@
 import com.googlesource.gerrit.plugins.multisite.MessageLogger.Direction;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerGson;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerSession;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
 import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
 import java.util.UUID;
 import org.slf4j.Logger;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/AbstractSubcriber.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/AbstractSubcriber.java
index 2308c0e..4591fff 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/AbstractSubcriber.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/AbstractSubcriber.java
@@ -14,15 +14,15 @@
 
 package com.googlesource.gerrit.plugins.multisite.consumer;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gson.Gson;
-import com.google.gwtorm.server.OrmException;
 import com.googlesource.gerrit.plugins.multisite.InstanceId;
 import com.googlesource.gerrit.plugins.multisite.MessageLogger;
 import com.googlesource.gerrit.plugins.multisite.MessageLogger.Direction;
-import com.googlesource.gerrit.plugins.multisite.broker.BrokerApi;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerGson;
 import com.googlesource.gerrit.plugins.multisite.forwarder.CacheNotFoundException;
@@ -61,7 +61,7 @@
 
   @Override
   public void run() {
-    brokerApi.receiveAync(getTopic().topic(), this::processRecord);
+    brokerApi.receiveAsync(getTopic().topic(), this::processRecord);
   }
 
   protected abstract EventTopic getTopic();
@@ -82,7 +82,7 @@
         logger.atSevere().withCause(e).log(
             "Malformed event '%s': [Exception: %s]", event.getHeader().getEventType());
         subscriberMetrics.incrementSubscriberFailedToConsumeMessage();
-      } catch (PermissionBackendException | OrmException | CacheNotFoundException e) {
+      } catch (PermissionBackendException | CacheNotFoundException e) {
         logger.atSevere().withCause(e).log(
             "Cannot handle message %s: [Exception: %s]", event.getHeader().getEventType());
         subscriberMetrics.incrementSubscriberFailedToConsumeMessage();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/DroppedEventListener.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/DroppedEventListener.java
index 680e8ed..80aee02 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/DroppedEventListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/DroppedEventListener.java
@@ -14,6 +14,8 @@
 
 package com.googlesource.gerrit.plugins.multisite.consumer;
 
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
+
 public interface DroppedEventListener {
   /**
    * Invoked when any event is dropped.
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/SourceAwareEventWrapper.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/SourceAwareEventWrapper.java
deleted file mode 100644
index b8bd0d8..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/SourceAwareEventWrapper.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (C) 2019 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.multisite.consumer;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.gerrit.server.events.Event;
-import com.google.gson.Gson;
-import com.google.gson.JsonObject;
-import java.util.UUID;
-
-public class SourceAwareEventWrapper {
-
-  private final EventHeader header;
-  private final JsonObject body;
-
-  public EventHeader getHeader() {
-    return header;
-  }
-
-  public JsonObject getBody() {
-    return body;
-  }
-
-  public Event getEventBody(Gson gson) {
-    return gson.fromJson(this.body, Event.class);
-  }
-
-  public static class EventHeader {
-    private final UUID eventId;
-    private final String eventType;
-    private final UUID sourceInstanceId;
-    private final Long eventCreatedOn;
-
-    public EventHeader(UUID eventId, String eventType, UUID sourceInstanceId, Long eventCreatedOn) {
-      this.eventId = eventId;
-      this.eventType = eventType;
-      this.sourceInstanceId = sourceInstanceId;
-      this.eventCreatedOn = eventCreatedOn;
-    }
-
-    public UUID getEventId() {
-      return eventId;
-    }
-
-    public String getEventType() {
-      return eventType;
-    }
-
-    public UUID getSourceInstanceId() {
-      return sourceInstanceId;
-    }
-
-    public Long getEventCreatedOn() {
-      return eventCreatedOn;
-    }
-
-    public void validate() {
-      requireNonNull(eventId, "EventId cannot be null");
-      requireNonNull(eventType, "EventType cannot be null");
-      requireNonNull(sourceInstanceId, "Source Instance ID cannot be null");
-    }
-
-    @Override
-    public String toString() {
-      return "{"
-          + "eventId="
-          + eventId
-          + ", eventType='"
-          + eventType
-          + '\''
-          + ", sourceInstanceId="
-          + sourceInstanceId
-          + ", eventCreatedOn="
-          + eventCreatedOn
-          + '}';
-    }
-  }
-
-  public SourceAwareEventWrapper(EventHeader header, JsonObject body) {
-    this.header = header;
-    this.body = body;
-  }
-
-  public void validate() {
-    requireNonNull(header, "Header cannot be null");
-    requireNonNull(body, "Body cannot be null");
-    header.validate();
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedAwareEventBroker.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedAwareEventBroker.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedAwareEventBroker.java
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedEventHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedEventHandler.java
index 85dab30..278ba4e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedEventHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedEventHandler.java
@@ -19,7 +19,6 @@
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.util.ManualRequestContext;
 import com.google.gerrit.server.util.OneOffRequestContext;
-import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import org.slf4j.Logger;
@@ -47,9 +46,8 @@
    * Dispatch an event in the local node, event will not be forwarded to the other node.
    *
    * @param event The event to dispatch
-   * @throws OrmException If an error occur while retrieving the change the event belongs to.
    */
-  public void dispatch(Event event) throws OrmException, PermissionBackendException {
+  public void dispatch(Event event) throws PermissionBackendException {
     try (ManualRequestContext ctx = oneOffCtx.open()) {
       Context.setForwardedEvent(true);
       log.debug("dispatching event {}", event.getType());
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexAccountHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexAccountHandler.java
index 29bfa44..31256b7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexAccountHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexAccountHandler.java
@@ -20,7 +20,6 @@
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.AccountIndexEvent;
-import java.io.IOException;
 import java.util.Optional;
 
 /**
@@ -41,7 +40,7 @@
   }
 
   @Override
-  protected void doIndex(Account.Id id, Optional<AccountIndexEvent> event) throws IOException {
+  protected void doIndex(Account.Id id, Optional<AccountIndexEvent> event) {
     indexer.index(id);
     log.debug("Account {} successfully indexed", id);
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexChangeHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexChangeHandler.java
index 1913b00..8340a5f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexChangeHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexChangeHandler.java
@@ -18,10 +18,8 @@
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.server.index.change.ChangeIndexer;
 import com.google.gerrit.server.notedb.ChangeNotes;
-import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.util.ManualRequestContext;
 import com.google.gerrit.server.util.OneOffRequestContext;
-import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.multisite.Configuration;
@@ -30,7 +28,6 @@
 import com.googlesource.gerrit.plugins.multisite.index.ChangeChecker;
 import com.googlesource.gerrit.plugins.multisite.index.ChangeCheckerImpl;
 import com.googlesource.gerrit.plugins.multisite.index.ForwardedIndexExecutor;
-import java.io.IOException;
 import java.util.Optional;
 import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
@@ -71,72 +68,48 @@
   }
 
   @Override
-  protected void doIndex(String id, Optional<ChangeIndexEvent> indexEvent)
-      throws IOException, OrmException {
+  protected void doIndex(String id, Optional<ChangeIndexEvent> indexEvent) {
     doIndex(id, indexEvent, 0);
   }
 
-  private void doIndex(String id, Optional<ChangeIndexEvent> indexEvent, int retryCount)
-      throws IOException, OrmException {
-    try {
-      ChangeChecker checker = changeCheckerFactory.create(id);
-      Optional<ChangeNotes> changeNotes = checker.getChangeNotes();
-      if (changeNotes.isPresent()) {
-        ChangeNotes notes = changeNotes.get();
-        reindex(notes);
+  private void doIndex(String id, Optional<ChangeIndexEvent> indexEvent, int retryCount) {
+    ChangeChecker checker = changeCheckerFactory.create(id);
+    Optional<ChangeNotes> changeNotes = checker.getChangeNotes();
+    if (changeNotes.isPresent()) {
+      ChangeNotes notes = changeNotes.get();
+      reindex(notes);
 
-        if (checker.isChangeUpToDate(indexEvent)) {
-          if (retryCount > 0) {
-            log.warn("Change {} has been eventually indexed after {} attempt(s)", id, retryCount);
-          } else {
-            log.debug("Change {} successfully indexed", id);
-          }
+      if (checker.isChangeUpToDate(indexEvent)) {
+        if (retryCount > 0) {
+          log.warn("Change {} has been eventually indexed after {} attempt(s)", id, retryCount);
         } else {
-          log.warn(
-              "Change {} seems too old compared to the event timestamp (event={} >> change-Ts={})",
-              id,
-              indexEvent,
-              checker);
-          rescheduleIndex(id, indexEvent, retryCount + 1);
+          log.debug("Change {} successfully indexed", id);
         }
       } else {
         log.warn(
-            "Change {} not present yet in local Git repository (event={}) after {} attempt(s)",
+            "Change {} seems too old compared to the event timestamp (event={} >> change-Ts={})",
             id,
             indexEvent,
-            retryCount);
-        if (!rescheduleIndex(id, indexEvent, retryCount + 1)) {
-          log.error(
-              "Change {} could not be found in the local Git repository (event={})",
-              id,
-              indexEvent);
-        }
+            checker);
+        rescheduleIndex(id, indexEvent, retryCount + 1);
       }
-    } catch (Exception e) {
-      if (isCausedByNoSuchChangeException(e)) {
-        indexer.delete(parseChangeId(id));
-        log.warn("Error trying to index Change {}. Deleted from index", id, e);
-        return;
+    } else {
+      log.warn(
+          "Change {} not present yet in local Git repository (event={}) after {} attempt(s)",
+          id,
+          indexEvent,
+          retryCount);
+      if (!rescheduleIndex(id, indexEvent, retryCount + 1)) {
+        log.error(
+            "Change {} could not be found in the local Git repository (event={})", id, indexEvent);
       }
-
-      throw e;
     }
   }
 
-  private static boolean isCausedByNoSuchChangeException(Throwable throwable) {
-    while (throwable != null) {
-      if (throwable instanceof NoSuchChangeException) {
-        return true;
-      }
-      throwable = throwable.getCause();
-    }
-    return false;
-  }
-
-  private void reindex(ChangeNotes notes) throws IOException, OrmException {
+  private void reindex(ChangeNotes notes) {
     try (ManualRequestContext ctx = oneOffCtx.open()) {
       notes.reload();
-      indexer.index(ctx.getReviewDbProvider().get(), notes.getChange());
+      indexer.index(notes.getChange());
     }
   }
 
@@ -172,7 +145,7 @@
   }
 
   @Override
-  protected void doDelete(String id, Optional<ChangeIndexEvent> indexEvent) throws IOException {
+  protected void doDelete(String id, Optional<ChangeIndexEvent> indexEvent) {
     indexer.delete(parseChangeId(id));
     log.debug("Change {} successfully deleted from index", id);
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexGroupHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexGroupHandler.java
index 76ce260..368dffe 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexGroupHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexGroupHandler.java
@@ -16,12 +16,10 @@
 
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.server.index.group.GroupIndexer;
-import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.GroupIndexEvent;
-import java.io.IOException;
 import java.util.Optional;
 
 /**
@@ -41,8 +39,7 @@
   }
 
   @Override
-  protected void doIndex(String uuid, Optional<GroupIndexEvent> event)
-      throws IOException, OrmException {
+  protected void doIndex(String uuid, Optional<GroupIndexEvent> event) {
     indexer.index(new AccountGroup.UUID(uuid));
     log.debug("Group {} successfully indexed", uuid);
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexProjectHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexProjectHandler.java
index ff2e111..e5f7e10 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexProjectHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexProjectHandler.java
@@ -22,7 +22,6 @@
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.ProjectIndexEvent;
 import com.googlesource.gerrit.plugins.multisite.index.ForwardedIndexExecutor;
 import com.googlesource.gerrit.plugins.multisite.index.ProjectChecker;
-import java.io.IOException;
 import java.util.Optional;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -58,15 +57,14 @@
   }
 
   @Override
-  protected void doIndex(String projectName, Optional<ProjectIndexEvent> event) throws IOException {
+  protected void doIndex(String projectName, Optional<ProjectIndexEvent> event) {
     if (!attemptIndex(projectName, event)) {
       log.warn("First Attempt failed, scheduling again after {} msecs", retryInterval);
       rescheduleIndex(projectName, event, 1);
     }
   }
 
-  public boolean attemptIndex(String projectName, Optional<ProjectIndexEvent> event)
-      throws IOException {
+  public boolean attemptIndex(String projectName, Optional<ProjectIndexEvent> event) {
     log.debug("Attempt to index project {}, event: [{}]", projectName, event);
     final Project.NameKey projectNameKey = new Project.NameKey(projectName);
     if (projectChecker.isProjectUpToDate(projectNameKey)) {
@@ -97,17 +95,13 @@
     indexExecutor.schedule(
         () -> {
           Context.setForwardedEvent(true);
-          try {
-            if (!attemptIndex(projectName, event)) {
-              log.warn(
-                  "Attempt {} to index project {} failed, scheduling again after {} msecs",
-                  retryCount,
-                  projectName,
-                  retryInterval);
-              rescheduleIndex(projectName, event, retryCount + 1);
-            }
-          } catch (IOException e) {
-            log.warn("Project {} could not be indexed", projectName, e);
+          if (!attemptIndex(projectName, event)) {
+            log.warn(
+                "Attempt {} to index project {} failed, scheduling again after {} msecs",
+                retryCount,
+                projectName,
+                retryInterval);
+            rescheduleIndex(projectName, event, retryCount + 1);
           }
         },
         retryInterval,
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexingHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexingHandler.java
index 67662f6..de6b836 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexingHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexingHandler.java
@@ -15,7 +15,6 @@
 package com.googlesource.gerrit.plugins.multisite.forwarder;
 
 import com.google.common.util.concurrent.Striped;
-import com.google.gwtorm.server.OrmException;
 import java.io.IOException;
 import java.util.Optional;
 import java.util.concurrent.locks.Lock;
@@ -43,9 +42,9 @@
 
   private final Striped<Lock> idLocks;
 
-  protected abstract void doIndex(T id, Optional<E> indexEvent) throws IOException, OrmException;
+  protected abstract void doIndex(T id, Optional<E> indexEvent);
 
-  protected abstract void doDelete(T id, Optional<E> indexEvent) throws IOException;
+  protected abstract void doDelete(T id, Optional<E> indexEvent);
 
   protected ForwardedIndexingHandler(int lockStripes) {
     idLocks = Striped.lock(lockStripes);
@@ -58,9 +57,8 @@
    * @param operation The operation to do; index or delete
    * @param event The index event details.
    * @throws IOException If an error occur while indexing.
-   * @throws OrmException If an error occur while retrieving a change related to the item to index
    */
-  public void index(T id, Operation operation, Optional<E> event) throws IOException, OrmException {
+  public void index(T id, Operation operation, Optional<E> event) throws IOException {
     log.debug("{} {} {}", operation, id, event);
     try {
       Context.setForwardedEvent(true);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerCacheEvictionForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerCacheEvictionForwarder.java
index dff21c1..dc64ced 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerCacheEvictionForwarder.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerCacheEvictionForwarder.java
@@ -14,9 +14,9 @@
 
 package com.googlesource.gerrit.plugins.multisite.forwarder.broker;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.multisite.broker.BrokerApi;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
 import com.googlesource.gerrit.plugins.multisite.forwarder.CacheEvictionForwarder;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.CacheEvictionEvent;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerIndexEventForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerIndexEventForwarder.java
index c2cc3dc..348af20 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerIndexEventForwarder.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerIndexEventForwarder.java
@@ -14,8 +14,8 @@
 
 package com.googlesource.gerrit.plugins.multisite.forwarder.broker;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
 import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.multisite.broker.BrokerApi;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
 import com.googlesource.gerrit.plugins.multisite.forwarder.IndexEventForwarder;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerProjectListUpdateForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerProjectListUpdateForwarder.java
index 1a8b652..12606e8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerProjectListUpdateForwarder.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerProjectListUpdateForwarder.java
@@ -16,9 +16,9 @@
 
 import static com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic.PROJECT_LIST_TOPIC;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.multisite.broker.BrokerApi;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ProjectListUpdateForwarder;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.ProjectListUpdateEvent;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerStreamEventForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerStreamEventForwarder.java
index ed3a717..05eeedd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerStreamEventForwarder.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerStreamEventForwarder.java
@@ -14,10 +14,10 @@
 
 package com.googlesource.gerrit.plugins.multisite.forwarder.broker;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
 import com.google.gerrit.server.events.Event;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.multisite.broker.BrokerApi;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
 import com.googlesource.gerrit.plugins.multisite.forwarder.StreamEventForwarder;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/EventTopic.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/EventTopic.java
index 7d42acc..371abae 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/EventTopic.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/EventTopic.java
@@ -36,10 +36,6 @@
     return aliasKey + "Topic";
   }
 
-  public String enabledKey() {
-    return aliasKey + "Enabled";
-  }
-
   public static EventTopic of(String topicString) {
     EventTopic[] topics = EventTopic.values();
     for (EventTopic topic : topics) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/ForwardedEventRouter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/ForwardedEventRouter.java
index 139020b..f9ad0c9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/ForwardedEventRouter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/ForwardedEventRouter.java
@@ -15,11 +15,10 @@
 package com.googlesource.gerrit.plugins.multisite.forwarder.router;
 
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gwtorm.server.OrmException;
 import com.googlesource.gerrit.plugins.multisite.forwarder.CacheNotFoundException;
 import java.io.IOException;
 
 public interface ForwardedEventRouter<EventType> {
   void route(EventType sourceEvent)
-      throws IOException, OrmException, PermissionBackendException, CacheNotFoundException;
+      throws IOException, PermissionBackendException, CacheNotFoundException;
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/IndexEventRouter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/IndexEventRouter.java
index 0103c38..3bd1142 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/IndexEventRouter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/IndexEventRouter.java
@@ -18,7 +18,6 @@
 import static com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler.Operation.INDEX;
 
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexAccountHandler;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexChangeHandler;
@@ -52,7 +51,7 @@
   }
 
   @Override
-  public void route(IndexEvent sourceEvent) throws IOException, OrmException {
+  public void route(IndexEvent sourceEvent) throws IOException {
     if (sourceEvent instanceof ChangeIndexEvent) {
       ChangeIndexEvent changeIndexEvent = (ChangeIndexEvent) sourceEvent;
       ForwardedIndexingHandler.Operation operation = changeIndexEvent.deleted ? DELETE : INDEX;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/StreamEventRouter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/StreamEventRouter.java
index 71edfb0..d911c00 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/StreamEventRouter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/StreamEventRouter.java
@@ -16,7 +16,6 @@
 
 import com.google.gerrit.server.events.Event;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedEventHandler;
 
@@ -29,7 +28,7 @@
   }
 
   @Override
-  public void route(Event sourceEvent) throws OrmException, PermissionBackendException {
+  public void route(Event sourceEvent) throws PermissionBackendException {
     streamEventHandler.dispatch(sourceEvent);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeChecker.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeChecker.java
index 1b0fea8..3646b3a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeChecker.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeChecker.java
@@ -15,7 +15,6 @@
 package com.googlesource.gerrit.plugins.multisite.index;
 
 import com.google.gerrit.server.notedb.ChangeNotes;
-import com.google.gwtorm.server.OrmException;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.ChangeIndexEvent;
 import java.io.IOException;
 import java.util.Optional;
@@ -27,9 +26,8 @@
    * Return the Change nodes read from ReviewDb or NoteDb.
    *
    * @return notes of the Change
-   * @throws OrmException if ReviewDb or NoteDb cannot be opened
    */
-  public Optional<ChangeNotes> getChangeNotes() throws OrmException;
+  public Optional<ChangeNotes> getChangeNotes();
 
   /**
    * Create a new index event POJO associated with the current Change.
@@ -40,21 +38,17 @@
    *     index
    * @return new IndexEvent
    * @throws IOException if the current Change cannot read
-   * @throws OrmException if ReviewDb cannot be opened
    */
   public Optional<ChangeIndexEvent> newIndexEvent(String projectName, int changeId, boolean deleted)
-      throws IOException, OrmException;
+      throws IOException;
 
   /**
    * Check if the local Change is aligned with the indexEvent received.
    *
    * @param indexEvent indexing event
    * @return true if the local Change is up-to-date, false otherwise.
-   * @throws IOException if an I/O error occurred while reading the local Change
-   * @throws OrmException if the local ReviewDb cannot be opened
    */
-  public boolean isChangeUpToDate(Optional<ChangeIndexEvent> indexEvent)
-      throws IOException, OrmException;
+  public boolean isChangeUpToDate(Optional<ChangeIndexEvent> indexEvent);
 
   /**
    * Return the last computed up-to-date Change time-stamp.
@@ -63,7 +57,6 @@
    *
    * @return the Change timestamp epoch in seconds
    * @throws IOException if an I/O error occurred while reading the local Change
-   * @throws OrmException if the local ReviewDb cannot be opened
    */
-  public Optional<Long> getComputedChangeTs() throws IOException, OrmException;
+  public Optional<Long> getComputedChangeTs() throws IOException;
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
index 8cb2fec..f1e80cc 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
@@ -14,16 +14,15 @@
 
 package com.googlesource.gerrit.plugins.multisite.index;
 
+import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Comment;
-import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CommentsUtil;
 import com.google.gerrit.server.change.ChangeFinder;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.util.ManualRequestContext;
 import com.google.gerrit.server.util.OneOffRequestContext;
-import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.ChangeIndexEvent;
@@ -66,7 +65,7 @@
 
   @Override
   public Optional<ChangeIndexEvent> newIndexEvent(String projectName, int changeId, boolean deleted)
-      throws IOException, OrmException {
+      throws IOException {
     return getComputedChangeTs()
         .map(
             ts -> {
@@ -78,7 +77,7 @@
   }
 
   @Override
-  public Optional<ChangeNotes> getChangeNotes() throws OrmException {
+  public Optional<ChangeNotes> getChangeNotes() {
     try (ManualRequestContext ctx = oneOffReqCtx.open()) {
       this.changeNotes = Optional.ofNullable(changeFinder.findOne(changeId));
       return changeNotes;
@@ -86,8 +85,7 @@
   }
 
   @Override
-  public boolean isChangeUpToDate(Optional<ChangeIndexEvent> indexEvent)
-      throws IOException, OrmException {
+  public boolean isChangeUpToDate(Optional<ChangeIndexEvent> indexEvent) {
     getComputedChangeTs();
     if (!computedChangeTs.isPresent()) {
       log.warn("Unable to compute last updated ts for change {}", changeId);
@@ -108,7 +106,7 @@
   }
 
   @Override
-  public Optional<Long> getComputedChangeTs() throws IOException, OrmException {
+  public Optional<Long> getComputedChangeTs() {
     if (!computedChangeTs.isPresent()) {
       computedChangeTs = computeLastChangeTs();
     }
@@ -117,17 +115,12 @@
 
   @Override
   public String toString() {
-    try {
-      return "change-id="
-          + changeId
-          + "@"
-          + getComputedChangeTs().map(ChangeIndexEvent::format)
-          + "/"
-          + getBranchTargetSha();
-    } catch (IOException | OrmException e) {
-      log.error("Unable to render change {}", changeId, e);
-      return "change-id=" + changeId;
-    }
+    return "change-id="
+        + changeId
+        + "@"
+        + getComputedChangeTs().map(ChangeIndexEvent::format)
+        + "/"
+        + getBranchTargetSha();
   }
 
   private String getBranchTargetSha() {
@@ -147,21 +140,19 @@
     }
   }
 
-  private Optional<Long> computeLastChangeTs() throws OrmException {
-    try (ReviewDb db = oneOffReqCtx.open().getReviewDbProvider().get()) {
-      return getChangeNotes().map(notes -> getTsFromChangeAndDraftComments(db, notes));
-    }
+  private Optional<Long> computeLastChangeTs() {
+    return getChangeNotes().map(notes -> getTsFromChangeAndDraftComments(notes));
   }
 
-  private long getTsFromChangeAndDraftComments(ReviewDb db, ChangeNotes notes) {
+  private long getTsFromChangeAndDraftComments(ChangeNotes notes) {
     Change change = notes.getChange();
     Timestamp changeTs = change.getLastUpdatedOn();
     try {
-      for (Comment comment : commentsUtil.draftByChange(db, changeNotes.get())) {
+      for (Comment comment : commentsUtil.draftByChange(changeNotes.get())) {
         Timestamp commentTs = comment.writtenOn;
         changeTs = commentTs.after(changeTs) ? commentTs : changeTs;
       }
-    } catch (OrmException e) {
+    } catch (StorageException e) {
       log.warn("Unable to access draft comments for change {}", change, e);
     }
     return changeTs.getTime() / 1000;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaBrokerApi.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaBrokerApi.java
index ff23b78..8dd853b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaBrokerApi.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaBrokerApi.java
@@ -14,13 +14,13 @@
 
 package com.googlesource.gerrit.plugins.multisite.kafka;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.server.events.Event;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-import com.googlesource.gerrit.plugins.multisite.broker.BrokerApi;
 import com.googlesource.gerrit.plugins.multisite.broker.kafka.BrokerPublisher;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
 import com.googlesource.gerrit.plugins.multisite.kafka.consumer.KafkaEventSubscriber;
 import java.util.ArrayList;
@@ -47,7 +47,7 @@
   }
 
   @Override
-  public void receiveAync(String topic, Consumer<SourceAwareEventWrapper> eventConsumer) {
+  public void receiveAsync(String topic, Consumer<SourceAwareEventWrapper> eventConsumer) {
     KafkaEventSubscriber subscriber = subscriberProvider.get();
     synchronized (subscribers) {
       subscribers.add(subscriber);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaBrokerModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaBrokerModule.java
index 5fdb07e..341f45d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaBrokerModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaBrokerModule.java
@@ -14,9 +14,9 @@
 
 package com.googlesource.gerrit.plugins.multisite.kafka;
 
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.lifecycle.LifecycleModule;
-import com.google.inject.Inject;
 import com.google.inject.TypeLiteral;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerSession;
 import com.googlesource.gerrit.plugins.multisite.broker.kafka.BrokerPublisher;
@@ -25,7 +25,6 @@
 import com.googlesource.gerrit.plugins.multisite.consumer.CacheEvictionEventSubscriber;
 import com.googlesource.gerrit.plugins.multisite.consumer.IndexEventSubscriber;
 import com.googlesource.gerrit.plugins.multisite.consumer.ProjectUpdateEventSubscriber;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
 import com.googlesource.gerrit.plugins.multisite.consumer.StreamEventSubscriber;
 import com.googlesource.gerrit.plugins.multisite.forwarder.CacheEvictionForwarder;
 import com.googlesource.gerrit.plugins.multisite.forwarder.IndexEventForwarder;
@@ -35,58 +34,30 @@
 import com.googlesource.gerrit.plugins.multisite.forwarder.broker.BrokerIndexEventForwarder;
 import com.googlesource.gerrit.plugins.multisite.forwarder.broker.BrokerProjectListUpdateForwarder;
 import com.googlesource.gerrit.plugins.multisite.forwarder.broker.BrokerStreamEventForwarder;
-import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
 import com.googlesource.gerrit.plugins.multisite.kafka.consumer.KafkaEventDeserializer;
 import org.apache.kafka.common.serialization.ByteArrayDeserializer;
 import org.apache.kafka.common.serialization.Deserializer;
 
 public class KafkaBrokerModule extends LifecycleModule {
-  private KafkaConfiguration config;
-
-  @Inject
-  public KafkaBrokerModule(KafkaConfiguration config) {
-    this.config = config;
-  }
 
   @Override
   protected void configure() {
-    if (config.kafkaSubscriber().enabled()) {
-      bind(new TypeLiteral<Deserializer<byte[]>>() {}).toInstance(new ByteArrayDeserializer());
-      bind(new TypeLiteral<Deserializer<SourceAwareEventWrapper>>() {})
-          .to(KafkaEventDeserializer.class);
+    bind(new TypeLiteral<Deserializer<byte[]>>() {}).toInstance(new ByteArrayDeserializer());
+    bind(new TypeLiteral<Deserializer<SourceAwareEventWrapper>>() {})
+        .to(KafkaEventDeserializer.class);
 
-      if (config.kafkaSubscriber().enabledEvent(EventTopic.INDEX_TOPIC)) {
-        DynamicSet.bind(binder(), AbstractSubcriber.class).to(IndexEventSubscriber.class);
-      }
-      if (config.kafkaSubscriber().enabledEvent(EventTopic.STREAM_EVENT_TOPIC)) {
-        DynamicSet.bind(binder(), AbstractSubcriber.class).to(StreamEventSubscriber.class);
-      }
-      if (config.kafkaSubscriber().enabledEvent(EventTopic.CACHE_TOPIC)) {
-        DynamicSet.bind(binder(), AbstractSubcriber.class).to(CacheEvictionEventSubscriber.class);
-      }
-      if (config.kafkaSubscriber().enabledEvent(EventTopic.PROJECT_LIST_TOPIC)) {
-        DynamicSet.bind(binder(), AbstractSubcriber.class).to(ProjectUpdateEventSubscriber.class);
-      }
-    }
+    DynamicSet.bind(binder(), AbstractSubcriber.class).to(IndexEventSubscriber.class);
+    DynamicSet.bind(binder(), AbstractSubcriber.class).to(StreamEventSubscriber.class);
+    DynamicSet.bind(binder(), AbstractSubcriber.class).to(CacheEvictionEventSubscriber.class);
+    DynamicSet.bind(binder(), AbstractSubcriber.class).to(ProjectUpdateEventSubscriber.class);
 
-    if (config.kafkaPublisher().enabled()) {
-      listener().to(BrokerPublisher.class);
-      bind(BrokerSession.class).to(KafkaSession.class);
+    listener().to(BrokerPublisher.class);
+    bind(BrokerSession.class).to(KafkaSession.class);
 
-      if (config.kafkaPublisher().enabledEvent(EventTopic.INDEX_TOPIC)) {
-        DynamicSet.bind(binder(), IndexEventForwarder.class).to(BrokerIndexEventForwarder.class);
-      }
-      if (config.kafkaPublisher().enabledEvent(EventTopic.CACHE_TOPIC)) {
-        DynamicSet.bind(binder(), CacheEvictionForwarder.class)
-            .to(BrokerCacheEvictionForwarder.class);
-      }
-      if (config.kafkaPublisher().enabledEvent(EventTopic.PROJECT_LIST_TOPIC)) {
-        DynamicSet.bind(binder(), ProjectListUpdateForwarder.class)
-            .to(BrokerProjectListUpdateForwarder.class);
-      }
-      if (config.kafkaPublisher().enabledEvent(EventTopic.STREAM_EVENT_TOPIC)) {
-        DynamicSet.bind(binder(), StreamEventForwarder.class).to(BrokerStreamEventForwarder.class);
-      }
-    }
+    DynamicSet.bind(binder(), IndexEventForwarder.class).to(BrokerIndexEventForwarder.class);
+    DynamicSet.bind(binder(), CacheEvictionForwarder.class).to(BrokerCacheEvictionForwarder.class);
+    DynamicSet.bind(binder(), ProjectListUpdateForwarder.class)
+        .to(BrokerProjectListUpdateForwarder.class);
+    DynamicSet.bind(binder(), StreamEventForwarder.class).to(BrokerStreamEventForwarder.class);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaConfiguration.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaConfiguration.java
index dee7382..0857334 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaConfiguration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaConfiguration.java
@@ -15,24 +15,21 @@
 package com.googlesource.gerrit.plugins.multisite.kafka;
 
 import static com.google.common.base.Suppliers.memoize;
-import static com.google.common.base.Suppliers.ofInstance;
 
 import com.google.common.base.CaseFormat;
 import com.google.common.base.Strings;
 import com.google.common.base.Supplier;
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
-import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 import java.util.UUID;
 import org.apache.kafka.common.serialization.StringSerializer;
-import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -42,9 +39,7 @@
   private static final Logger log = LoggerFactory.getLogger(KafkaConfiguration.class);
   static final String KAFKA_PROPERTY_PREFIX = "KafkaProp-";
   static final String KAFKA_SECTION = "kafka";
-  static final String ENABLE_KEY = "enabled";
   private static final String DEFAULT_KAFKA_BOOTSTRAP_SERVERS = "localhost:9092";
-  private static final boolean DEFAULT_ENABLE_PROCESSING = true;
   private static final int DEFAULT_POLLING_INTERVAL_MS = 1000;
 
   private final Supplier<KafkaSubscriber> subscriber;
@@ -52,11 +47,11 @@
   private final Supplier<KafkaPublisher> publisher;
 
   @Inject
-  public KafkaConfiguration(Configuration configuration) {
-    Supplier<Config> lazyCfg = lazyLoad(configuration.getMultiSiteConfig());
-    kafka = memoize(() -> new Kafka(lazyCfg));
-    publisher = memoize(() -> new KafkaPublisher(lazyCfg));
-    subscriber = memoize(() -> new KafkaSubscriber(lazyCfg));
+  public KafkaConfiguration(PluginConfigFactory configFactory, @PluginName String pluginName) {
+    Config cfg = configFactory.getGlobalPluginConfig(pluginName);
+    kafka = memoize(() -> new Kafka(cfg));
+    publisher = memoize(() -> new KafkaPublisher(cfg));
+    subscriber = memoize(() -> new KafkaSubscriber(cfg));
   }
 
   public Kafka getKafka() {
@@ -67,9 +62,7 @@
     return subscriber.get();
   }
 
-  private static void applyKafkaConfig(
-      Supplier<Config> configSupplier, String subsectionName, Properties target) {
-    Config config = configSupplier.get();
+  private static void applyKafkaConfig(Config config, String subsectionName, Properties target) {
     for (String section : config.getSubsections(KAFKA_SECTION)) {
       if (section.equals(subsectionName)) {
         for (String name : config.getNames(KAFKA_SECTION, section, true)) {
@@ -89,63 +82,27 @@
     target.put(
         "bootstrap.servers",
         getString(
-            configSupplier,
-            KAFKA_SECTION,
-            null,
-            "bootstrapServers",
-            DEFAULT_KAFKA_BOOTSTRAP_SERVERS));
+            config, KAFKA_SECTION, null, "bootstrapServers", DEFAULT_KAFKA_BOOTSTRAP_SERVERS));
   }
 
   private static String getString(
-      Supplier<Config> cfg, String section, String subsection, String name, String defaultValue) {
-    String value = cfg.get().getString(section, subsection, name);
+      Config cfg, String section, String subsection, String name, String defaultValue) {
+    String value = cfg.getString(section, subsection, name);
     if (!Strings.isNullOrEmpty(value)) {
       return value;
     }
     return defaultValue;
   }
 
-  private static Map<EventTopic, Boolean> eventsEnabled(
-      Supplier<Config> config, String subsection) {
-    Map<EventTopic, Boolean> eventsEnabled = new HashMap<>();
-    for (EventTopic topic : EventTopic.values()) {
-      eventsEnabled.put(
-          topic,
-          config
-              .get()
-              .getBoolean(
-                  KAFKA_SECTION, subsection, topic.enabledKey(), DEFAULT_ENABLE_PROCESSING));
-    }
-    return eventsEnabled;
-  }
-
   public KafkaPublisher kafkaPublisher() {
     return publisher.get();
   }
 
-  private Supplier<Config> lazyLoad(Config config) {
-    if (config instanceof FileBasedConfig) {
-      return memoize(
-          () -> {
-            FileBasedConfig fileConfig = (FileBasedConfig) config;
-            String fileConfigFileName = fileConfig.getFile().getPath();
-            try {
-              log.info("Loading configuration from {}", fileConfigFileName);
-              fileConfig.load();
-            } catch (IOException | ConfigInvalidException e) {
-              log.error("Unable to load configuration from " + fileConfigFileName, e);
-            }
-            return fileConfig;
-          });
-    }
-    return ofInstance(config);
-  }
-
   public static class Kafka {
     private final Map<EventTopic, String> eventTopics;
     private final String bootstrapServers;
 
-    Kafka(Supplier<Config> config) {
+    Kafka(Config config) {
       this.bootstrapServers =
           getString(
               config, KAFKA_SECTION, null, "bootstrapServers", DEFAULT_KAFKA_BOOTSTRAP_SERVERS);
@@ -167,8 +124,8 @@
     }
 
     private static String getString(
-        Supplier<Config> cfg, String section, String subsection, String name, String defaultValue) {
-      String value = cfg.get().getString(section, subsection, name);
+        Config cfg, String section, String subsection, String name, String defaultValue) {
+      String value = cfg.getString(section, subsection, name);
       if (!Strings.isNullOrEmpty(value)) {
         return value;
       }
@@ -180,25 +137,11 @@
     private static final long serialVersionUID = 0L;
 
     public static final String KAFKA_STRING_SERIALIZER = StringSerializer.class.getName();
-
     public static final String KAFKA_PUBLISHER_SUBSECTION = "publisher";
-    public static final boolean DEFAULT_BROKER_ENABLED = false;
 
-    private final boolean enabled;
-    private final Map<EventTopic, Boolean> eventsEnabled;
-
-    private KafkaPublisher(Supplier<Config> cfg) {
-      enabled =
-          cfg.get()
-              .getBoolean(
-                  KAFKA_SECTION, KAFKA_PUBLISHER_SUBSECTION, ENABLE_KEY, DEFAULT_BROKER_ENABLED);
-
-      eventsEnabled = eventsEnabled(cfg, KAFKA_PUBLISHER_SUBSECTION);
-
-      if (enabled) {
-        setDefaults();
-        applyKafkaConfig(cfg, KAFKA_PUBLISHER_SUBSECTION, this);
-      }
+    private KafkaPublisher(Config kafkaConfig) {
+      setDefaults();
+      applyKafkaConfig(kafkaConfig, KAFKA_PUBLISHER_SUBSECTION, this);
     }
 
     private void setDefaults() {
@@ -211,14 +154,6 @@
       put("value.serializer", KAFKA_STRING_SERIALIZER);
       put("reconnect.backoff.ms", 5000L);
     }
-
-    public boolean enabled() {
-      return enabled;
-    }
-
-    public boolean enabledEvent(EventTopic eventType) {
-      return eventsEnabled.get(eventType);
-    }
   }
 
   public static class KafkaSubscriber extends Properties {
@@ -226,13 +161,11 @@
 
     static final String KAFKA_SUBSCRIBER_SUBSECTION = "subscriber";
 
-    private final boolean enabled;
     private final Integer pollingInterval;
-    private Map<EventTopic, Boolean> eventsEnabled;
     private final Config cfg;
 
-    public KafkaSubscriber(Supplier<Config> configSupplier) {
-      this.cfg = configSupplier.get();
+    public KafkaSubscriber(Config kafkaCfg) {
+      this.cfg = kafkaCfg;
 
       this.pollingInterval =
           cfg.getInt(
@@ -241,21 +174,7 @@
               "pollingIntervalMs",
               DEFAULT_POLLING_INTERVAL_MS);
 
-      enabled = cfg.getBoolean(KAFKA_SECTION, KAFKA_SUBSCRIBER_SUBSECTION, ENABLE_KEY, false);
-
-      eventsEnabled = eventsEnabled(configSupplier, KAFKA_SUBSCRIBER_SUBSECTION);
-
-      if (enabled) {
-        applyKafkaConfig(configSupplier, KAFKA_SUBSCRIBER_SUBSECTION, this);
-      }
-    }
-
-    public boolean enabled() {
-      return enabled;
-    }
-
-    public boolean enabledEvent(EventTopic topic) {
-      return eventsEnabled.get(topic);
+      applyKafkaConfig(kafkaCfg, KAFKA_SUBSCRIBER_SUBSECTION, this);
     }
 
     public Properties initPropsWith(UUID instanceId) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventDeserializer.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventDeserializer.java
index 38b8d61..7b3be66 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventDeserializer.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventDeserializer.java
@@ -14,11 +14,11 @@
 
 package com.googlesource.gerrit.plugins.multisite.kafka.consumer;
 
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.gson.Gson;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerGson;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
 import java.util.Map;
 import org.apache.kafka.common.serialization.Deserializer;
 import org.apache.kafka.common.serialization.StringDeserializer;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventSubscriber.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventSubscriber.java
index c72fa0d..69d7d47 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventSubscriber.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventSubscriber.java
@@ -15,12 +15,12 @@
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.server.util.ManualRequestContext;
 import com.google.gerrit.server.util.OneOffRequestContext;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.multisite.InstanceId;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
 import com.googlesource.gerrit.plugins.multisite.consumer.SubscriberMetrics;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
 import com.googlesource.gerrit.plugins.multisite.kafka.KafkaConfiguration;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
index 4e6bef5..932f0c4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
@@ -19,7 +19,6 @@
 import com.google.inject.assistedinject.Assisted;
 import com.googlesource.gerrit.plugins.multisite.LockWrapper;
 import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
 import java.io.IOException;
@@ -29,6 +28,8 @@
 import java.util.stream.Stream;
 import org.eclipse.jgit.lib.BatchRefUpdate;
 import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.RefDatabase;
 import org.eclipse.jgit.transport.ReceiveCommand;
 
@@ -124,7 +125,7 @@
     try {
       switch (command.getType()) {
         case CREATE:
-          return new RefPair(SharedRefDatabase.nullRef(command.getRefName()), getNewRef(command));
+          return new RefPair(nullRef(command.getRefName()), getNewRef(command));
 
         case UPDATE:
         case UPDATE_NONFASTFORWARD:
@@ -155,4 +156,8 @@
     }
     return latestRefsToUpdate;
   }
+
+  private static final Ref nullRef(String refName) {
+    return new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, refName, ObjectId.zeroId());
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabase.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabase.java
index 630b091..e1d1c65 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabase.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabase.java
@@ -99,11 +99,6 @@
   }
 
   @Override
-  public Ref getRef(String name) throws IOException {
-    return refDatabase.getRef(name);
-  }
-
-  @Override
   public String toString() {
     return refDatabase.toString();
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationPushFilter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationPushFilter.java
index 5f25607..42f7194 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationPushFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/MultisiteReplicationPushFilter.java
@@ -14,16 +14,18 @@
 
 package com.googlesource.gerrit.plugins.multisite.validation;
 
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
+import com.google.gerrit.reviewdb.client.Project;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedLockException;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
 import com.googlesource.gerrit.plugins.replication.ReplicationPushFilter;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
+import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.transport.RemoteRefUpdate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -52,13 +54,15 @@
                   String ref = refUpdate.getSrcRef();
                   try {
                     if (sharedRefDb.isUpToDate(
-                        projectName, SharedRefDatabase.newRef(ref, refUpdate.getNewObjectId()))) {
+                        new Project.NameKey(projectName),
+                        new ObjectIdRef.Unpeeled(
+                            Ref.Storage.NETWORK, ref, refUpdate.getNewObjectId()))) {
                       return true;
                     }
                     repLog.warn(
                         "{} is not up-to-date with the shared-refdb and thus will NOT BE replicated",
                         refUpdate);
-                  } catch (SharedLockException e) {
+                  } catch (GlobalRefDbLockException e) {
                     repLog.warn(
                         "{} is locked on shared-refdb and thus will NOT BE replicated", refUpdate);
                   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanup.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanup.java
index 78e1cea..9c93793 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanup.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanup.java
@@ -14,11 +14,12 @@
 
 package com.googlesource.gerrit.plugins.multisite.validation;
 
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.extensions.events.ProjectDeletedListener;
+import com.google.gerrit.reviewdb.client.Project;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import java.io.IOException;
 
 public class ProjectDeletedSharedDbCleanup implements ProjectDeletedListener {
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -41,8 +42,8 @@
         "Deleting project '%s'. Will perform a cleanup in Shared-Ref database.", projectName);
 
     try {
-      sharedDb.removeProject(projectName);
-    } catch (IOException e) {
+      sharedDb.remove(new Project.NameKey(projectName));
+    } catch (GlobalRefDbSystemError e) {
       validationMetrics.incrementSplitBrain();
       logger.atSevere().withCause(e).log(
           "Project '%s' deleted from GIT but it was not able to cleanup"
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
index 82d4ff0..a63c00b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
@@ -14,10 +14,10 @@
 
 package com.googlesource.gerrit.plugins.multisite.validation;
 
-import static com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase.nullRef;
-
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
 import com.google.common.base.MoreObjects;
 import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.reviewdb.client.Project;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 import com.googlesource.gerrit.plugins.multisite.LockWrapper;
@@ -25,12 +25,12 @@
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.OutOfSyncException;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedDbSplitBrainException;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedLockException;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
 import java.io.IOException;
 import java.util.HashMap;
 import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.RefDatabase;
 import org.eclipse.jgit.lib.RefUpdate;
@@ -144,8 +144,10 @@
             projectName, refPair.getName(), refPair.putValue);
     boolean succeeded;
     try {
-      succeeded = sharedRefDb.compareAndPut(projectName, refPair.compareRef, refPair.putValue);
-    } catch (IOException e) {
+      succeeded =
+          sharedRefDb.compareAndPut(
+              new Project.NameKey(projectName), refPair.compareRef, refPair.putValue);
+    } catch (GlobalRefDbSystemError e) {
       throw new SharedDbSplitBrainException(errorMessage, e);
     }
 
@@ -166,14 +168,17 @@
         String.format("%s-%s", projectName, refName),
         () ->
             lockWrapperFactory.create(
-                projectName, refName, sharedRefDb.lockRef(projectName, refName)));
+                projectName,
+                refName,
+                sharedRefDb.lockRef(new Project.NameKey(projectName), refName)));
 
     RefPair latestRefPair = getLatestLocalRef(refPair);
-    if (sharedRefDb.isUpToDate(projectName, latestRefPair.compareRef)) {
+    if (sharedRefDb.isUpToDate(new Project.NameKey(projectName), latestRefPair.compareRef)) {
       return latestRefPair;
     }
 
-    if (isNullRef(latestRefPair.compareRef) || sharedRefDb.exists(projectName, refName)) {
+    if (isNullRef(latestRefPair.compareRef)
+        || sharedRefDb.exists(new Project.NameKey(projectName), refName)) {
       validationMetrics.incrementSplitBrainPrevention();
 
       softFailBasedOnEnforcement(
@@ -193,6 +198,10 @@
         latestRef == null ? nullRef(refPair.getName()) : latestRef, refPair.putValue);
   }
 
+  private Ref nullRef(String name) {
+    return new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, name, ObjectId.zeroId());
+  }
+
   protected boolean isSuccessful(RefUpdate.Result result) {
     switch (result) {
       case NEW:
@@ -219,7 +228,7 @@
   }
 
   protected Ref getCurrentRef(String refName) throws IOException {
-    return MoreObjects.firstNonNull(refDb.getRef(refName), SharedRefDatabase.nullRef(refName));
+    return MoreObjects.firstNonNull(refDb.getRef(refName), nullRef(refName));
   }
 
   public static class CloseableSet<T extends AutoCloseable> implements AutoCloseable {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
index e331819..1719f38 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
@@ -16,19 +16,16 @@
 
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.extensions.config.FactoryModule;
-import com.google.gerrit.extensions.events.ProjectDeletedListener;
 import com.google.gerrit.extensions.registration.DynamicItem;
-import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.inject.Scopes;
 import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.LockWrapper;
 import com.googlesource.gerrit.plugins.multisite.Log4jSharedRefLogger;
+import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
 import com.googlesource.gerrit.plugins.multisite.SharedRefLogger;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.CustomSharedRefEnforcementByProject;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.NoopSharedRefDatabase;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
 import com.googlesource.gerrit.plugins.replication.ReplicationExtensionPointModule;
 import com.googlesource.gerrit.plugins.replication.ReplicationPushFilter;
@@ -37,23 +34,16 @@
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
   private final Configuration cfg;
-  private final boolean disableGitRepositoryValidation;
 
-  public ValidationModule(Configuration cfg, boolean disableGitRepositoryValidation) {
+  public ValidationModule(Configuration cfg) {
     this.cfg = cfg;
-    this.disableGitRepositoryValidation = disableGitRepositoryValidation;
   }
 
   @Override
   protected void configure() {
     install(new ReplicationExtensionPointModule());
 
-    DynamicItem.itemOf(binder(), SharedRefDatabase.class);
-    DynamicItem.bind(binder(), SharedRefDatabase.class)
-        .to(NoopSharedRefDatabase.class)
-        .in(Scopes.SINGLETON);
-    logger.atInfo().log("Shared ref-db engine: none");
-
+    bind(SharedRefDatabaseWrapper.class).in(Scopes.SINGLETON);
     bind(SharedRefLogger.class).to(Log4jSharedRefLogger.class);
     factory(LockWrapper.Factory.class);
 
@@ -64,12 +54,10 @@
     factory(RefUpdateValidator.Factory.class);
     factory(BatchRefUpdateValidator.Factory.class);
 
+    bind(GitRepositoryManager.class).to(MultiSiteGitRepositoryManager.class);
     DynamicItem.bind(binder(), ReplicationPushFilter.class)
         .to(MultisiteReplicationPushFilter.class);
 
-    if (!disableGitRepositoryValidation) {
-      bind(GitRepositoryManager.class).to(MultiSiteGitRepositoryManager.class);
-    }
     if (cfg.getSharedRefDb().getEnforcementRules().isEmpty()) {
       bind(SharedRefEnforcement.class).to(DefaultSharedRefEnforcement.class).in(Scopes.SINGLETON);
     } else {
@@ -77,6 +65,5 @@
           .to(CustomSharedRefEnforcementByProject.class)
           .in(Scopes.SINGLETON);
     }
-    DynamicSet.bind(binder(), ProjectDeletedListener.class).to(ProjectDeletedSharedDbCleanup.class);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ZkConnectionConfig.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ZkConnectionConfig.java
deleted file mode 100644
index 0339f01..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ZkConnectionConfig.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation;
-
-import org.apache.curator.RetryPolicy;
-
-public class ZkConnectionConfig {
-
-  public final RetryPolicy curatorRetryPolicy;
-  public final Long transactionLockTimeout;
-
-  public ZkConnectionConfig(RetryPolicy curatorRetryPolicy, Long transactionLockTimeout) {
-    this.curatorRetryPolicy = curatorRetryPolicy;
-    this.transactionLockTimeout = transactionLockTimeout;
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabase.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabase.java
index e40688f..aa15108 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabase.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabase.java
@@ -14,30 +14,37 @@
 
 package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb;
 
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase;
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
+import com.google.gerrit.reviewdb.client.Project;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Ref;
 
-public class NoopSharedRefDatabase implements SharedRefDatabase {
+public class NoopSharedRefDatabase implements GlobalRefDatabase {
+
   @Override
-  public boolean isUpToDate(String project, Ref ref) {
+  public boolean isUpToDate(Project.NameKey project, Ref ref) throws GlobalRefDbLockException {
     return true;
   }
 
   @Override
-  public boolean compareAndPut(String project, Ref currRef, ObjectId newRefValue) {
+  public boolean compareAndPut(Project.NameKey project, Ref currRef, ObjectId newRefValue)
+      throws GlobalRefDbSystemError {
     return true;
   }
 
   @Override
-  public AutoCloseable lockRef(String project, String refName) {
+  public AutoCloseable lockRef(Project.NameKey project, String refName)
+      throws GlobalRefDbLockException {
     return () -> {};
   }
 
   @Override
-  public boolean exists(String project, String refName) {
+  public boolean exists(Project.NameKey project, String refName) {
     return false;
   }
 
   @Override
-  public void removeProject(String project) {}
+  public void remove(Project.NameKey project) throws GlobalRefDbSystemError {}
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedRefDatabase.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedRefDatabase.java
deleted file mode 100644
index a93efcf..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/SharedRefDatabase.java
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb;
-
-import java.io.IOException;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdRef;
-import org.eclipse.jgit.lib.Ref;
-
-public interface SharedRefDatabase {
-
-  /** A null ref that isn't associated to any name. */
-  Ref NULL_REF = nullRef(null);
-
-  /**
-   * Create a new in-memory ref name associated with an NULL object id.
-   *
-   * @param refName ref name
-   * @return the new NULL ref object
-   */
-  static Ref nullRef(String refName) {
-    return new Ref() {
-
-      @Override
-      public String getName() {
-        return refName;
-      }
-
-      @Override
-      public boolean isSymbolic() {
-        return false;
-      }
-
-      @Override
-      public Ref getLeaf() {
-        return null;
-      }
-
-      @Override
-      public Ref getTarget() {
-        return null;
-      }
-
-      @Override
-      public ObjectId getObjectId() {
-        return ObjectId.zeroId();
-      }
-
-      @Override
-      public ObjectId getPeeledObjectId() {
-        return ObjectId.zeroId();
-      }
-
-      @Override
-      public boolean isPeeled() {
-        return false;
-      }
-
-      @Override
-      public Storage getStorage() {
-        return Storage.NEW;
-      }
-    };
-  }
-
-  /**
-   * Create a new in-memory Ref name associated with an objectId.
-   *
-   * @param refName ref name
-   * @param objectId object id
-   */
-  static Ref newRef(String refName, ObjectId objectId) {
-    return new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, refName, objectId);
-  }
-
-  /**
-   * Verify in shared db if Ref is the most recent
-   *
-   * @param project project name of the ref
-   * @param ref to be checked against shared-ref db
-   * @return true if it is; false otherwise
-   * @throws SharedLockException if there was a problem locking the resource
-   */
-  boolean isUpToDate(String project, Ref ref) throws SharedLockException;
-
-  /**
-   * Compare a reference, and put if it matches.
-   *
-   * <p>Two reference match if and only if they satisfy the following:
-   *
-   * <ul>
-   *   <li>If one reference is a symbolic ref, the other one should be a symbolic ref.
-   *   <li>If both are symbolic refs, the target names should be same.
-   *   <li>If both are object ID refs, the object IDs should be same.
-   * </ul>
-   *
-   * @param project project name of the ref
-   * @param currRef old value to compare to. If the reference is expected to not exist the old value
-   *     has a storage of {@link org.eclipse.jgit.lib.Ref.Storage#NEW} and an ObjectId value of
-   *     {@code null}.
-   * @param newRefValue new reference to store.
-   * @return true if the put was successful; false otherwise.
-   * @throws java.io.IOException the reference cannot be put due to a system error.
-   */
-  boolean compareAndPut(String project, Ref currRef, ObjectId newRefValue) throws IOException;
-
-  /**
-   * Lock a reference for writing.
-   *
-   * @param project project name
-   * @param refName ref to lock
-   * @return lock object
-   * @throws SharedLockException if the lock cannot be obtained
-   */
-  AutoCloseable lockRef(String project, String refName) throws SharedLockException;
-
-  /**
-   * Verify if the DB contains a value for the specific project and ref name
-   *
-   * @param project
-   * @param refName
-   * @return true if the ref exists on the project
-   */
-  boolean exists(String project, String refName);
-
-  /**
-   * Clean project path from SharedRefDatabase
-   *
-   * @param project project name
-   * @throws IOException
-   */
-  void removeProject(String project) throws IOException;
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabase.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabase.java
deleted file mode 100644
index 1179045..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabase.java
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (C) 2012 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.multisite.validation.dfsrefdb.zookeeper;
-
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
-import com.google.common.flogger.FluentLogger;
-import com.google.inject.Inject;
-import com.googlesource.gerrit.plugins.multisite.validation.ZkConnectionConfig;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedLockException;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import org.apache.curator.RetryPolicy;
-import org.apache.curator.framework.CuratorFramework;
-import org.apache.curator.framework.recipes.atomic.AtomicValue;
-import org.apache.curator.framework.recipes.atomic.DistributedAtomicValue;
-import org.apache.curator.framework.recipes.locks.InterProcessMutex;
-import org.apache.curator.framework.recipes.locks.Locker;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-
-public class ZkSharedRefDatabase implements SharedRefDatabase {
-  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
-  private final CuratorFramework client;
-  private final RetryPolicy retryPolicy;
-
-  private final Long transactionLockTimeOut;
-
-  @Inject
-  public ZkSharedRefDatabase(CuratorFramework client, ZkConnectionConfig connConfig) {
-    this.client = client;
-    this.retryPolicy = connConfig.curatorRetryPolicy;
-    this.transactionLockTimeOut = connConfig.transactionLockTimeout;
-  }
-
-  @Override
-  public boolean isUpToDate(String project, Ref ref) throws SharedLockException {
-    if (!exists(project, ref.getName())) {
-      return true;
-    }
-
-    try {
-      final byte[] valueInZk = client.getData().forPath(pathFor(project, ref.getName()));
-
-      // Assuming this is a delete node NULL_REF
-      if (valueInZk == null) {
-        logger.atInfo().log(
-            "%s:%s not found in Zookeeper, assumed as delete node NULL_REF",
-            project, ref.getName());
-        return false;
-      }
-
-      ObjectId objectIdInSharedRefDb = readObjectId(valueInZk);
-      Boolean isUpToDate = objectIdInSharedRefDb.equals(ref.getObjectId());
-
-      if (!isUpToDate) {
-        logger.atWarning().log(
-            "%s:%s is out of sync: local=%s zk=%s",
-            project, ref.getName(), ref.getObjectId(), objectIdInSharedRefDb);
-      }
-
-      return isUpToDate;
-    } catch (Exception e) {
-      throw new SharedLockException(project, ref.getName(), e);
-    }
-  }
-
-  @Override
-  public void removeProject(String project) throws IOException {
-    try {
-      client.delete().deletingChildrenIfNeeded().forPath("/" + project);
-    } catch (Exception e) {
-      throw new IOException(String.format("Not able to delete project '%s'", project), e);
-    }
-  }
-
-  @Override
-  public boolean exists(String project, String refName) throws ZookeeperRuntimeException {
-    try {
-      return client.checkExists().forPath(pathFor(project, refName)) != null;
-    } catch (Exception e) {
-      throw new ZookeeperRuntimeException("Failed to check if path exists in Zookeeper", e);
-    }
-  }
-
-  @Override
-  public Locker lockRef(String project, String refName) throws SharedLockException {
-    InterProcessMutex refPathMutex =
-        new InterProcessMutex(client, "/locks" + pathFor(project, refName));
-    try {
-      return new Locker(refPathMutex, transactionLockTimeOut, MILLISECONDS);
-    } catch (Exception e) {
-      throw new SharedLockException(project, refName, e);
-    }
-  }
-
-  @Override
-  public boolean compareAndPut(String projectName, Ref oldRef, ObjectId newRefValue)
-      throws IOException {
-
-    final DistributedAtomicValue distributedRefValue =
-        new DistributedAtomicValue(client, pathFor(projectName, oldRef), retryPolicy);
-
-    try {
-      if (oldRef == NULL_REF) {
-        return distributedRefValue.initialize(writeObjectId(newRefValue));
-      }
-      final ObjectId newValue = newRefValue == null ? ObjectId.zeroId() : newRefValue;
-      final AtomicValue<byte[]> newDistributedValue =
-          distributedRefValue.compareAndSet(
-              writeObjectId(oldRef.getObjectId()), writeObjectId(newValue));
-
-      if (!newDistributedValue.succeeded() && refNotInZk(projectName, oldRef)) {
-        return distributedRefValue.initialize(writeObjectId(newRefValue));
-      }
-
-      return newDistributedValue.succeeded();
-    } catch (Exception e) {
-      logger.atWarning().withCause(e).log(
-          "Error trying to perform CAS at path %s", pathFor(projectName, oldRef));
-      throw new IOException(
-          String.format("Error trying to perform CAS at path %s", pathFor(projectName, oldRef)), e);
-    }
-  }
-
-  private boolean refNotInZk(String projectName, Ref oldRef) throws Exception {
-    return client.checkExists().forPath(pathFor(projectName, oldRef)) == null;
-  }
-
-  static String pathFor(String projectName, Ref oldRef) {
-    return pathFor(projectName, oldRef.getName());
-  }
-
-  static String pathFor(String projectName, String refName) {
-    return "/" + projectName + "/" + refName;
-  }
-
-  static ObjectId readObjectId(byte[] value) {
-    return ObjectId.fromString(value, 0);
-  }
-
-  static byte[] writeObjectId(ObjectId value) {
-    return ObjectId.toString(value).getBytes(StandardCharsets.US_ASCII);
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkValidationModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkValidationModule.java
deleted file mode 100644
index f83b4d9..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkValidationModule.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb.zookeeper;
-
-import com.google.gerrit.extensions.registration.DynamicItem;
-import com.google.inject.AbstractModule;
-import com.google.inject.Inject;
-import com.google.inject.Scopes;
-import com.googlesource.gerrit.plugins.multisite.Configuration;
-import com.googlesource.gerrit.plugins.multisite.ZookeeperConfig;
-import com.googlesource.gerrit.plugins.multisite.validation.ZkConnectionConfig;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
-import org.apache.curator.framework.CuratorFramework;
-
-public class ZkValidationModule extends AbstractModule {
-
-  private ZookeeperConfig cfg;
-
-  @Inject
-  public ZkValidationModule(Configuration cfg) {
-    this.cfg = new ZookeeperConfig(cfg.getMultiSiteConfig());
-  }
-
-  @Override
-  protected void configure() {
-    DynamicItem.bind(binder(), SharedRefDatabase.class)
-        .to(ZkSharedRefDatabase.class)
-        .in(Scopes.SINGLETON);
-    bind(CuratorFramework.class).toInstance(cfg.buildCurator());
-
-    bind(ZkConnectionConfig.class)
-        .toInstance(
-            new ZkConnectionConfig(cfg.buildCasRetryPolicy(), cfg.getZkInterProcessLockTimeOut()));
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZookeeperRuntimeException.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZookeeperRuntimeException.java
deleted file mode 100644
index 9f2951b..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZookeeperRuntimeException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb.zookeeper;
-
-/** Unable to communicate with Zookeeper */
-public class ZookeeperRuntimeException extends RuntimeException {
-  private static final long serialVersionUID = 1L;
-
-  public ZookeeperRuntimeException(String description, Throwable t) {
-    super(description, t);
-  }
-}
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index 264c8e9..c404ea1 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -8,7 +8,6 @@
 
 The masters must be:
 
-* migrated to NoteDb
 * connected to the same message broker
 * behind a load balancer (e.g., HAProxy)
 
@@ -73,18 +72,15 @@
   eventTopic = gerrit_index
 
 [kafka "publisher"]
-  enable = true
   indexEventTopic = gerrit_index
   streamEventTopic = gerrit_stream
   cacheEvictionEventTopic = gerrit_cache_eviction
 
 [kafka "subscriber"]
-  enable = true
   pollingIntervalMs = 1000
   autoCommitIntervalMs = 1000
 ```
 
-
 For further information and supported options, refer to [config](config.md)
 documentation.
 
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 227d0e8..b44d1dd 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -21,29 +21,16 @@
   projectListEventTopic = gerrit_project_list
 
 [kafka "publisher"]
-  enabled = true
-
-  indexEventEnabled = true
-  cacheEventEnabled = true
-  projectListEventEnabled = true
-  streamEventEnabled = true
-
   KafkaProp-compressionType = none
   KafkaProp-deliveryTimeoutMs = 60000
 
 [kafka "subscriber"]
-  enabled = true
   pollingIntervalMs = 1000
 
   KafkaProp-enableAutoCommit = true
   KafkaProp-autoCommitIntervalMs = 1000
   KafkaProp-autoCommitIntervalMs = 5000
 
-  indexEventEnabled = true
-  cacheEventEnabled = true
-  projectListEventEnabled = true
-  streamEventEnabled = true
-
 [ref-database "zookeeper"]
   connectString = "localhost:2181"
   rootNode = "/gerrit/multi-site"
@@ -126,58 +113,6 @@
 :   Name of the Kafka topic to use for publishing cache eviction events
     Defaults to GERRIT.EVENT.PROJECT.LIST
 
-```kafka.publisher.indexEventEnabled```
-:   Enable publication of index events, ignored when `kafka.publisher.enabled`
-    is false
-
-    Defaults: true
-
-```kafka.publisher.cacheEventEnabled```
-:   Enable publication of cache events, ignored when `kafka.publisher.enabled`
-    is false
-
-    Defaults: true
-
-```kafka.publisher.projectListEventEnabled```
-:   Enable publication of project list events, ignored when `kafka.publisher.enabled`
-    is false
-
-    Defaults: true
-
-```kafka.publisher.streamEventEnabled```
-:   Enable publication of stream events, ignored when `kafka.publisher.enabled`
-    is false
-
-    Defaults: true
-
-```kafka.subscriber.enabled```
-:   Enable consuming of events from Kafka
-    Defaults: false
-
-```kafka.subscriber.indexEventEnabled```
-:   Enable consumption of index events, ignored when `kafka.subscriber.enabled`
-    is false
-
-    Defaults: true
-
-```kafka.subscriber.cacheEventEnabled```
-:   Enable consumption of cache events, ignored when `kafka.subscriber.enabled`
-    is false
-
-    Defaults: true
-
-```kafka.subscriber.projectListEventEnabled```
-:   Enable consumption of project list events, ignored when `kafka.subscriber.enabled`
-    is false
-
-    Defaults: true
-
-```kafka.subscriber.streamEventEnabled```
-:   Enable consumption of stream events, ignored when `kafka.subscriber.enabled`
-    is false
-
-    Defaults: true
-
 ```kafka.subscriber.pollingIntervalMs```
 :   Polling interval in milliseconds for checking incoming events
 
@@ -290,11 +225,12 @@
 For example, if you want to set the `auto.commit.interval.ms` property for
 consumers, you need to configure this property as `KafkaProp-autoCommitIntervalMs`.
 
-**NOTE**: custom Kafka properties will be ignored when the relevant subsection is
-disabled (i.e. `kafka.subscriber.enabled` and/or `kafka.publisher.enabled` are
-set to `false`).
-
 The complete list of available settings can be found directly in the kafka website:
 
 * **Publisher**: https://kafka.apache.org/documentation/#producerconfigs
 * **Subscriber**: https://kafka.apache.org/documentation/#consumerconfigs
+
+#### Notes:
+* From version 3.0 publisher and subscribers cannot be disabled independently anymore.
+* From version 3.0 disabling the management of certain cache invalidations or re-indexing
+is not available anymore.
\ No newline at end of file
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/ModuleTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/ModuleTest.java
index 8b7a17b..10b4adb 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/ModuleTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/ModuleTest.java
@@ -37,7 +37,6 @@
   @Mock(answer = Answers.RETURNS_DEEP_STUBS)
   private Configuration configMock;
 
-  @Mock private NoteDbStatus noteDb;
   @Mock private BrokerModule brokerModule;
 
   @Rule public TemporaryFolder tempFolder = new TemporaryFolder();
@@ -46,7 +45,7 @@
 
   @Before
   public void setup() {
-    module = new Module(configMock, noteDb, brokerModule);
+    module = new Module(configMock, brokerModule);
   }
 
   @Test
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiWrapperTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiWrapperTest.java
index 2abc7b0..194e891 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiWrapperTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerApiWrapperTest.java
@@ -5,6 +5,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.server.events.Event;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedEventHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedEventHandlerTest.java
index 3b01c61..5c36ada 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedEventHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedEventHandlerTest.java
@@ -19,11 +19,11 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.verify;
 
+import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.server.events.Event;
 import com.google.gerrit.server.events.EventDispatcher;
 import com.google.gerrit.server.events.ProjectCreatedEvent;
 import com.google.gerrit.server.util.OneOffRequestContext;
-import com.google.gwtorm.server.OrmException;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -81,7 +81,7 @@
             (Answer<Void>)
                 invocation -> {
                   assertThat(Context.isForwardedEvent()).isTrue();
-                  throw new OrmException("someMessage");
+                  throw new StorageException("someMessage");
                 })
         .when(dispatcherMock)
         .postEvent(event);
@@ -89,8 +89,8 @@
     assertThat(Context.isForwardedEvent()).isFalse();
     try {
       handler.dispatch(event);
-      fail("should have throw an OrmException");
-    } catch (OrmException e) {
+      fail("should have throw an StorageException");
+    } catch (StorageException e) {
       assertThat(e.getMessage()).isEqualTo("someMessage");
     }
     assertThat(Context.isForwardedEvent()).isFalse();
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexChangeHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexChangeHandlerTest.java
index 2793253..0a910c5 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexChangeHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedIndexChangeHandlerTest.java
@@ -24,17 +24,15 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.index.change.ChangeIndexer;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.util.ManualRequestContext;
 import com.google.gerrit.server.util.OneOffRequestContext;
 import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gwtorm.server.OrmException;
-import com.google.inject.util.Providers;
 import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler.Operation;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.ChangeIndexEvent;
@@ -60,10 +58,8 @@
   private static String TEST_CHANGE_ID = TEST_PROJECT + "~" + TEST_CHANGE_NUMBER;
   private static final boolean CHANGE_EXISTS = true;
   private static final boolean CHANGE_DOES_NOT_EXIST = false;
-  private static final boolean DO_NOT_THROW_IO_EXCEPTION = false;
-  private static final boolean DO_NOT_THROW_ORM_EXCEPTION = false;
-  private static final boolean THROW_IO_EXCEPTION = true;
-  private static final boolean THROW_ORM_EXCEPTION = true;
+  private static final boolean DO_NOT_THROW_STORAGE_EXCEPTION = false;
+  private static final boolean THROW_STORAGE_EXCEPTION = true;
   private static final boolean CHANGE_UP_TO_DATE = true;
   private static final boolean CHANGE_OUTDATED = false;
 
@@ -71,7 +67,6 @@
   @Mock private ChangeIndexer indexerMock;
   @Mock private OneOffRequestContext ctxMock;
   @Mock private ManualRequestContext manualRequestContextMock;
-  @Mock private ReviewDb dbMock;
   @Mock private ChangeNotes changeNotes;
   @Mock private Configuration configurationMock;
   @Mock private Configuration.Index index;
@@ -87,7 +82,6 @@
   @Before
   public void setUp() throws Exception {
     when(ctxMock.open()).thenReturn(manualRequestContextMock);
-    when(manualRequestContextMock.getReviewDbProvider()).thenReturn(Providers.of(dbMock));
     id = new Change.Id(TEST_CHANGE_NUMBER);
     change = new Change(null, id, null, null, TimeUtil.nowTs());
     when(changeNotes.getChange()).thenReturn(change);
@@ -103,7 +97,7 @@
   public void changeIsIndexedWhenUpToDate() throws Exception {
     setupChangeAccessRelatedMocks(CHANGE_EXISTS, CHANGE_UP_TO_DATE);
     handler.index(TEST_CHANGE_ID, Operation.INDEX, Optional.empty());
-    verify(indexerMock, times(1)).index(any(ReviewDb.class), any(Change.class));
+    verify(indexerMock, times(1)).index(any(Change.class));
   }
 
   @Test
@@ -111,7 +105,7 @@
     setupChangeAccessRelatedMocks(CHANGE_EXISTS, CHANGE_OUTDATED);
     handler.index(
         TEST_CHANGE_ID, Operation.INDEX, Optional.of(new ChangeIndexEvent("foo", 1, false)));
-    verify(indexerMock, times(1)).index(any(ReviewDb.class), any(Change.class));
+    verify(indexerMock, times(1)).index(any(Change.class));
   }
 
   @Test
@@ -125,22 +119,13 @@
     setupChangeAccessRelatedMocks(CHANGE_DOES_NOT_EXIST, CHANGE_OUTDATED);
     handler.index(TEST_CHANGE_ID, Operation.INDEX, Optional.empty());
     verify(indexerMock, never()).delete(id);
-    verify(indexerMock, never())
-        .index(any(ReviewDb.class), any(Project.NameKey.class), any(Change.Id.class));
+    verify(indexerMock, never()).index(any(Project.NameKey.class), any(Change.Id.class));
   }
 
   @Test
-  public void schemaThrowsExceptionWhenLookingUpForChange() throws Exception {
-    setupChangeAccessRelatedMocks(CHANGE_EXISTS, THROW_ORM_EXCEPTION, CHANGE_UP_TO_DATE);
-    exception.expect(OrmException.class);
-    handler.index(TEST_CHANGE_ID, Operation.INDEX, Optional.empty());
-  }
-
-  @Test
-  public void indexerThrowsIOExceptionTryingToIndexChange() throws Exception {
-    setupChangeAccessRelatedMocks(
-        CHANGE_EXISTS, DO_NOT_THROW_ORM_EXCEPTION, THROW_IO_EXCEPTION, CHANGE_UP_TO_DATE);
-    exception.expect(IOException.class);
+  public void indexerThrowsStorageExceptionTryingToIndexChange() throws Exception {
+    setupChangeAccessRelatedMocks(CHANGE_EXISTS, THROW_STORAGE_EXCEPTION, CHANGE_UP_TO_DATE);
+    exception.expect(StorageException.class);
     handler.index(TEST_CHANGE_ID, Operation.INDEX, Optional.empty());
   }
 
@@ -156,13 +141,13 @@
                   return null;
                 })
         .when(indexerMock)
-        .index(any(ReviewDb.class), any(Change.class));
+        .index(any(Change.class));
 
     assertThat(Context.isForwardedEvent()).isFalse();
     handler.index(TEST_CHANGE_ID, Operation.INDEX, Optional.empty());
     assertThat(Context.isForwardedEvent()).isFalse();
 
-    verify(indexerMock, times(1)).index(any(ReviewDb.class), any(Change.class));
+    verify(indexerMock, times(1)).index(any(Change.class));
   }
 
   @Test
@@ -175,7 +160,7 @@
                   throw new IOException("someMessage");
                 })
         .when(indexerMock)
-        .index(any(ReviewDb.class), any(Change.class));
+        .index(any(Change.class));
 
     assertThat(Context.isForwardedEvent()).isFalse();
     try {
@@ -186,36 +171,22 @@
     }
     assertThat(Context.isForwardedEvent()).isFalse();
 
-    verify(indexerMock, times(1)).index(any(ReviewDb.class), any(Change.class));
+    verify(indexerMock, times(1)).index(any(Change.class));
   }
 
   private void setupChangeAccessRelatedMocks(boolean changeExist, boolean changeUpToDate)
       throws Exception {
-    setupChangeAccessRelatedMocks(
-        changeExist, DO_NOT_THROW_ORM_EXCEPTION, DO_NOT_THROW_IO_EXCEPTION, changeUpToDate);
+    setupChangeAccessRelatedMocks(changeExist, DO_NOT_THROW_STORAGE_EXCEPTION, changeUpToDate);
   }
 
   private void setupChangeAccessRelatedMocks(
-      boolean changeExist, boolean ormException, boolean changeUpToDate)
-      throws OrmException, IOException {
-    setupChangeAccessRelatedMocks(
-        changeExist, ormException, DO_NOT_THROW_IO_EXCEPTION, changeUpToDate);
-  }
-
-  private void setupChangeAccessRelatedMocks(
-      boolean changeExists, boolean ormException, boolean ioException, boolean changeIsUpToDate)
-      throws OrmException, IOException {
-    if (ormException) {
-      doThrow(new OrmException("")).when(ctxMock).open();
-    }
-
+      boolean changeExists, boolean storageException, boolean changeIsUpToDate)
+      throws StorageException {
     if (changeExists) {
       when(changeCheckerFactoryMock.create(TEST_CHANGE_ID)).thenReturn(changeCheckerPresentMock);
       when(changeCheckerPresentMock.getChangeNotes()).thenReturn(Optional.of(changeNotes));
-      if (ioException) {
-        doThrow(new IOException("io-error"))
-            .when(indexerMock)
-            .index(any(ReviewDb.class), any(Change.class));
+      if (storageException) {
+        doThrow(new StorageException("io-error")).when(indexerMock).index(any(Change.class));
       }
     }
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaConfigurationTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaConfigurationTest.java
index 84e1dd8..2d266c2 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaConfigurationTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/KafkaConfigurationTest.java
@@ -15,68 +15,41 @@
 package com.googlesource.gerrit.plugins.multisite.kafka;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.googlesource.gerrit.plugins.multisite.kafka.KafkaConfiguration.ENABLE_KEY;
-import static com.googlesource.gerrit.plugins.multisite.kafka.KafkaConfiguration.KAFKA_PROPERTY_PREFIX;
 import static com.googlesource.gerrit.plugins.multisite.kafka.KafkaConfiguration.KAFKA_SECTION;
 import static com.googlesource.gerrit.plugins.multisite.kafka.KafkaConfiguration.KafkaPublisher.KAFKA_PUBLISHER_SUBSECTION;
 import static com.googlesource.gerrit.plugins.multisite.kafka.KafkaConfiguration.KafkaSubscriber.KAFKA_SUBSCRIBER_SUBSECTION;
+import static org.mockito.Mockito.when;
 
-import com.googlesource.gerrit.plugins.multisite.Configuration;
+import com.google.gerrit.server.config.PluginConfigFactory;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
 import org.eclipse.jgit.lib.Config;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(MockitoJUnitRunner.class)
 public class KafkaConfigurationTest {
 
-  private Config globalPluginConfig;
-  private Configuration multiSiteConfig;
+  private Config kafkaConfig;
+  @Mock PluginConfigFactory configFactory;
 
   @Before
   public void setup() {
-    globalPluginConfig = new Config();
-    multiSiteConfig = new Configuration(globalPluginConfig, new Config());
+    kafkaConfig = new Config();
+    when(configFactory.getGlobalPluginConfig("multi-site")).thenReturn(kafkaConfig);
   }
 
   private KafkaConfiguration getConfiguration() {
-    return new KafkaConfiguration(multiSiteConfig);
-  }
-
-  @Test
-  public void kafkaSubscriberPropertiesAreSetWhenSectionIsEnabled() {
-    final String kafkaPropertyName = KAFKA_PROPERTY_PREFIX + "fooBarBaz";
-    final String kafkaPropertyValue = "aValue";
-    globalPluginConfig.setBoolean(KAFKA_SECTION, KAFKA_SUBSCRIBER_SUBSECTION, ENABLE_KEY, true);
-    globalPluginConfig.setString(
-        KAFKA_SECTION, KAFKA_SUBSCRIBER_SUBSECTION, kafkaPropertyName, kafkaPropertyValue);
-
-    final String property = getConfiguration().kafkaSubscriber().getProperty("foo.bar.baz");
-
-    assertThat(property.equals(kafkaPropertyValue)).isTrue();
-  }
-
-  @Test
-  public void kafkaSubscriberPropertiesAreNotSetWhenSectionIsDisabled() {
-    final String kafkaPropertyName = KAFKA_PROPERTY_PREFIX + "fooBarBaz";
-    final String kafkaPropertyValue = "aValue";
-    globalPluginConfig.setBoolean(KAFKA_SECTION, KAFKA_SUBSCRIBER_SUBSECTION, ENABLE_KEY, false);
-    globalPluginConfig.setString(
-        KAFKA_SECTION, KAFKA_SUBSCRIBER_SUBSECTION, kafkaPropertyName, kafkaPropertyValue);
-
-    final String property = getConfiguration().kafkaSubscriber().getProperty("foo.bar.baz");
-
-    assertThat(property).isNull();
+    return new KafkaConfiguration(configFactory, "multi-site");
   }
 
   @Test
   public void kafkaSubscriberPropertiesAreIgnoredWhenPrefixIsNotSet() {
     final String kafkaPropertyName = "fooBarBaz";
     final String kafkaPropertyValue = "aValue";
-    globalPluginConfig.setBoolean(KAFKA_SECTION, KAFKA_SUBSCRIBER_SUBSECTION, ENABLE_KEY, true);
-    globalPluginConfig.setString(
+    kafkaConfig.setString(
         KAFKA_SECTION, KAFKA_SUBSCRIBER_SUBSECTION, kafkaPropertyName, kafkaPropertyValue);
 
     final String property = getConfiguration().kafkaSubscriber().getProperty("foo.bar.baz");
@@ -85,37 +58,10 @@
   }
 
   @Test
-  public void kafkaPublisherPropertiesAreSetWhenSectionIsEnabled() {
-    final String kafkaPropertyName = KAFKA_PROPERTY_PREFIX + "fooBarBaz";
-    final String kafkaPropertyValue = "aValue";
-    globalPluginConfig.setBoolean(KAFKA_SECTION, KAFKA_PUBLISHER_SUBSECTION, ENABLE_KEY, true);
-    globalPluginConfig.setString(
-        KAFKA_SECTION, KAFKA_PUBLISHER_SUBSECTION, kafkaPropertyName, kafkaPropertyValue);
-
-    final String property = getConfiguration().kafkaPublisher().getProperty("foo.bar.baz");
-
-    assertThat(property.equals(kafkaPropertyValue)).isTrue();
-  }
-
-  @Test
   public void kafkaPublisherPropertiesAreIgnoredWhenPrefixIsNotSet() {
     final String kafkaPropertyName = "fooBarBaz";
     final String kafkaPropertyValue = "aValue";
-    globalPluginConfig.setBoolean(KAFKA_SECTION, KAFKA_PUBLISHER_SUBSECTION, ENABLE_KEY, true);
-    globalPluginConfig.setString(
-        KAFKA_SECTION, KAFKA_PUBLISHER_SUBSECTION, kafkaPropertyName, kafkaPropertyValue);
-
-    final String property = getConfiguration().kafkaPublisher().getProperty("foo.bar.baz");
-
-    assertThat(property).isNull();
-  }
-
-  @Test
-  public void kafkaPublisherPropertiesAreNotSetWhenSectionIsDisabled() {
-    final String kafkaPropertyName = KAFKA_PROPERTY_PREFIX + "fooBarBaz";
-    final String kafkaPropertyValue = "aValue";
-    globalPluginConfig.setBoolean(KAFKA_SECTION, KAFKA_PUBLISHER_SUBSECTION, ENABLE_KEY, false);
-    globalPluginConfig.setString(
+    kafkaConfig.setString(
         KAFKA_SECTION, KAFKA_PUBLISHER_SUBSECTION, kafkaPropertyName, kafkaPropertyValue);
 
     final String property = getConfiguration().kafkaPublisher().getProperty("foo.bar.baz");
@@ -157,44 +103,7 @@
     assertThat(property).isEqualTo("gerrit_cache");
   }
 
-  @Test
-  public void shouldReturnKafkaTopicEnabledForCacheEventTopic() {
-    setKafkaTopicEnabled("cacheEventEnabled", false);
-    final Boolean property =
-        getConfiguration().kafkaPublisher().enabledEvent(EventTopic.CACHE_TOPIC);
-    assertThat(property).isFalse();
-  }
-
-  @Test
-  public void shouldReturnKafkaTopicEnabledForIndexTopic() {
-    setKafkaTopicEnabled("indexEventEnabled", false);
-    final Boolean property =
-        getConfiguration().kafkaPublisher().enabledEvent(EventTopic.INDEX_TOPIC);
-    assertThat(property).isFalse();
-  }
-
-  @Test
-  public void shouldReturnKafkaTopicEnabledForStreamEventTopic() {
-    setKafkaTopicEnabled("streamEventEnabled", false);
-    final Boolean property =
-        getConfiguration().kafkaPublisher().enabledEvent(EventTopic.STREAM_EVENT_TOPIC);
-    assertThat(property).isFalse();
-  }
-
-  @Test
-  public void shouldReturnKafkaTopicEnabledForProjectListEventTopic() {
-    setKafkaTopicEnabled("projectListEventEnabled", false);
-    final Boolean property =
-        getConfiguration().kafkaPublisher().enabledEvent(EventTopic.PROJECT_LIST_TOPIC);
-    assertThat(property).isFalse();
-  }
-
   private void setKafkaTopicAlias(String topicKey, String topic) {
-    globalPluginConfig.setString(KAFKA_SECTION, null, topicKey, topic);
-  }
-
-  private void setKafkaTopicEnabled(String topicEnabledKey, Boolean isEnabled) {
-    globalPluginConfig.setBoolean(
-        KAFKA_SECTION, KAFKA_PUBLISHER_SUBSECTION, topicEnabledKey, isEnabled);
+    kafkaConfig.setString(KAFKA_SECTION, null, topicKey, topic);
   }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/EventConsumerIT.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/EventConsumerIT.java
index cbd192d..a8e7b3a 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/EventConsumerIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/EventConsumerIT.java
@@ -16,7 +16,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static java.util.stream.Collectors.toSet;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
+import com.gerritforge.gerrit.eventbroker.BrokerApi;
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.gerrit.acceptance.AbstractDaemonTest;
 import com.google.gerrit.acceptance.GerritConfig;
 import com.google.gerrit.acceptance.LogThreshold;
@@ -27,6 +31,7 @@
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.lifecycle.LifecycleModule;
+import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.data.PatchSetAttribute;
 import com.google.gerrit.server.events.CommentAddedEvent;
@@ -40,20 +45,17 @@
 import com.google.inject.Scopes;
 import com.google.inject.TypeLiteral;
 import com.googlesource.gerrit.plugins.multisite.Configuration;
+import com.googlesource.gerrit.plugins.multisite.GitModule;
 import com.googlesource.gerrit.plugins.multisite.Module;
-import com.googlesource.gerrit.plugins.multisite.NoteDbStatus;
 import com.googlesource.gerrit.plugins.multisite.PluginModule;
-import com.googlesource.gerrit.plugins.multisite.broker.BrokerApi;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerGson;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerModule;
 import com.googlesource.gerrit.plugins.multisite.consumer.DroppedEventListener;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
 import com.googlesource.gerrit.plugins.multisite.consumer.SubscriberModule;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.ChangeIndexEvent;
 import com.googlesource.gerrit.plugins.multisite.kafka.KafkaBrokerModule;
 import com.googlesource.gerrit.plugins.multisite.kafka.KafkaConfiguration;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.ZkValidationModule;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Comparator;
@@ -81,10 +83,6 @@
       "com.googlesource.gerrit.plugins.multisite.kafka.consumer.EventConsumerIT$KafkaTestContainerModule";
   private static final int QUEUE_POLL_TIMEOUT_MSECS = 10000;
 
-  static {
-    System.setProperty("gerrit.notedb", "ON");
-  }
-
   public static class KafkaTestContainerModule extends LifecycleModule {
 
     public static class KafkaStopAtShutdown implements LifecycleListener {
@@ -118,24 +116,24 @@
     private final FileBasedConfig config;
     private final Module multiSiteModule;
     private final PluginModule pluginModule;
+    private final GitModule gitModule;
 
     @Inject
-    public KafkaTestContainerModule(SitePaths sitePaths, NoteDbStatus noteDb) throws IOException {
+    public KafkaTestContainerModule(SitePaths sitePaths) throws IOException {
       this.config =
           new FileBasedConfig(
               sitePaths.etc_dir.resolve(Configuration.MULTI_SITE_CONFIG).toFile(), FS.DETECTED);
-      config.setBoolean("kafka", "publisher", "enabled", true);
-      config.setBoolean("kafka", "subscriber", "enabled", true);
       config.setBoolean("ref-database", null, "enabled", false);
       config.save();
 
       Configuration multiSiteConfig = new Configuration(config, new Config());
-      this.multiSiteModule = new Module(multiSiteConfig, noteDb, new TestBrokerModule(), true);
-      this.pluginModule =
-          new PluginModule(
-              multiSiteConfig,
-              new ZkValidationModule(multiSiteConfig),
-              new KafkaBrokerModule(new KafkaConfiguration(multiSiteConfig)));
+
+      PluginConfigFactory cfgFactory = mock(PluginConfigFactory.class);
+      when(cfgFactory.getGlobalPluginConfig("multi-site")).thenReturn(config);
+
+      this.multiSiteModule = new Module(multiSiteConfig, new TestBrokerModule());
+      this.pluginModule = new PluginModule(multiSiteConfig, new KafkaBrokerModule());
+      this.gitModule = new GitModule(multiSiteConfig);
     }
 
     @Override
@@ -147,6 +145,7 @@
 
         install(multiSiteModule);
         install(pluginModule);
+        install(gitModule);
 
       } catch (IOException e) {
         throw new IllegalStateException(e);
@@ -157,8 +156,16 @@
       KafkaContainer kafkaContainer = new KafkaContainer();
       kafkaContainer.start();
 
-      config.setString("kafka", null, "bootstrapServers", kafkaContainer.getBootstrapServers());
-      config.save();
+      Config kafkaConfig = new Config();
+      kafkaConfig.setString(
+          "kafka", null, "bootstrapServers", kafkaContainer.getBootstrapServers());
+
+      PluginConfigFactory configFactory = mock(PluginConfigFactory.class);
+      when(configFactory.getGlobalPluginConfig("multi-site")).thenReturn(kafkaConfig);
+      KafkaConfiguration kafkaConfiguration = new KafkaConfiguration(configFactory, "multi-site");
+      bind(KafkaConfiguration.class).toInstance(kafkaConfiguration);
+
+      listener().toInstance(new KafkaStopAtShutdown(kafkaContainer));
 
       return kafkaContainer;
     }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventDeserializerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventDeserializerTest.java
index 239b586..05a67db 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventDeserializerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventDeserializerTest.java
@@ -17,9 +17,9 @@
 import static com.google.common.truth.Truth.assertThat;
 import static java.nio.charset.StandardCharsets.UTF_8;
 
+import com.gerritforge.gerrit.eventbroker.SourceAwareEventWrapper;
 import com.google.gson.Gson;
 import com.googlesource.gerrit.plugins.multisite.broker.GsonProvider;
-import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
 import java.util.UUID;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
index 5a68d2f..133c35d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
@@ -14,27 +14,27 @@
 
 package com.googlesource.gerrit.plugins.multisite.validation;
 
-import static junit.framework.TestCase.assertFalse;
 import static org.eclipse.jgit.transport.ReceiveCommand.Type.UPDATE;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 
-import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.gerrit.metrics.DisabledMetricMaker;
+import com.google.gerrit.reviewdb.client.Project;
 import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.RefFixture;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.ZkSharedRefDatabase;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.ZookeeperTestContainerSupport;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
-import org.apache.curator.retry.RetryNTimes;
 import org.eclipse.jgit.internal.storage.file.RefDirectory;
 import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.BatchRefUpdate;
 import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevWalk;
@@ -43,7 +43,11 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
 
+@RunWith(MockitoJUnitRunner.class)
 public class BatchRefUpdateValidatorTest extends LocalDiskRepositoryTestCase implements RefFixture {
   @Rule public TestName nameRule = new TestName();
 
@@ -53,15 +57,13 @@
   private RevCommit A;
   private RevCommit B;
 
-  ZookeeperTestContainerSupport zookeeperContainer;
-  SharedRefDatabaseWrapper zkSharedRefDatabase;
+  @Mock SharedRefDatabaseWrapper sharedRefDatabase;
 
   @Before
   public void setup() throws Exception {
     super.setUp();
 
     gitRepoSetup();
-    zookeeperAndPolicyEnforcementSetup();
   }
 
   private void gitRepoSetup() throws Exception {
@@ -72,24 +74,6 @@
     B = repo.commit(repo.getRevWalk().parseCommit(A));
   }
 
-  private void zookeeperAndPolicyEnforcementSetup() {
-    zookeeperContainer = new ZookeeperTestContainerSupport(false);
-    int SLEEP_BETWEEN_RETRIES_MS = 30;
-    long TRANSACTION_LOCK_TIMEOUT = 1000l;
-    int NUMBER_OF_RETRIES = 5;
-
-    zkSharedRefDatabase =
-        new SharedRefDatabaseWrapper(
-            DynamicItem.itemOf(
-                SharedRefDatabase.class,
-                new ZkSharedRefDatabase(
-                    zookeeperContainer.getCurator(),
-                    new ZkConnectionConfig(
-                        new RetryNTimes(NUMBER_OF_RETRIES, SLEEP_BETWEEN_RETRIES_MS),
-                        TRANSACTION_LOCK_TIMEOUT))),
-            new DisabledSharedRefLogger());
-  }
-
   @Test
   public void immutableChangeShouldNotBeWrittenIntoZk() throws Exception {
     String AN_IMMUTABLE_REF = "refs/changes/01/1/1";
@@ -102,7 +86,8 @@
     BatchRefUpdateValidator.executeBatchUpdateWithValidation(
         batchRefUpdate, () -> execute(batchRefUpdate));
 
-    assertFalse(zkSharedRefDatabase.exists(A_TEST_PROJECT_NAME, AN_IMMUTABLE_REF));
+    verify(sharedRefDatabase, never())
+        .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
   }
 
   @Test
@@ -116,7 +101,8 @@
     BatchRefUpdateValidator.executeBatchUpdateWithValidation(
         batchRefUpdate, () -> execute(batchRefUpdate));
 
-    assertFalse(zkSharedRefDatabase.exists(A_TEST_PROJECT_NAME, DRAFT_COMMENT));
+    verify(sharedRefDatabase, never())
+        .compareAndPut(A_TEST_PROJECT_NAME_KEY, newRef(DRAFT_COMMENT, A.getId()), B.getId());
   }
 
   private BatchRefUpdateValidator newDefaultValidator(String projectName) {
@@ -126,7 +112,7 @@
   private BatchRefUpdateValidator getRefValidatorForEnforcement(
       String projectName, SharedRefEnforcement sharedRefEnforcement) {
     return new BatchRefUpdateValidator(
-        zkSharedRefDatabase,
+        sharedRefDatabase,
         new ValidationMetrics(new DisabledMetricMaker()),
         sharedRefEnforcement,
         new DummyLockWrapper(),
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/Log4jSharedRefLoggerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/Log4jSharedRefLoggerTest.java
index f368d41..c6f0fc1 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/Log4jSharedRefLoggerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/Log4jSharedRefLoggerTest.java
@@ -18,10 +18,10 @@
 
 import com.google.gerrit.acceptance.AbstractDaemonTest;
 import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.json.OutputFormat;
 import com.google.gerrit.reviewdb.client.RefNames;
-import com.google.gerrit.server.OutputFormat;
-import com.google.gerrit.server.Sequences;
 import com.google.gerrit.server.config.SitePaths;
+import com.google.gerrit.server.notedb.Sequences;
 import com.google.gerrit.server.util.SystemLog;
 import com.google.gson.Gson;
 import com.googlesource.gerrit.plugins.multisite.Log4jSharedRefLogger;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
index 730e558..f6eadcc 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
@@ -25,7 +25,7 @@
 
 import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.RefFixture;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
 import java.io.IOException;
 import java.util.Collections;
 import org.eclipse.jgit.lib.BatchRefUpdate;
@@ -110,13 +110,13 @@
     setMockRequiredReturnValues();
 
     // When compareAndPut against sharedDb succeeds
-    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, oldRef);
+    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
     doReturn(true)
         .when(sharedRefDb)
-        .compareAndPut(eq(A_TEST_PROJECT_NAME), refEquals(oldRef), eq(newRef.getObjectId()));
+        .compareAndPut(eq(A_TEST_PROJECT_NAME_KEY), refEquals(oldRef), eq(newRef.getObjectId()));
     multiSiteRefUpdate.execute(revWalk, progressMonitor, Collections.emptyList());
     verify(sharedRefDb)
-        .compareAndPut(eq(A_TEST_PROJECT_NAME), refEquals(oldRef), eq(newRef.getObjectId()));
+        .compareAndPut(eq(A_TEST_PROJECT_NAME_KEY), refEquals(oldRef), eq(newRef.getObjectId()));
   }
 
   private Ref refEquals(Ref oldRef) {
@@ -126,8 +126,8 @@
   @Test
   public void executeAndFailsWithExceptions() throws IOException {
     setMockRequiredReturnValues();
-    doReturn(true).when(sharedRefDb).exists(A_TEST_PROJECT_NAME, A_TEST_REF_NAME);
-    doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, oldRef);
+    doReturn(true).when(sharedRefDb).exists(A_TEST_PROJECT_NAME_KEY, A_TEST_REF_NAME);
+    doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
     try {
       multiSiteRefUpdate.execute(revWalk, progressMonitor, Collections.emptyList());
       fail("Expecting an IOException to be thrown");
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteGitRepositoryManagerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteGitRepositoryManagerTest.java
index 82476a1..491ced4 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteGitRepositoryManagerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteGitRepositoryManagerTest.java
@@ -18,7 +18,7 @@
 import static org.mockito.Mockito.verify;
 
 import com.google.gerrit.server.git.LocalDiskRepositoryManager;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.RefFixture;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
 import org.eclipse.jgit.lib.Repository;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabaseTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabaseTest.java
index b41378b..41b83e5 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabaseTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefDatabaseTest.java
@@ -17,7 +17,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.RefFixture;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
 import org.eclipse.jgit.lib.RefDatabase;
 import org.eclipse.jgit.lib.RefUpdate;
 import org.junit.Rule;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
index a9d8e76..16cda4e 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
@@ -24,8 +24,8 @@
 import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
 import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.Factory;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.RefFixture;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.RefUpdateStub;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefUpdateStub;
 import java.io.IOException;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectIdRef;
@@ -65,10 +65,10 @@
   @Test
   public void newUpdateShouldValidateAndSucceed() throws Exception {
 
-    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, oldRef);
+    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
     doReturn(true)
         .when(sharedRefDb)
-        .compareAndPut(A_TEST_PROJECT_NAME, oldRef, newRef.getObjectId());
+        .compareAndPut(A_TEST_PROJECT_NAME_KEY, oldRef, newRef.getObjectId());
 
     RefUpdate refUpdate = RefUpdateStub.forSuccessfulUpdate(oldRef, newRef.getObjectId());
 
@@ -82,7 +82,7 @@
   @Test(expected = Exception.class)
   public void newUpdateShouldValidateAndFailWithIOException() throws Exception {
 
-    doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, oldRef);
+    doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
 
     RefUpdate refUpdate = RefUpdateStub.forSuccessfulUpdate(oldRef, newRef.getObjectId());
 
@@ -94,7 +94,7 @@
   @Test
   public void newUpdateShouldIncreaseRefUpdateFailureCountWhenFailing() throws IOException {
 
-    doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, oldRef);
+    doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
 
     RefUpdate refUpdate = RefUpdateStub.forSuccessfulUpdate(oldRef, newRef.getObjectId());
 
@@ -113,10 +113,10 @@
   public void newUpdateShouldNotIncreaseSplitBrainPreventedCounterIfFailingSharedDbPostUpdate()
       throws IOException {
 
-    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, oldRef);
+    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
     doReturn(false)
         .when(sharedRefDb)
-        .compareAndPut(A_TEST_PROJECT_NAME, oldRef, newRef.getObjectId());
+        .compareAndPut(A_TEST_PROJECT_NAME_KEY, oldRef, newRef.getObjectId());
 
     RefUpdate refUpdate = RefUpdateStub.forSuccessfulUpdate(oldRef, newRef.getObjectId());
 
@@ -135,10 +135,10 @@
   public void newUpdateShouldtIncreaseSplitBrainCounterIfFailingSharedDbPostUpdate()
       throws IOException {
 
-    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, oldRef);
+    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
     doReturn(false)
         .when(sharedRefDb)
-        .compareAndPut(A_TEST_PROJECT_NAME, oldRef, newRef.getObjectId());
+        .compareAndPut(A_TEST_PROJECT_NAME_KEY, oldRef, newRef.getObjectId());
 
     RefUpdate refUpdate = RefUpdateStub.forSuccessfulUpdate(oldRef, newRef.getObjectId());
 
@@ -155,9 +155,11 @@
 
   @Test
   public void deleteShouldValidateAndSucceed() throws IOException {
-    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, oldRef);
+    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
 
-    doReturn(true).when(sharedRefDb).compareAndPut(A_TEST_PROJECT_NAME, oldRef, ObjectId.zeroId());
+    doReturn(true)
+        .when(sharedRefDb)
+        .compareAndPut(A_TEST_PROJECT_NAME_KEY, oldRef, ObjectId.zeroId());
 
     RefUpdate refUpdate = RefUpdateStub.forSuccessfulDelete(oldRef);
 
@@ -171,7 +173,7 @@
   @Test
   public void deleteShouldIncreaseRefUpdateFailureCountWhenFailing() throws IOException {
 
-    doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, oldRef);
+    doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
 
     RefUpdate refUpdate = RefUpdateStub.forSuccessfulDelete(oldRef);
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRepositoryTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRepositoryTest.java
index eb05b30..15c596f 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRepositoryTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRepositoryTest.java
@@ -18,7 +18,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.RefFixture;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
 import java.io.IOException;
 import org.eclipse.jgit.lib.RefDatabase;
 import org.eclipse.jgit.lib.RefUpdate.Result;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanupTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanupTest.java
new file mode 100644
index 0000000..ba381a4
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectDeletedSharedDbCleanupTest.java
@@ -0,0 +1,45 @@
+package com.googlesource.gerrit.plugins.multisite.validation;
+
+import com.google.gerrit.extensions.api.changes.NotifyHandling;
+import com.google.gerrit.extensions.events.ProjectDeletedListener;
+import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ProjectDeletedSharedDbCleanupTest implements RefFixture {
+  @Rule public TestName nameRule = new TestName();
+
+  @Mock ValidationMetrics mockValidationMetrics;
+  @Mock SharedRefDatabaseWrapper sharedRefDatabase;
+
+  @Test
+  public void aDeleteProjectEventShouldCleanupProjectFromZk() throws Exception {
+    String projectName = A_TEST_PROJECT_NAME;
+    ProjectDeletedSharedDbCleanup projectDeletedSharedDbCleanup =
+        new ProjectDeletedSharedDbCleanup(sharedRefDatabase, mockValidationMetrics);
+
+    ProjectDeletedListener.Event event =
+        new ProjectDeletedListener.Event() {
+          @Override
+          public String getProjectName() {
+            return projectName;
+          }
+
+          @Override
+          public NotifyHandling getNotify() {
+            return NotifyHandling.NONE;
+          }
+        };
+
+    projectDeletedSharedDbCleanup.onProjectDeleted(event);
+
+    Mockito.verify(sharedRefDatabase, Mockito.times(1)).remove(A_TEST_PROJECT_NAME_KEY);
+  }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
index f0677b8..3887611 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
@@ -16,20 +16,18 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
+import com.google.gerrit.reviewdb.client.Project;
 import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.OutOfSyncException;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedDbSplitBrainException;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.RefFixture;
 import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdRef;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.RefDatabase;
 import org.eclipse.jgit.lib.RefUpdate;
@@ -86,15 +84,18 @@
 
   @Test
   public void validationShouldSucceedWhenLocalRefDbIsUpToDate() throws Exception {
-    lenient().doReturn(false).when(sharedRefDb).isUpToDate(anyString(), any(Ref.class));
-    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, localRef);
     lenient()
         .doReturn(false)
         .when(sharedRefDb)
-        .compareAndPut(anyString(), any(Ref.class), any(ObjectId.class));
+        .isUpToDate(any(Project.NameKey.class), any(Ref.class));
+    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, localRef);
+    lenient()
+        .doReturn(false)
+        .when(sharedRefDb)
+        .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
     doReturn(true)
         .when(sharedRefDb)
-        .compareAndPut(A_TEST_PROJECT_NAME, localRef, newUpdateRef.getObjectId());
+        .compareAndPut(A_TEST_PROJECT_NAME_KEY, localRef, newUpdateRef.getObjectId());
 
     Result result = refUpdateValidator.executeRefUpdate(refUpdate, () -> RefUpdate.Result.NEW);
 
@@ -104,14 +105,14 @@
   @Test
   public void sharedRefDbShouldBeUpdatedWithRefDeleted() throws Exception {
     doReturn(ObjectId.zeroId()).when(refUpdate).getNewObjectId();
-    doReturn(true).when(sharedRefDb).isUpToDate(anyString(), any(Ref.class));
+    doReturn(true).when(sharedRefDb).isUpToDate(any(Project.NameKey.class), any(Ref.class));
     lenient()
         .doReturn(false)
         .when(sharedRefDb)
-        .compareAndPut(anyString(), any(Ref.class), any(ObjectId.class));
+        .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
     doReturn(true)
         .when(sharedRefDb)
-        .compareAndPut(A_TEST_PROJECT_NAME, localRef, ObjectId.zeroId());
+        .compareAndPut(A_TEST_PROJECT_NAME_KEY, localRef, ObjectId.zeroId());
     doReturn(localRef).doReturn(null).when(localRefDb).getRef(refName);
 
     Result result = refUpdateValidator.executeRefUpdate(refUpdate, () -> RefUpdate.Result.FORCED);
@@ -121,16 +122,16 @@
 
   @Test
   public void sharedRefDbShouldBeUpdatedWithNewRefCreated() throws Exception {
-    Ref localNullRef = SharedRefDatabase.nullRef(refName);
+    Ref localNullRef = nullRef(refName);
 
-    doReturn(true).when(sharedRefDb).isUpToDate(anyString(), any(Ref.class));
+    doReturn(true).when(sharedRefDb).isUpToDate(any(Project.NameKey.class), any(Ref.class));
     lenient()
         .doReturn(false)
         .when(sharedRefDb)
-        .compareAndPut(anyString(), any(Ref.class), any(ObjectId.class));
+        .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
     doReturn(true)
         .when(sharedRefDb)
-        .compareAndPut(A_TEST_PROJECT_NAME, localNullRef, newUpdateRef.getObjectId());
+        .compareAndPut(A_TEST_PROJECT_NAME_KEY, localNullRef, newUpdateRef.getObjectId());
     doReturn(localNullRef).doReturn(newUpdateRef).when(localRefDb).getRef(refName);
 
     Result result = refUpdateValidator.executeRefUpdate(refUpdate, () -> RefUpdate.Result.NEW);
@@ -140,9 +141,12 @@
 
   @Test(expected = OutOfSyncException.class)
   public void validationShouldFailWhenLocalRefDbIsNotUpToDate() throws Exception {
-    lenient().doReturn(true).when(sharedRefDb).isUpToDate(anyString(), any(Ref.class));
-    doReturn(true).when(sharedRefDb).exists(A_TEST_PROJECT_NAME, refName);
-    doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, localRef);
+    lenient()
+        .doReturn(true)
+        .when(sharedRefDb)
+        .isUpToDate(any(Project.NameKey.class), any(Ref.class));
+    doReturn(true).when(sharedRefDb).exists(A_TEST_PROJECT_NAME_KEY, refName);
+    doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, localRef);
 
     refUpdateValidator.executeRefUpdate(refUpdate, () -> RefUpdate.Result.NEW);
   }
@@ -150,32 +154,35 @@
   @Test(expected = SharedDbSplitBrainException.class)
   public void shouldTrowSplitBrainWhenLocalRefDbIsUpToDateButFinalCompareAndPutIsFailing()
       throws Exception {
-    lenient().doReturn(false).when(sharedRefDb).isUpToDate(anyString(), any(Ref.class));
-    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, localRef);
+    lenient()
+        .doReturn(false)
+        .when(sharedRefDb)
+        .isUpToDate(any(Project.NameKey.class), any(Ref.class));
+    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, localRef);
     lenient()
         .doReturn(true)
         .when(sharedRefDb)
-        .compareAndPut(anyString(), any(Ref.class), any(ObjectId.class));
+        .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
     doReturn(false)
         .when(sharedRefDb)
-        .compareAndPut(A_TEST_PROJECT_NAME, localRef, newUpdateRef.getObjectId());
+        .compareAndPut(A_TEST_PROJECT_NAME_KEY, localRef, newUpdateRef.getObjectId());
 
     refUpdateValidator.executeRefUpdate(refUpdate, () -> RefUpdate.Result.NEW);
   }
 
   @Test
   public void shouldNotUpdateSharedRefDbWhenFinalCompareAndPutIsFailing() throws Exception {
-    lenient().doReturn(false).when(sharedRefDb).isUpToDate(anyString(), any(Ref.class));
-    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME, localRef);
+    lenient()
+        .doReturn(false)
+        .when(sharedRefDb)
+        .isUpToDate(any(Project.NameKey.class), any(Ref.class));
+    doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, localRef);
 
     Result result =
         refUpdateValidator.executeRefUpdate(refUpdate, () -> RefUpdate.Result.LOCK_FAILURE);
 
-    verify(sharedRefDb, never()).compareAndPut(anyString(), any(Ref.class), any(ObjectId.class));
+    verify(sharedRefDb, never())
+        .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
     assertThat(result).isEqualTo(RefUpdate.Result.LOCK_FAILURE);
   }
-
-  private Ref newRef(String refName, ObjectId objectId) {
-    return new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, refName, objectId);
-  }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/CustomSharedRefEnforcementByProjectTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/CustomSharedRefEnforcementByProjectTest.java
similarity index 94%
rename from src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/CustomSharedRefEnforcementByProjectTest.java
rename to src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/CustomSharedRefEnforcementByProjectTest.java
index d63436c..4ee3c85 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/CustomSharedRefEnforcementByProjectTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/CustomSharedRefEnforcementByProjectTest.java
@@ -12,15 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper;
+package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase.newRef;
 
 import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.Configuration.SharedRefDatabase;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.CustomSharedRefEnforcementByProject;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
 import java.util.Arrays;
 import org.eclipse.jgit.lib.Config;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/DefaultSharedRefEnforcementTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/DefaultSharedRefEnforcementTest.java
similarity index 89%
rename from src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/DefaultSharedRefEnforcementTest.java
rename to src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/DefaultSharedRefEnforcementTest.java
index 83fcf52..b462408 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/DefaultSharedRefEnforcementTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/DefaultSharedRefEnforcementTest.java
@@ -12,13 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper;
+package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb;
 
 import static com.google.common.truth.Truth.assertThat;
-import static com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase.newRef;
 
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement.EnforcePolicy;
 import org.eclipse.jgit.lib.Ref;
 import org.junit.Test;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java
index caf0d69..087259a 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java
@@ -19,7 +19,11 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDatabase;
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDbLockException;
+import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
 import com.google.gerrit.extensions.registration.DynamicItem;
+import com.google.gerrit.reviewdb.client.Project;
 import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
 import com.googlesource.gerrit.plugins.multisite.validation.DisabledSharedRefLogger;
 import com.googlesource.gerrit.plugins.multisite.validation.MultisiteReplicationPushFilter;
@@ -43,12 +47,13 @@
   @Mock SharedRefDatabaseWrapper sharedRefDatabaseMock;
 
   String project = "fooProject";
+  Project.NameKey projectName = new Project.NameKey(project);
 
   @Test
   public void shouldReturnAllRefUpdatesWhenAllUpToDate() throws Exception {
     List<RemoteRefUpdate> refUpdates =
         Arrays.asList(refUpdate("refs/heads/foo"), refUpdate("refs/heads/bar"));
-    doReturn(true).when(sharedRefDatabaseMock).isUpToDate(eq(project), any());
+    doReturn(true).when(sharedRefDatabaseMock).isUpToDate(eq(projectName), any());
 
     MultisiteReplicationPushFilter pushFilter =
         new MultisiteReplicationPushFilter(sharedRefDatabaseMock);
@@ -92,35 +97,37 @@
     Set<String> rejectedSet = new HashSet<>();
     rejectedSet.addAll(Arrays.asList(rejectedRefs));
 
-    SharedRefDatabase sharedRefDatabase =
-        new SharedRefDatabase() {
+    GlobalRefDatabase sharedRefDatabase =
+        new GlobalRefDatabase() {
 
           @Override
-          public void removeProject(String project) throws IOException {}
-
-          @Override
-          public AutoCloseable lockRef(String project, String refName) throws SharedLockException {
-            return null;
-          }
-
-          @Override
-          public boolean isUpToDate(String project, Ref ref) throws SharedLockException {
+          public boolean isUpToDate(Project.NameKey project, Ref ref)
+              throws GlobalRefDbLockException {
             return !rejectedSet.contains(ref.getName());
           }
 
           @Override
-          public boolean exists(String project, String refName) {
+          public boolean exists(Project.NameKey project, String refName) {
             return true;
           }
 
           @Override
-          public boolean compareAndPut(String project, Ref currRef, ObjectId newRefValue)
-              throws IOException {
+          public boolean compareAndPut(Project.NameKey project, Ref currRef, ObjectId newRefValue)
+              throws GlobalRefDbSystemError {
             return false;
           }
+
+          @Override
+          public AutoCloseable lockRef(Project.NameKey project, String refName)
+              throws GlobalRefDbLockException {
+            return null;
+          }
+
+          @Override
+          public void remove(Project.NameKey project) throws GlobalRefDbSystemError {}
         };
     return new SharedRefDatabaseWrapper(
-        DynamicItem.itemOf(SharedRefDatabase.class, sharedRefDatabase),
+        DynamicItem.itemOf(GlobalRefDatabase.class, sharedRefDatabase),
         new DisabledSharedRefLogger());
   }
 
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabaseTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabaseTest.java
new file mode 100644
index 0000000..c63530a
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/NoopSharedRefDatabaseTest.java
@@ -0,0 +1,28 @@
+package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.eclipse.jgit.lib.Ref;
+import org.junit.Test;
+
+public class NoopSharedRefDatabaseTest implements RefFixture {
+
+  private Ref sampleRef = newRef(A_TEST_REF_NAME, AN_OBJECT_ID_1);
+  private NoopSharedRefDatabase objectUnderTest = new NoopSharedRefDatabase();
+
+  @Test
+  public void isUpToDateShouldAlwaysReturnTrue() {
+    assertThat(objectUnderTest.isUpToDate(A_TEST_PROJECT_NAME_KEY, sampleRef)).isTrue();
+  }
+
+  @Test
+  public void compareAndPutShouldAlwaysReturnTrue() {
+    assertThat(objectUnderTest.compareAndPut(A_TEST_PROJECT_NAME_KEY, sampleRef, AN_OBJECT_ID_2))
+        .isTrue();
+  }
+
+  @Test
+  public void existsShouldAlwaysReturnFalse() {
+    assertThat(objectUnderTest.exists(A_TEST_PROJECT_NAME_KEY, A_TEST_REF_NAME)).isFalse();
+  }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/RefFixture.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefFixture.java
similarity index 84%
rename from src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/RefFixture.java
rename to src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefFixture.java
index 72ea236..8ddbf5c 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/RefFixture.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefFixture.java
@@ -12,11 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper;
+package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb;
 
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
 import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.Ref;
 import org.junit.Ignore;
 
 @Ignore
@@ -41,4 +43,12 @@
   default String testBranch() {
     return "aTestBranch";
   }
+
+  default Ref newRef(String refName, ObjectId objectId) {
+    return new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, refName, objectId);
+  }
+
+  default Ref nullRef(String refName) {
+    return newRef(refName, ObjectId.zeroId());
+  }
 }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefSharedDatabaseTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefSharedDatabaseTest.java
index 57ab5e0..c9eeaa8 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefSharedDatabaseTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefSharedDatabaseTest.java
@@ -16,8 +16,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.RefFixture;
 import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Ref.Storage;
 import org.junit.Rule;
@@ -38,7 +38,7 @@
     ObjectId objectId = AN_OBJECT_ID_1;
     String refName = aBranchRef();
 
-    Ref aNewRef = SharedRefDatabase.newRef(refName, objectId);
+    Ref aNewRef = new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, refName, objectId);
 
     assertThat(aNewRef.getName()).isEqualTo(refName);
     assertThat(aNewRef.getObjectId()).isEqualTo(objectId);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/RefUpdateStub.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefUpdateStub.java
similarity index 99%
rename from src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/RefUpdateStub.java
rename to src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefUpdateStub.java
index cec476e..7c1d7b4 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/RefUpdateStub.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/RefUpdateStub.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper;
+package com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb;
 
 import java.io.IOException;
 import org.apache.commons.lang.NotImplementedException;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabaseIT.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabaseIT.java
deleted file mode 100644
index e2bdfbc..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabaseIT.java
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb.zookeeper;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.google.gerrit.acceptance.AbstractDaemonTest;
-import com.google.gerrit.extensions.registration.DynamicItem;
-import com.google.gerrit.metrics.DisabledMetricMaker;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.BatchRefUpdateValidator;
-import com.googlesource.gerrit.plugins.multisite.validation.DisabledSharedRefLogger;
-import com.googlesource.gerrit.plugins.multisite.validation.DummyLockWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.MultiSiteBatchRefUpdate;
-import com.googlesource.gerrit.plugins.multisite.validation.ValidationMetrics;
-import com.googlesource.gerrit.plugins.multisite.validation.ZkConnectionConfig;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
-import org.apache.curator.retry.RetryNTimes;
-import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
-import org.eclipse.jgit.lib.NullProgressMonitor;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.RefDatabase;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.transport.ReceiveCommand;
-import org.eclipse.jgit.transport.ReceiveCommand.Result;
-import org.eclipse.jgit.transport.ReceiveCommand.Type;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-
-public class ZkSharedRefDatabaseIT extends AbstractDaemonTest implements RefFixture {
-  @Rule public TestName nameRule = new TestName();
-
-  ZookeeperTestContainerSupport zookeeperContainer;
-  SharedRefDatabaseWrapper zkSharedRefDatabase;
-  SharedRefEnforcement refEnforcement;
-
-  int SLEEP_BETWEEN_RETRIES_MS = 30;
-  long TRANSACTION_LOCK_TIMEOUT = 1000l;
-  int NUMBER_OF_RETRIES = 5;
-
-  @Before
-  public void setup() {
-    refEnforcement = new DefaultSharedRefEnforcement();
-    zookeeperContainer = new ZookeeperTestContainerSupport(false);
-    zkSharedRefDatabase =
-        new SharedRefDatabaseWrapper(
-            DynamicItem.itemOf(
-                SharedRefDatabase.class,
-                new ZkSharedRefDatabase(
-                    zookeeperContainer.getCurator(),
-                    new ZkConnectionConfig(
-                        new RetryNTimes(NUMBER_OF_RETRIES, SLEEP_BETWEEN_RETRIES_MS),
-                        TRANSACTION_LOCK_TIMEOUT))),
-            new DisabledSharedRefLogger());
-  }
-
-  @After
-  public void cleanup() {
-    zookeeperContainer.cleanup();
-  }
-
-  @Test
-  public void sequenceOfGitUpdatesWithARejectionCausesZKCheckToFail() throws Exception {
-    ObjectId commitObjectIdOne = commitBuilder().add("test_file.txt", "A").create().getId();
-    ObjectId commitObjectIdTwo = commitBuilder().add("test_file.txt", "B").create().getId();
-    ObjectId commitObjectIdThree = commitBuilder().add("test_file.txt", "A2").create().getId();
-
-    ReceiveCommand aRefCreation =
-        new ReceiveCommand(ObjectId.zeroId(), commitObjectIdOne, A_TEST_REF_NAME);
-
-    ReceiveCommand aCommandThatWillBeRejectedByJGit =
-        new ReceiveCommand(
-            commitObjectIdOne, commitObjectIdTwo, A_TEST_REF_NAME, Type.UPDATE_NONFASTFORWARD);
-
-    ReceiveCommand aCommandThatShouldSucceed =
-        new ReceiveCommand(commitObjectIdOne, commitObjectIdThree, A_TEST_REF_NAME, Type.UPDATE);
-
-    InMemoryRepository repository = testRepo.getRepository();
-    try (RevWalk rw = new RevWalk(repository)) {
-      newBatchRefUpdate(repository, aRefCreation).execute(rw, NullProgressMonitor.INSTANCE);
-
-      // The rejection of this command should not leave the shared DB into an inconsistent state
-      newBatchRefUpdate(repository, aCommandThatWillBeRejectedByJGit)
-          .execute(rw, NullProgressMonitor.INSTANCE);
-
-      // This command will succeed only if the previous one is not leaving any traces in the
-      // shared ref DB
-      newBatchRefUpdate(repository, aCommandThatShouldSucceed)
-          .execute(rw, NullProgressMonitor.INSTANCE);
-
-      assertThat(aRefCreation.getResult()).isEqualTo(Result.OK);
-      assertThat(aCommandThatWillBeRejectedByJGit.getResult())
-          .isEqualTo(Result.REJECTED_NONFASTFORWARD);
-      assertThat(aCommandThatShouldSucceed.getResult()).isEqualTo(Result.OK);
-    }
-  }
-
-  @Test
-  public void aBatchWithOneFailedCommandShouldFailAllOtherCommands() throws Exception {
-    ObjectId commitObjectIdOne = commitBuilder().add("test_file1.txt", "A").create().getId();
-    ObjectId commitObjectIdTwo = commitBuilder().add("test_file1.txt", "B").create().getId();
-    ObjectId commitObjectIdThree = commitBuilder().add("test_file2.txt", "C").create().getId();
-
-    ReceiveCommand firstCommand =
-        new ReceiveCommand(ObjectId.zeroId(), commitObjectIdOne, A_TEST_REF_NAME);
-
-    ReceiveCommand aNonFastForwardUpdate =
-        new ReceiveCommand(
-            commitObjectIdOne, commitObjectIdTwo, A_TEST_REF_NAME, Type.UPDATE_NONFASTFORWARD);
-
-    ReceiveCommand aNewCreate =
-        new ReceiveCommand(ObjectId.zeroId(), commitObjectIdThree, "refs/for/master2");
-
-    InMemoryRepository repository = testRepo.getRepository();
-    try (RevWalk rw = new RevWalk(repository)) {
-      newBatchRefUpdate(repository, firstCommand, aNonFastForwardUpdate, aNewCreate)
-          .execute(rw, NullProgressMonitor.INSTANCE);
-    }
-
-    // All commands in batch failed because of the second one
-    assertThat(firstCommand.getResult()).isEqualTo(Result.REJECTED_OTHER_REASON);
-    assertThat(aNonFastForwardUpdate.getResult()).isEqualTo(Result.REJECTED_NONFASTFORWARD);
-    assertThat(aNewCreate.getResult()).isEqualTo(Result.REJECTED_OTHER_REASON);
-
-    // Zookeeper has been left untouched
-    assertFalse(existsDataInZkForCommand(firstCommand));
-    assertFalse(existsDataInZkForCommand(aNonFastForwardUpdate));
-    assertFalse(existsDataInZkForCommand(aNewCreate));
-  }
-
-  @Test
-  public void shouldBeSuccessfulWhenRefIsRecreated() throws Exception {
-    ObjectId commitObjectIdOne = commitBuilder().add("test_file1.txt", "A").create().getId();
-    ObjectId commitObjectIdTwo = commitBuilder().add("test_file1.txt", "B").create().getId();
-
-    ReceiveCommand firstCommand =
-        new ReceiveCommand(ObjectId.zeroId(), commitObjectIdOne, A_TEST_REF_NAME);
-
-    ReceiveCommand deleteCommand =
-        new ReceiveCommand(commitObjectIdOne, ObjectId.zeroId(), A_TEST_REF_NAME, Type.DELETE);
-
-    ReceiveCommand secondCommand =
-        new ReceiveCommand(ObjectId.zeroId(), commitObjectIdTwo, A_TEST_REF_NAME);
-
-    InMemoryRepository repository = testRepo.getRepository();
-    try (RevWalk rw = new RevWalk(repository)) {
-
-      newBatchRefUpdate(repository, firstCommand).execute(rw, NullProgressMonitor.INSTANCE);
-      newBatchRefUpdate(repository, deleteCommand).execute(rw, NullProgressMonitor.INSTANCE);
-      newBatchRefUpdate(repository, secondCommand).execute(rw, NullProgressMonitor.INSTANCE);
-    }
-
-    assertTrue(existsDataInZkForCommand(secondCommand));
-  }
-
-  private boolean existsDataInZkForCommand(ReceiveCommand firstCommand) throws Exception {
-    return zkSharedRefDatabase.exists(A_TEST_PROJECT_NAME, firstCommand.getRefName());
-  }
-
-  private MultiSiteBatchRefUpdate newBatchRefUpdate(
-      Repository localGitRepo, ReceiveCommand... commands) {
-
-    BatchRefUpdateValidator.Factory batchRefValidatorFactory =
-        new BatchRefUpdateValidator.Factory() {
-          @Override
-          public BatchRefUpdateValidator create(String projectName, RefDatabase refDb) {
-            return new BatchRefUpdateValidator(
-                zkSharedRefDatabase,
-                new ValidationMetrics(new DisabledMetricMaker()),
-                new DefaultSharedRefEnforcement(),
-                new DummyLockWrapper(),
-                projectName,
-                refDb);
-          }
-        };
-
-    MultiSiteBatchRefUpdate result =
-        new MultiSiteBatchRefUpdate(
-            batchRefValidatorFactory, A_TEST_PROJECT_NAME, localGitRepo.getRefDatabase());
-
-    result.setAllowNonFastForwards(false);
-    for (ReceiveCommand command : commands) {
-      result.addCommand(command);
-    }
-    return result;
-  }
-
-  @Override
-  public String testBranch() {
-    return "branch_" + nameRule.getMethodName();
-  }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabaseTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabaseTest.java
deleted file mode 100644
index bff41f1..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkSharedRefDatabaseTest.java
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb.zookeeper;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.mock;
-
-import com.google.gerrit.extensions.api.changes.NotifyHandling;
-import com.google.gerrit.extensions.events.ProjectDeletedListener;
-import com.google.gerrit.extensions.registration.DynamicItem;
-import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
-import com.googlesource.gerrit.plugins.multisite.validation.DisabledSharedRefLogger;
-import com.googlesource.gerrit.plugins.multisite.validation.ProjectDeletedSharedDbCleanup;
-import com.googlesource.gerrit.plugins.multisite.validation.ValidationMetrics;
-import com.googlesource.gerrit.plugins.multisite.validation.ZkConnectionConfig;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
-import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
-import org.apache.curator.retry.RetryNTimes;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-
-public class ZkSharedRefDatabaseTest implements RefFixture {
-  @Rule public TestName nameRule = new TestName();
-
-  ZookeeperTestContainerSupport zookeeperContainer;
-  SharedRefDatabaseWrapper zkSharedRefDatabase;
-  SharedRefEnforcement refEnforcement;
-
-  ValidationMetrics mockValidationMetrics;
-
-  @Before
-  public void setup() {
-    refEnforcement = new DefaultSharedRefEnforcement();
-    zookeeperContainer = new ZookeeperTestContainerSupport(false);
-    int SLEEP_BETWEEN_RETRIES_MS = 30;
-    long TRANSACTION_LOCK_TIMEOUT = 1000l;
-    int NUMBER_OF_RETRIES = 5;
-
-    zkSharedRefDatabase =
-        new SharedRefDatabaseWrapper(
-            DynamicItem.itemOf(
-                SharedRefDatabase.class,
-                new ZkSharedRefDatabase(
-                    zookeeperContainer.getCurator(),
-                    new ZkConnectionConfig(
-                        new RetryNTimes(NUMBER_OF_RETRIES, SLEEP_BETWEEN_RETRIES_MS),
-                        TRANSACTION_LOCK_TIMEOUT))),
-            new DisabledSharedRefLogger());
-
-    mockValidationMetrics = mock(ValidationMetrics.class);
-  }
-
-  @After
-  public void cleanup() {
-    zookeeperContainer.cleanup();
-  }
-
-  @Test
-  public void shouldCompareAndPutSuccessfully() throws Exception {
-    Ref oldRef = refOf(AN_OBJECT_ID_1);
-    Ref newRef = refOf(AN_OBJECT_ID_2);
-    String projectName = A_TEST_PROJECT_NAME;
-
-    zookeeperContainer.createRefInZk(projectName, oldRef);
-
-    assertThat(zkSharedRefDatabase.compareAndPut(projectName, oldRef, newRef.getObjectId()))
-        .isTrue();
-  }
-
-  @Test
-  public void shouldFetchLatestObjectIdInZk() throws Exception {
-    Ref oldRef = refOf(AN_OBJECT_ID_1);
-    Ref newRef = refOf(AN_OBJECT_ID_2);
-    String projectName = A_TEST_PROJECT_NAME;
-
-    zookeeperContainer.createRefInZk(projectName, oldRef);
-
-    assertThat(zkSharedRefDatabase.compareAndPut(projectName, oldRef, newRef.getObjectId()))
-        .isTrue();
-
-    assertThat(zkSharedRefDatabase.isUpToDate(projectName, newRef)).isTrue();
-    assertThat(zkSharedRefDatabase.isUpToDate(projectName, oldRef)).isFalse();
-  }
-
-  @Test
-  public void shouldCompareAndPutWithNullOldRefSuccessfully() throws Exception {
-    Ref oldRef = refOf(null);
-    Ref newRef = refOf(AN_OBJECT_ID_2);
-    String projectName = A_TEST_PROJECT_NAME;
-
-    zookeeperContainer.createRefInZk(projectName, oldRef);
-
-    assertThat(zkSharedRefDatabase.compareAndPut(projectName, oldRef, newRef.getObjectId()))
-        .isTrue();
-  }
-
-  @Test
-  public void compareAndPutShouldFailIfTheObjectionHasNotTheExpectedValue() throws Exception {
-    String projectName = A_TEST_PROJECT_NAME;
-
-    Ref oldRef = refOf(AN_OBJECT_ID_1);
-    Ref expectedRef = refOf(AN_OBJECT_ID_2);
-
-    zookeeperContainer.createRefInZk(projectName, oldRef);
-
-    assertThat(zkSharedRefDatabase.compareAndPut(projectName, expectedRef, AN_OBJECT_ID_3))
-        .isFalse();
-  }
-
-  private Ref refOf(ObjectId objectId) {
-    return SharedRefDatabase.newRef(aBranchRef(), objectId);
-  }
-
-  @Test
-  public void removeProjectShouldRemoveTheWholePathInZk() throws Exception {
-    String projectName = A_TEST_PROJECT_NAME;
-    Ref someRef = refOf(AN_OBJECT_ID_1);
-
-    zookeeperContainer.createRefInZk(projectName, someRef);
-
-    assertThat(zookeeperContainer.readRefValueFromZk(projectName, someRef))
-        .isEqualTo(AN_OBJECT_ID_1);
-
-    assertThat(getNumChildrenForPath("/")).isEqualTo(1);
-
-    zkSharedRefDatabase.removeProject(projectName);
-
-    assertThat(getNumChildrenForPath("/")).isEqualTo(0);
-  }
-
-  @Test
-  public void aDeleteProjectEventShouldCleanupProjectFromZk() throws Exception {
-    String projectName = A_TEST_PROJECT_NAME;
-    Ref someRef = refOf(AN_OBJECT_ID_1);
-    ProjectDeletedSharedDbCleanup projectDeletedSharedDbCleanup =
-        new ProjectDeletedSharedDbCleanup(zkSharedRefDatabase, mockValidationMetrics);
-
-    ProjectDeletedListener.Event event =
-        new ProjectDeletedListener.Event() {
-          @Override
-          public String getProjectName() {
-            return projectName;
-          }
-
-          @Override
-          public NotifyHandling getNotify() {
-            return NotifyHandling.NONE;
-          }
-        };
-
-    zookeeperContainer.createRefInZk(projectName, someRef);
-
-    assertThat(getNumChildrenForPath("/")).isEqualTo(1);
-
-    projectDeletedSharedDbCleanup.onProjectDeleted(event);
-
-    assertThat(getNumChildrenForPath("/")).isEqualTo(0);
-  }
-
-  @Override
-  public String testBranch() {
-    return "branch_" + nameRule.getMethodName();
-  }
-
-  private int getNumChildrenForPath(String path) throws Exception {
-    return zookeeperContainer
-        .getCurator()
-        .checkExists()
-        .forPath(String.format(path))
-        .getNumChildren();
-  }
-}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZookeeperTestContainerSupport.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZookeeperTestContainerSupport.java
deleted file mode 100644
index 3237e3a..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZookeeperTestContainerSupport.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (C) 2019 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.multisite.validation.dfsrefdb.zookeeper;
-
-import static com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.ZkSharedRefDatabase.pathFor;
-import static com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.zookeeper.ZkSharedRefDatabase.writeObjectId;
-
-import com.googlesource.gerrit.plugins.multisite.ZookeeperConfig;
-import org.apache.curator.framework.CuratorFramework;
-import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.junit.Ignore;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.containers.wait.strategy.Wait;
-
-@Ignore
-public class ZookeeperTestContainerSupport {
-
-  static class ZookeeperContainer extends GenericContainer<ZookeeperContainer> {
-    public static String ZOOKEEPER_VERSION = "3.4.13";
-
-    public ZookeeperContainer() {
-      super("zookeeper:" + ZOOKEEPER_VERSION);
-    }
-  }
-
-  private ZookeeperContainer container;
-  private ZookeeperConfig configuration;
-  private CuratorFramework curator;
-
-  public CuratorFramework getCurator() {
-    return curator;
-  }
-
-  public ZookeeperContainer getContainer() {
-    return container;
-  }
-
-  @SuppressWarnings("resource")
-  public ZookeeperTestContainerSupport(boolean migrationMode) {
-    container = new ZookeeperContainer().withExposedPorts(2181).waitingFor(Wait.forListeningPort());
-    container.start();
-    Integer zkHostPort = container.getMappedPort(2181);
-    Config sharedRefDbConfig = new Config();
-    String connectString = container.getContainerIpAddress() + ":" + zkHostPort;
-    sharedRefDbConfig.setBoolean("ref-database", null, "enabled", true);
-    sharedRefDbConfig.setString("ref-database", "zookeeper", "connectString", connectString);
-    sharedRefDbConfig.setString(
-        "ref-database",
-        ZookeeperConfig.SUBSECTION,
-        ZookeeperConfig.KEY_CONNECT_STRING,
-        connectString);
-
-    configuration = new ZookeeperConfig(sharedRefDbConfig);
-    this.curator = configuration.buildCurator();
-  }
-
-  public void cleanup() {
-    this.curator.delete();
-    this.container.stop();
-  }
-
-  public ObjectId readRefValueFromZk(String projectName, Ref ref) throws Exception {
-    final byte[] bytes = curator.getData().forPath(pathFor(projectName, ref));
-    return ZkSharedRefDatabase.readObjectId(bytes);
-  }
-
-  public void createRefInZk(String projectName, Ref ref) throws Exception {
-    curator
-        .create()
-        .creatingParentContainersIfNeeded()
-        .forPath(pathFor(projectName, ref), writeObjectId(ref.getObjectId()));
-  }
-}