Merge branch 'stable-2.16' into stable-3.0

* stable-2.16:
  Move routers configuration out of kafka domain
  Move subscribers related code out of kafka module
  Use BrokerApi for events consuming
  Move SourceAwareEventWrapper out of the kafka package
  Move Kafka consumer logic to a separate class
  Split event consumer logic into separate steps
  Move broker publish metrics to the BrokerApiWrapper
  Introduce DynamicItem<BrokerApi> and its BrokerApiWrapper
  Move BrokerPublisher into the Kafka package domain
  Rename EventFamily to EventTopic
  Use BrokerApi for sending stream events
  Use BrokerApi for sending project list updates
  Use BrokerApi for sending index events
  Introduce the abstract BrokerApi
  Message subscriber metric for number of message consumed
  Skip message logging when publishing failed
  ForwardedIndexChangeHandler: Suppress FutureReturnValueIgnored warning

Change-Id: I1de6e90ab94d93dcb6d2753debe00e8bb86b2339
diff --git a/BUILD b/BUILD
index 47182ab..0e88858 100644
--- a/BUILD
+++ b/BUILD
@@ -45,12 +45,14 @@
     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",
+        "@curator-framework//jar",
+        "@curator-recipes//jar",
+        "@curator-test//jar",
+        "@curator-client//jar",
+        "@zookeeper//jar",
     ],
 )
