Use DynamicMap<> for registering a routing events handler

Refactoring to reduce the coupling of the event router receiving
events from the events-broker or Gerrit event-bus to the associated
registered handler.

The overall logic and configuration remain unchanged; however, this
change helps decouple the routing mechanism from the associated
implementation logic, opening the door to a conditional registration of
the events handlers based on configuration.

Change-Id: I194e5571923400ec2755365e5ac9d233ae688dd9
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 5212aa4..6e0aa11 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
@@ -14,12 +14,15 @@
 
 package com.googlesource.gerrit.plugins.multisite.forwarder;
 
+import static com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler.Operation.INDEX;
+
 import com.google.gerrit.entities.Account;
 import com.google.gerrit.server.index.account.AccountIndexer;
 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.AccountIndexEvent;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.IndexEvent;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
@@ -48,6 +51,14 @@
   }
 
   @Override
+  public void handle(IndexEvent sourceEvent) throws IOException {
+    if (sourceEvent instanceof AccountIndexEvent) {
+      AccountIndexEvent accountIndexEvent = (AccountIndexEvent) sourceEvent;
+      indexAsync(Account.id(accountIndexEvent.accountId), INDEX);
+    }
+  }
+
+  @Override
   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 15f7c13..1f3fd93 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
@@ -14,6 +14,9 @@
 
 package com.googlesource.gerrit.plugins.multisite.forwarder;
 
+import static com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler.Operation.DELETE;
+import static com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler.Operation.INDEX;
+
 import com.google.common.base.Splitter;
 import com.google.gerrit.entities.Change;
 import com.google.gerrit.server.index.change.ChangeIndexer;
@@ -24,9 +27,11 @@
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.ChangeIndexEvent;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.IndexEvent;
 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.ScheduledExecutorService;
 
@@ -55,6 +60,18 @@
   }
 
   @Override
+  public void handle(IndexEvent sourceEvent) throws IOException {
+    if (sourceEvent instanceof ChangeIndexEvent) {
+      ChangeIndexEvent changeIndexEvent = (ChangeIndexEvent) sourceEvent;
+      ForwardedIndexingHandler.Operation operation = changeIndexEvent.deleted ? DELETE : INDEX;
+      index(
+          changeIndexEvent.projectName + "~" + changeIndexEvent.changeId,
+          operation,
+          Optional.of(changeIndexEvent));
+    }
+  }
+
+  @Override
   protected void doIndex(String id, Optional<ChangeIndexEvent> indexEvent) {
     scheduleIndexing(id, indexEvent, this::indexIfConsistent);
   }
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 d05405f..f1141c9 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
@@ -14,6 +14,8 @@
 
 package com.googlesource.gerrit.plugins.multisite.forwarder;
 
+import static com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler.Operation.INDEX;
+
 import com.google.gerrit.entities.AccountGroup;
 import com.google.gerrit.server.index.group.GroupIndexer;
 import com.google.gerrit.server.util.OneOffRequestContext;
@@ -21,8 +23,10 @@
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.multisite.Configuration;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.GroupIndexEvent;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.IndexEvent;
 import com.googlesource.gerrit.plugins.multisite.index.ForwardedIndexExecutor;
 import com.googlesource.gerrit.plugins.multisite.index.GroupChecker;
+import java.io.IOException;
 import java.util.Optional;
 import java.util.concurrent.ScheduledExecutorService;
 
@@ -51,6 +55,14 @@
   }
 
   @Override
+  public void handle(IndexEvent sourceEvent) throws IOException {
+    if (sourceEvent instanceof GroupIndexEvent) {
+      GroupIndexEvent groupIndexEvent = (GroupIndexEvent) sourceEvent;
+      index(groupIndexEvent.groupUUID, INDEX, Optional.of(groupIndexEvent));
+    }
+  }
+
+  @Override
   protected void doIndex(String uuid, Optional<GroupIndexEvent> event) {
     scheduleIndexing(uuid, event, this::reindex);
   }
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 2054f10..453d961 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
@@ -14,15 +14,19 @@
 
 package com.googlesource.gerrit.plugins.multisite.forwarder;
 
