Leverage stream events publishing from the events-broker

Events-broker now provides a class to handle the publishing of gerrit
stream events in a centralized way.

In order to maintain backward-compatibility with the fact that
events-broker implementations were publishing stream events to the
`gerrit` topic, a new optional `broker.gerritEventsTopic` configuration
has been introduced.

The need for the additional `STREAM_EVENT_TOPIC` topic can be removed
once [1] has been completed.

[1] https://bugs.chromium.org/p/gerrit/issues/detail?id=14835

Bug: Issue 14834
Change-Id: Iafe5a8155a98746191926286d3618beabf3aa452
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 ad53449..69bd62f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
@@ -54,7 +54,7 @@
       install(new CacheModule());
     }
     if (config.event().synchronize()) {
-      install(new EventModule());
+      install(new EventModule(config));
     }
     if (config.index().synchronize()) {
       install(new IndexModule());
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventModule.java
index 1c0c644..663d8e5 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventModule.java
@@ -14,13 +14,25 @@
 
 package com.googlesource.gerrit.plugins.multisite.event;
 
+import com.gerritforge.gerrit.eventbroker.StreamEventPublisher;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.lifecycle.LifecycleModule;
 import com.google.gerrit.server.events.EventListener;
+import com.google.inject.Inject;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+import com.googlesource.gerrit.plugins.multisite.Configuration;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
 import com.googlesource.gerrit.plugins.multisite.validation.ProjectVersionRefUpdate;
 import java.util.concurrent.Executor;
 
 public class EventModule extends LifecycleModule {
+  private final Configuration configuration;
+
+  @Inject
+  public EventModule(Configuration configuration) {
+    this.configuration = configuration;
+  }
 
   @Override
   protected void configure() {
@@ -28,5 +40,10 @@
     listener().to(EventExecutorProvider.class);
     DynamicSet.bind(binder(), EventListener.class).to(EventHandler.class);
     DynamicSet.bind(binder(), EventListener.class).to(ProjectVersionRefUpdate.class);
+    bind(new TypeLiteral<String>() {})
+        .annotatedWith(Names.named(StreamEventPublisher.STREAM_EVENTS_TOPIC))
+        .toInstance(EventTopic.GERRIT_TOPIC.topic(configuration));
+
+    DynamicSet.bind(binder(), EventListener.class).to(StreamEventPublisher.class);
   }
 }
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 4e7a781..507f067 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
@@ -21,7 +21,36 @@
   BATCH_INDEX_TOPIC("GERRIT.EVENT.BATCH.INDEX", "batchIndexEvent"),
   CACHE_TOPIC("GERRIT.EVENT.CACHE", "cacheEvent"),
   PROJECT_LIST_TOPIC("GERRIT.EVENT.PROJECT.LIST", "projectListEvent"),
-  STREAM_EVENT_TOPIC("GERRIT.EVENT.STREAM", "streamEvent");
+  /**
+   * the STREAM_EVENT_TOPICS and the GERRIT_TOPIC are both used to publish stream events. It might
+   * not be immediately intuitive why there are _two_ streams for this, rather than one. These are
+   * some gotchas regarding this:
+   *
+   * <ul>
+   *   <li>A subset of stream events is published to the STREAM_EVENT_TOPIC (i.e. only global
+   *       project events). This is done by the EventHandler.
+   *   <li>All, unfiltered gerrit events are published to a topic called `gerrit` (the
+   *       GERRIT_TOPIC). This is done by the StreamEventPublisher provided by the events-broker
+   *       library.
+   * </ul>
+   *
+   * Historically, the GERRIT_TOPIC existed to allow the streaming of all stream events. With the
+   * introduction of multi-site however, events had to be wrapped into EventMessage and streamed
+   * separately, in order to provide a header containing the instance-id that produced that message.
+   * For this purpose a *new* STREAM_EVENT_TOPIC topic was introduced.
+   *
+   * <p><a href="https://bugs.chromium.org/p/gerrit/issues/detail?id=14823">Issue 14823</a> now
+   * removed the need of EventMessage altogether,so that the `STREAM_EVENT_TOPIC` stream,
+   * conceptually would not be needed anymore.
+   *
+   * <p>However, before the `STREAM_EVENT_TOPIC` stream can be effectively removed, the filtering of
+   * the events needs to happen on the receiving side, as explained in <a
+   * href="https://bugs.chromium.org/p/gerrit/issues/detail?id=14835">Issue 14835</a>.
+   *
+   * <p>This would allow to *all* events to be streamed to the STREAM_EVENT_TOPICS.
+   */
+  STREAM_EVENT_TOPIC("GERRIT.EVENT.STREAM", "streamEvent"),
+  GERRIT_TOPIC("gerrit", "gerritEvents");
 
   private final String topic;
   private final String aliasKey;
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index a76545f..d7d2239 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -59,9 +59,15 @@
     Defaults to GERRIT.EVENT.INDEX
 
 ```broker.streamEventTopic```
-:   Name of the topic to use for publishing stream events
+:   Name of the topic to use for publishing stream events. Note that only
+    project events are streamed and only for global projects (see
+    `projects.pattern`).
     Defaults to GERRIT.EVENT.STREAM
 
+`broker.gerritEventsTopic`
+:   Name of the topic to use for publishing all stream events.
+    Default: gerrit
+
 ```broker.cacheEventTopic```
 :   Name of the topic to use for publishing cache eviction events
     Defaults to GERRIT.EVENT.CACHE