diff --git a/README.md b/README.md
index 01b3498..0f526a9 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
 ```
 
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 369f6e0..eb53541 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",
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/setup.sh b/setup_local_env/setup.sh
index 23176fa..ff75d7e 100755
--- a/setup_local_env/setup.sh
+++ b/setup_local_env/setup.sh
@@ -317,11 +317,11 @@
 	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
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/Log4jSharedRefLogger.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Log4jSharedRefLogger.java
index 5930576..b5d20e0 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/Module.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
index b201942..03bff94 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
@@ -14,15 +14,15 @@
 
 package com.googlesource.gerrit.plugins.multisite;
 
-import com.google.common.annotations.VisibleForTesting;
+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.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;
@@ -38,7 +38,9 @@
 import com.googlesource.gerrit.plugins.multisite.index.IndexModule;
 import com.googlesource.gerrit.plugins.multisite.kafka.KafkaBrokerApi;
 import com.googlesource.gerrit.plugins.multisite.kafka.router.KafkaForwardedEventRouterModule;
-import com.googlesource.gerrit.plugins.multisite.validation.ValidationModule;
+import com.googlesource.gerrit.plugins.multisite.validation.ProjectDeletedSharedDbCleanup;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.NoopSharedRefDatabase;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefDatabase;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.IOException;
@@ -53,59 +55,33 @@
 public class Module extends LifecycleModule {
   private static final Logger log = LoggerFactory.getLogger(Module.class);
   private Configuration config;
-  private NoteDbStatus noteDb;
   private KafkaForwardedEventRouterModule kafkaForwardedEventRouterModule;
   private KafkaBrokerForwarderModule kafkaBrokerForwarderModule;
-  private final boolean disableGitRepositoryValidation;
 
   @Inject
   public Module(
       Configuration config,
-      NoteDbStatus noteDb,
-      KafkaForwardedEventRouterModule forwardedEeventRouterModule,
-      KafkaBrokerForwarderModule brokerForwarderModule) {
-    this(config, noteDb, forwardedEeventRouterModule, brokerForwarderModule, 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,
-      KafkaForwardedEventRouterModule forwardedEeventRouterModule,
-      KafkaBrokerForwarderModule brokerForwarderModule,
-      boolean disableGitRepositoryValidation) {
-    init(config, noteDb, forwardedEeventRouterModule, brokerForwarderModule);
-    this.disableGitRepositoryValidation = disableGitRepositoryValidation;
-  }
-
-  private void init(
-      Configuration config,
-      NoteDbStatus noteDb,
       KafkaForwardedEventRouterModule forwardedEeventRouterModule,
       KafkaBrokerForwarderModule brokerForwarderModule) {
     this.config = config;
-    this.noteDb = noteDb;
     this.kafkaForwardedEventRouterModule = forwardedEeventRouterModule;
     this.kafkaBrokerForwarderModule = brokerForwarderModule;
   }
 
   @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(), SharedRefDatabase.class);
+    DynamicItem.bind(binder(), SharedRefDatabase.class)
+        .to(NoopSharedRefDatabase.class)
+        .in(Scopes.SINGLETON);
+    log.info("Shared ref-db engine: none");
+
     listener().to(Log4jMessageLogger.class);
     bind(MessageLogger.class).to(Log4jMessageLogger.class);
 
@@ -130,9 +106,10 @@
     install(kafkaForwardedEventRouterModule);
     install(kafkaBrokerForwarderModule);
 
-    install(
-        new ValidationModule(
-            config, disableGitRepositoryValidation || !config.getSharedRefDb().isEnabled()));
+    if (config.getSharedRefDb().isEnabled()) {
+      DynamicSet.bind(binder(), ProjectDeletedListener.class)
+          .to(ProjectDeletedSharedDbCleanup.class);
+    }
 
     bind(Gson.class)
         .annotatedWith(BrokerGson.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 ff8bd13..22a8d2d 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.
@@ -33,6 +33,8 @@
 
   @Override
   protected void configure() {
+    listener().to(PluginStartup.class);
+
     if (config.getSharedRefDb().isEnabled()) {
       logger.atInfo().log("Shared ref-db engine: Zookeeper");
       install(zkValidationModule);
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..eda8d7c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
@@ -14,6 +14,7 @@
 
 package com.googlesource.gerrit.plugins.multisite;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.gerrit.extensions.registration.DynamicItem;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedLockException;
@@ -24,14 +25,21 @@
 
 public class SharedRefDatabaseWrapper implements SharedRefDatabase {
 
-  private final DynamicItem<SharedRefDatabase> sharedRefDbDynamicItem;
+  @Inject(optional = true)
+  private DynamicItem<SharedRefDatabase> sharedRefDbDynamicItem;
+
   private final SharedRefLogger sharedRefLogger;
 
   @Inject
+  public SharedRefDatabaseWrapper(SharedRefLogger sharedRefLogger) {
+    this.sharedRefLogger = sharedRefLogger;
+  }
+
+  @VisibleForTesting
   public SharedRefDatabaseWrapper(
       DynamicItem<SharedRefDatabase> sharedRefDbDynamicItem, SharedRefLogger sharedRefLogger) {
-    this.sharedRefDbDynamicItem = sharedRefDbDynamicItem;
     this.sharedRefLogger = sharedRefLogger;
+    this.sharedRefDbDynamicItem = sharedRefDbDynamicItem;
   }
 
   @Override
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 6e70299..8e41690 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
@@ -18,7 +18,6 @@
 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;
@@ -27,7 +26,6 @@
 import com.googlesource.gerrit.plugins.multisite.forwarder.CacheNotFoundException;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
 import com.googlesource.gerrit.plugins.multisite.forwarder.router.ForwardedEventRouter;
-
 import java.io.IOException;
 import java.util.UUID;
 
@@ -82,7 +80,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/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/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 5abf527..b8662a1 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.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexAccountHandler;
@@ -54,7 +53,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 adb9e87..a330416 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.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedEventHandler;
@@ -31,7 +30,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/consumer/KafkaEventSubscriber.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/KafkaEventSubscriber.java
index c72fa0d..406981b 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
@@ -16,8 +16,12 @@
 import static java.nio.charset.StandardCharsets.UTF_8;
 
 import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.exceptions.StorageException;
+import com.google.gerrit.extensions.registration.DynamicSet;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.util.ManualRequestContext;
 import com.google.gerrit.server.util.OneOffRequestContext;
+import com.google.gson.Gson;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.multisite.InstanceId;
 import com.googlesource.gerrit.plugins.multisite.consumer.SourceAwareEventWrapper;
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/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/dfsrefdb/zookeeper/ZkValidationModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/zookeeper/ZkValidationModule.java
index f83b4d9..360beea 100644
--- 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
@@ -39,7 +39,6 @@
         .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/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index 264c8e9..204742e 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)
 
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 e93d5f3..59df7bb 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/ModuleTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/ModuleTest.java
@@ -38,8 +38,6 @@
   @Mock(answer = Answers.RETURNS_DEEP_STUBS)
   private Configuration configMock;
 
-  @Mock private NoteDbStatus noteDb;
-
   @Mock private KafkaForwardedEventRouterModule routerModule;
   @Mock private KafkaBrokerForwarderModule brokerForwarderModule;
 
@@ -49,7 +47,7 @@
 
   @Before
   public void setup() {
-    module = new Module(configMock, noteDb, routerModule, brokerForwarderModule);
+    module = new Module(configMock, routerModule, brokerForwarderModule);
   }
 
   @Test
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/consumer/EventConsumerIT.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/kafka/consumer/EventConsumerIT.java
index b69f9e6..d1da1f0 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
@@ -39,7 +39,6 @@
 import com.google.inject.TypeLiteral;
 import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.Module;
-import com.googlesource.gerrit.plugins.multisite.NoteDbStatus;
 import com.googlesource.gerrit.plugins.multisite.broker.BrokerGson;
 import com.googlesource.gerrit.plugins.multisite.broker.kafka.KafkaBrokerForwarderModule;
 import com.googlesource.gerrit.plugins.multisite.consumer.DroppedEventListener;
@@ -74,10 +73,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 {
@@ -102,7 +97,7 @@
     private final Module multiSiteModule;
 
     @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);
@@ -116,11 +111,9 @@
       this.multiSiteModule =
           new Module(
               multiSiteConfig,
-              noteDb,
               new KafkaForwardedEventRouterModule(
                   kafkaConfiguration, new KafkaConsumerModule(kafkaConfiguration)),
-              new KafkaBrokerForwarderModule(kafkaConfiguration),
-              true);
+              new KafkaBrokerForwarderModule(kafkaConfiguration));
     }
 
     @Override
@@ -143,6 +136,10 @@
 
       config.setString("kafka", null, "bootstrapServers", kafkaContainer.getBootstrapServers());
       config.save();
+      Configuration multiSiteConfig = new Configuration(config, new Config());
+      bind(Configuration.class).toInstance(multiSiteConfig);
+
+      listener().toInstance(new KafkaStopAtShutdown(kafkaContainer));
 
       return kafkaContainer;
     }
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;