+import static com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler.Operation.INDEX;
+
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.index.project.ProjectIndexer;
 import com.google.gerrit.server.util.OneOffRequestContext;
 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.IndexEvent;
 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;
 
@@ -51,6 +55,14 @@
   }
 
   @Override
+  public void handle(IndexEvent sourceEvent) throws IOException {
+    if (sourceEvent instanceof ProjectIndexEvent) {
+      ProjectIndexEvent projectIndexEvent = (ProjectIndexEvent) sourceEvent;
+      index(projectIndexEvent.projectName, INDEX, Optional.of(projectIndexEvent));
+    }
+  }
+
+  @Override
   protected void doIndex(String projectName, Optional<ProjectIndexEvent> event) {
     scheduleIndexing(projectName, event, this::reindex);
   }
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 de6b836..a6440e4 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,6 +15,7 @@
 package com.googlesource.gerrit.plugins.multisite.forwarder;
 
 import com.google.common.util.concurrent.Striped;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.IndexEvent;
 import java.io.IOException;
 import java.util.Optional;
 import java.util.concurrent.locks.Lock;
@@ -40,6 +41,8 @@
     }
   }
 
+  public abstract void handle(IndexEvent sourceEvent) throws IOException;
+
   private final Striped<Lock> idLocks;
 
   protected abstract void doIndex(T id, Optional<E> indexEvent);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/AccountIndexEvent.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/AccountIndexEvent.java
index 065ef7e..31333e7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/AccountIndexEvent.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/AccountIndexEvent.java
@@ -17,7 +17,7 @@
 import com.google.common.base.Objects;
 
 public class AccountIndexEvent extends IndexEvent {
-  static final String TYPE = "account-index";
+  public static final String TYPE = "account-index";
 
   public int accountId;
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/ChangeIndexEvent.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/ChangeIndexEvent.java
index 64fbdfb..7fd3b6c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/ChangeIndexEvent.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/ChangeIndexEvent.java
@@ -21,7 +21,7 @@
 import java.time.format.DateTimeFormatter;
 
 public class ChangeIndexEvent extends IndexEvent {
-  static final String TYPE = "change-index";
+  public static final String TYPE = "change-index";
 
   public String projectName;
   public int changeId;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/GroupIndexEvent.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/GroupIndexEvent.java
index 05ac198..63adeb6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/GroupIndexEvent.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/GroupIndexEvent.java
@@ -19,7 +19,7 @@
 import org.eclipse.jgit.lib.ObjectId;
 
 public class GroupIndexEvent extends IndexEvent {
-  static final String TYPE = "group-index";
+  public static final String TYPE = "group-index";
 
   public final String groupUUID;
   public final ObjectId sha1;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/ProjectIndexEvent.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/ProjectIndexEvent.java
index 954befb..00cca2e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/ProjectIndexEvent.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/events/ProjectIndexEvent.java
@@ -17,7 +17,7 @@
 import com.google.common.base.Objects;
 
 public class ProjectIndexEvent extends IndexEvent {
-  static final String TYPE = "project-index";
+  public static final String TYPE = "project-index";
 
   public String projectName;
 
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 a647bce..238db51 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
@@ -14,12 +14,13 @@
 
 package com.googlesource.gerrit.plugins.multisite.forwarder.router;
 
-import static com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler.Operation.DELETE;
+import static com.google.gerrit.extensions.registration.PluginName.GERRIT;
 import static com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler.Operation.INDEX;
 
 import com.google.common.flogger.FluentLogger;
 import com.google.gerrit.entities.Account;
 import com.google.gerrit.extensions.events.LifecycleListener;
+import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.server.config.AllUsersName;
 import com.google.gerrit.server.config.GerritInstanceId;
 import com.google.gerrit.server.events.Event;
@@ -27,15 +28,8 @@
 import com.google.gerrit.server.events.RefEvent;
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexAccountHandler;
-import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexChangeHandler;
-import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexGroupHandler;
-import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexProjectHandler;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler;
-import com.googlesource.gerrit.plugins.multisite.forwarder.events.AccountIndexEvent;
-import com.googlesource.gerrit.plugins.multisite.forwarder.events.ChangeIndexEvent;
-import com.googlesource.gerrit.plugins.multisite.forwarder.events.GroupIndexEvent;
 import com.googlesource.gerrit.plugins.multisite.forwarder.events.IndexEvent;
-import com.googlesource.gerrit.plugins.multisite.forwarder.events.ProjectIndexEvent;
 import java.io.IOException;
 import java.util.Optional;
 import java.util.Set;
@@ -45,50 +39,30 @@
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
   private final ForwardedIndexAccountHandler indexAccountHandler;
-  private final ForwardedIndexChangeHandler indexChangeHandler;
-  private final ForwardedIndexGroupHandler indexGroupHandler;
-  private final ForwardedIndexProjectHandler indexProjectHandler;
   private final AllUsersName allUsersName;
   private final String gerritInstanceId;
+  private final DynamicMap<ForwardedIndexingHandler<?, ? extends IndexEvent>> indexHandlers;
 
   @Inject
   public IndexEventRouter(
       ForwardedIndexAccountHandler indexAccountHandler,
-      ForwardedIndexChangeHandler indexChangeHandler,
-      ForwardedIndexGroupHandler indexGroupHandler,
-      ForwardedIndexProjectHandler indexProjectHandler,
+      DynamicMap<ForwardedIndexingHandler<?, ? extends IndexEvent>> indexHandlers,
       AllUsersName allUsersName,
       @GerritInstanceId String gerritInstanceId) {
     this.indexAccountHandler = indexAccountHandler;
-    this.indexChangeHandler = indexChangeHandler;
-    this.indexGroupHandler = indexGroupHandler;
-    this.indexProjectHandler = indexProjectHandler;
+    this.indexHandlers = indexHandlers;
     this.allUsersName = allUsersName;
     this.gerritInstanceId = gerritInstanceId;
   }
 
   @Override
   public void route(IndexEvent sourceEvent) throws IOException {
-    if (sourceEvent instanceof ChangeIndexEvent) {
-      ChangeIndexEvent changeIndexEvent = (ChangeIndexEvent) sourceEvent;
-      ForwardedIndexingHandler.Operation operation = changeIndexEvent.deleted ? DELETE : INDEX;
-      indexChangeHandler.index(
-          changeIndexEvent.projectName + "~" + changeIndexEvent.changeId,
-          operation,
-          Optional.of(changeIndexEvent));
-    } else if (sourceEvent instanceof AccountIndexEvent) {
-      AccountIndexEvent accountIndexEvent = (AccountIndexEvent) sourceEvent;
-      indexAccountHandler.indexAsync(Account.id(accountIndexEvent.accountId), INDEX);
-    } else if (sourceEvent instanceof GroupIndexEvent) {
-      GroupIndexEvent groupIndexEvent = (GroupIndexEvent) sourceEvent;
-      indexGroupHandler.index(groupIndexEvent.groupUUID, INDEX, Optional.of(groupIndexEvent));
-    } else if (sourceEvent instanceof ProjectIndexEvent) {
-      ProjectIndexEvent projectIndexEvent = (ProjectIndexEvent) sourceEvent;
-      indexProjectHandler.index(
-          projectIndexEvent.projectName, INDEX, Optional.of(projectIndexEvent));
+    ForwardedIndexingHandler<?, ? extends IndexEvent> handler =
+        indexHandlers.get(GERRIT, sourceEvent.getType());
+    if (handler != null) {
+      handler.handle(sourceEvent);
     } else {
-      throw new UnsupportedOperationException(
-          String.format("Cannot route event %s", sourceEvent.getType()));
+      logger.atInfo().log("No registered handlers to route event %s", sourceEvent.getType());
     }
   }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/RouterModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/RouterModule.java
index 2193034..1353e30 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/RouterModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/router/RouterModule.java
@@ -14,17 +14,48 @@
 
 package com.googlesource.gerrit.plugins.multisite.forwarder.router;
 
+import com.google.gerrit.extensions.annotations.Exports;
+import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.lifecycle.LifecycleModule;
 import com.google.gerrit.server.events.EventListener;
 import com.google.inject.Scopes;
+import com.google.inject.TypeLiteral;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexAccountHandler;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexChangeHandler;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexGroupHandler;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexProjectHandler;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexingHandler;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.AccountIndexEvent;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.ChangeIndexEvent;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.GroupIndexEvent;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.IndexEvent;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.ProjectIndexEvent;
 
 public class RouterModule extends LifecycleModule {
+
+  public static final TypeLiteral<ForwardedIndexingHandler<?, ? extends IndexEvent>> INDEX_HANDLER =
+      new TypeLiteral<>() {};
+
   @Override
   protected void configure() {
     bind(IndexEventRouter.class).in(Scopes.SINGLETON);
     listener().to(IndexEventRouter.class).in(Scopes.SINGLETON);
     DynamicSet.bind(binder(), EventListener.class).to(IndexEventRouter.class);
+    DynamicMap.mapOf(binder(), INDEX_HANDLER);
+
+    bind(INDEX_HANDLER)
+        .annotatedWith(Exports.named(ChangeIndexEvent.TYPE))
+        .to(ForwardedIndexChangeHandler.class);
+    bind(INDEX_HANDLER)
+        .annotatedWith(Exports.named(GroupIndexEvent.TYPE))
+        .to(ForwardedIndexGroupHandler.class);
+    bind(INDEX_HANDLER)
+        .annotatedWith(Exports.named(ProjectIndexEvent.TYPE))
+        .to(ForwardedIndexProjectHandler.class);
+    bind(INDEX_HANDLER)
+        .annotatedWith(Exports.named(AccountIndexEvent.TYPE))
+        .to(ForwardedIndexAccountHandler.class);
 
     bind(CacheEvictionEventRouter.class).in(Scopes.SINGLETON);
     bind(ProjectListUpdateRouter.class).in(Scopes.SINGLETON);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/event/IndexEventRouterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/event/IndexEventRouterTest.java
index 4ffdbbc..11600f9 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/event/IndexEventRouterTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/event/IndexEventRouterTest.java
@@ -14,12 +14,14 @@
 
 package com.googlesource.gerrit.plugins.multisite.event;
 
-import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static com.google.gerrit.extensions.registration.PluginName.GERRIT;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 
-import com.google.gerrit.entities.Account;
+import com.google.gerrit.extensions.registration.DynamicMap;
+import com.google.gerrit.extensions.registration.PrivateInternals_DynamicMapImpl;
 import com.google.gerrit.server.config.AllUsersName;
+import com.google.inject.util.Providers;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedEventHandler;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexAccountHandler;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwardedIndexChangeHandler;
@@ -34,7 +36,6 @@
 import com.googlesource.gerrit.plugins.multisite.forwarder.router.IndexEventRouter;
 import com.googlesource.gerrit.plugins.multisite.forwarder.router.StreamEventRouter;
 import com.googlesource.gerrit.plugins.replication.events.RefReplicationDoneEvent;
-import java.util.Optional;
 import org.eclipse.jgit.lib.ObjectId;
 import org.junit.Before;
 import org.junit.Test;
@@ -52,17 +53,16 @@
   @Mock private ForwardedIndexProjectHandler indexProjectHandler;
   @Mock private ForwardedEventHandler forwardedEventHandler;
   private AllUsersName allUsersName = new AllUsersName("All-Users");
+  PrivateInternals_DynamicMapImpl<ForwardedIndexingHandler<?, ? extends IndexEvent>> indexHandlers;
 
   @Before
   public void setUp() {
-    router =
-        new IndexEventRouter(
-            indexAccountHandler,
-            indexChangeHandler,
-            indexGroupHandler,
-            indexProjectHandler,
-            allUsersName,
-            INSTANCE_ID);
+    indexHandlers = (PrivateInternals_DynamicMapImpl) DynamicMap.emptyMap();
+    indexHandlers.put(GERRIT, AccountIndexEvent.TYPE, Providers.of(indexAccountHandler));
+    indexHandlers.put(GERRIT, GroupIndexEvent.TYPE, Providers.of(indexGroupHandler));
+    indexHandlers.put(GERRIT, ChangeIndexEvent.TYPE, Providers.of(indexChangeHandler));
+    indexHandlers.put(GERRIT, ProjectIndexEvent.TYPE, Providers.of(indexProjectHandler));
+    router = new IndexEventRouter(indexAccountHandler, indexHandlers, allUsersName, INSTANCE_ID);
   }
 
   @Test
@@ -70,22 +70,19 @@
     final AccountIndexEvent event = new AccountIndexEvent(1, INSTANCE_ID);
     router.route(event);
 
-    verify(indexAccountHandler)
-        .indexAsync(Account.id(event.accountId), ForwardedIndexingHandler.Operation.INDEX);
+    verify(indexAccountHandler).handle(event);
 
     verifyNoInteractions(indexChangeHandler, indexGroupHandler, indexProjectHandler);
   }
 
   @Test
   public void streamEventRouterShouldTriggerAccountIndexFlush() throws Exception {
-
     StreamEventRouter streamEventRouter = new StreamEventRouter(forwardedEventHandler, router);
 
     final AccountIndexEvent event = new AccountIndexEvent(1, INSTANCE_ID);
     router.route(event);
 
-    verify(indexAccountHandler)
-        .indexAsync(Account.id(event.accountId), ForwardedIndexingHandler.Operation.INDEX);
+    verify(indexAccountHandler).handle(event);
 
     verifyNoInteractions(indexChangeHandler, indexGroupHandler, indexProjectHandler);
 
@@ -100,8 +97,7 @@
     final GroupIndexEvent event = new GroupIndexEvent(groupId, ObjectId.zeroId(), INSTANCE_ID);
     router.route(event);
 
-    verify(indexGroupHandler)
-        .index(groupId, ForwardedIndexingHandler.Operation.INDEX, Optional.of(event));
+    verify(indexGroupHandler).handle(event);
 
     verifyNoInteractions(indexAccountHandler, indexChangeHandler, indexProjectHandler);
   }
@@ -112,8 +108,7 @@
     final ProjectIndexEvent event = new ProjectIndexEvent(projectName, INSTANCE_ID);
     router.route(event);
 
-    verify(indexProjectHandler)
-        .index(projectName, ForwardedIndexingHandler.Operation.INDEX, Optional.of(event));
+    verify(indexProjectHandler).handle(event);
 
     verifyNoInteractions(indexAccountHandler, indexChangeHandler, indexGroupHandler);
   }
@@ -123,11 +118,7 @@
     final ChangeIndexEvent event = new ChangeIndexEvent("projectName", 3, false, INSTANCE_ID);
     router.route(event);
 
-    verify(indexChangeHandler)
-        .index(
-            event.projectName + "~" + event.changeId,
-            ForwardedIndexingHandler.Operation.INDEX,
-            Optional.of(event));
+    verify(indexChangeHandler).handle(event);
 
     verifyNoInteractions(indexAccountHandler, indexGroupHandler, indexProjectHandler);
   }
@@ -137,20 +128,16 @@
     final ChangeIndexEvent event = new ChangeIndexEvent("projectName", 3, true, INSTANCE_ID);
     router.route(event);
 
-    verify(indexChangeHandler)
-        .index(
-            event.projectName + "~" + event.changeId,
-            ForwardedIndexingHandler.Operation.DELETE,
-            Optional.of(event));
+    verify(indexChangeHandler).handle(event);
 
     verifyNoInteractions(indexAccountHandler, indexGroupHandler, indexProjectHandler);
   }
 
   @Test
-  public void routerShouldFailForNotRecognisedEvents() throws Exception {
+  public void routerShouldIgnoreNotRecognisedEvents() throws Exception {
     final IndexEvent newEventType = new IndexEvent("new-type", INSTANCE_ID) {};
 
-    assertThrows(UnsupportedOperationException.class, () -> router.route(newEventType));
+    router.route(newEventType);
     verifyNoInteractions(
         indexAccountHandler, indexChangeHandler, indexGroupHandler, indexProjectHandler);
   }