Merge branch 'stable-3.0'

* stable-3.0:
  Replace websession-flatfile with websession-broker for local setup
  Add events-broker to local setup
  Expose replication status metrics
  Use BrokerApi dynamic item definition from events-broker

Change-Id: Ie857f4b879ef7c43d4f7571bb0d99e29b6f69751
diff --git a/setup_local_env/configs/gerrit.config b/setup_local_env/configs/gerrit.config
index 3cdf940..6092cc1 100644
--- a/setup_local_env/configs/gerrit.config
+++ b/setup_local_env/configs/gerrit.config
@@ -2,6 +2,7 @@
     basePath = git
     serverId = 69ec38f0-350e-4d9c-96d4-bc956f2faaac
     canonicalWebUrl = $GERRIT_CANONICAL_WEB_URL
+    installModule = com.gerritforge.gerrit.eventbroker.BrokerApiModule # events-broker module to setup BrokerApi dynamic item
     installModule = com.googlesource.gerrit.plugins.multisite.Module # multi-site needs to be a gerrit lib
     installDbModule = com.googlesource.gerrit.plugins.multisite.GitModule
 [database]
@@ -40,7 +41,7 @@
 [plugin "kafka-events"]
     bootstrapServers = localhost:$KAFKA_PORT
     groupId = $KAFKA_GROUP_ID
-    numberOfSubscribers = 4
+    numberOfSubscribers = 5
     securityProtocol = PLAINTEXT
     pollingIntervalMs = 1000
     enableAutoCommit = true
diff --git a/setup_local_env/setup.sh b/setup_local_env/setup.sh
index be7366f..8fa6c3b 100755
--- a/setup_local_env/setup.sh
+++ b/setup_local_env/setup.sh
@@ -152,7 +152,7 @@
     echo "[--multisite-lib-file]          Location to lib multi-site.jar file"
     echo
     echo "[--new-deployment]              Cleans up previous gerrit deployment and re-installs it. default true"
-    echo "[--get-websession-plugin]       Download websession-flatfile plugin from CI lastSuccessfulBuild; default true"
+    echo "[--get-websession-plugin]       Download websession-broker plugin from CI lastSuccessfulBuild; default true"
     echo "[--deployment-location]         Base location for the test deployment; default /tmp"
     echo
     echo "[--gerrit-canonical-host]       The default host for Gerrit to be accessed through; default localhost"
@@ -182,7 +182,7 @@
     shift
   ;;
   "--get-websession-plugin")
-    DOWNLOAD_WEBSESSION_FLATFILE=$2
+    DOWNLOAD_WEBSESSION_PLUGIN=$2
     shift
     shift
   ;;
@@ -274,7 +274,7 @@
 
 # Defaults
 NEW_INSTALLATION=${NEW_INSTALLATION:-"true"}
-DOWNLOAD_WEBSESSION_FLATFILE=${DOWNLOAD_WEBSESSION_FLATFILE:-"true"}
+DOWNLOAD_WEBSESSION_PLUGIN=${DOWNLOAD_WEBSESSION_PLUGIN:-"true"}
 DEPLOYMENT_LOCATION=${DEPLOYMENT_LOCATION:-"/tmp"}
 export GERRIT_CANONICAL_HOSTNAME=${GERRIT_CANONICAL_HOSTNAME:-"localhost"}
 export GERRIT_CANONICAL_PORT=${GERRIT_CANONICAL_PORT:-"8080"}
@@ -319,16 +319,16 @@
 else
   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 master"
-  wget https://gerrit-ci.gerritforge.com/view/Plugins-master/job/plugin-websession-flatfile-bazel-master-master/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\
+if [ $DOWNLOAD_WEBSESSION_PLUGIN = "true" ];then
+  echo "Downloading websession-broker plugin stable 3.0"
+  wget https://gerrit-ci.gerritforge.com/view/Plugins-stable-3.0/job/plugin-websession-broker-gh-bazel-stable-3.0/lastSuccessfulBuild/artifact/bazel-bin/plugins/websession-broker/websession-broker.jar \
+  -O $DEPLOYMENT_LOCATION/websession-broker.jar || { echo >&2 "Cannot download websession-broker plugin: Check internet connection. Abort\
 ing"; exit 1; }
   wget https://gerrit-ci.gerritforge.com/view/Plugins-master/job/plugin-healthcheck-bazel-master-master/lastSuccessfulBuild/artifact/bazel-bin/plugins/healthcheck/healthcheck.jar \
   -O $DEPLOYMENT_LOCATION/healthcheck.jar || { echo >&2 "Cannot download healthcheck plugin: Check internet connection. Abort\
 ing"; exit 1; }
 else
-  echo "Without the websession-flatfile; user login via haproxy will fail."
+  echo "Without the websession-broker; user login via haproxy will fail."
 fi
 
 echo "Downloading zookeeper plugin master"
@@ -336,6 +336,11 @@
   -O $DEPLOYMENT_LOCATION/zookeeper.jar || { echo >&2 "Cannot download zookeeper plugin: Check internet connection. Abort\
 ing"; exit 1; }
 
+echo "Downloading events-broker library stable 3.0"
+  wget https://repo1.maven.org/maven2/com/gerritforge/events-broker/3.0.5/events-broker-3.0.5.jar \
+  -O $DEPLOYMENT_LOCATION/events-broker.jar || { echo >&2 "Cannot download events-broker library: Check internet connection. Abort\
+ing"; exit 1; }
+
 echo "Downloading kafka-events plugin master"
   wget https://gerrit-ci.gerritforge.com/view/Plugins-master/job/plugin-kafka-events-bazel-master-master/lastSuccessfulBuild/artifact/bazel-bin/plugins/kafka-events/kafka-events.jar \
   -O $DEPLOYMENT_LOCATION/kafka-events.jar || { echo >&2 "Cannot download kafka-events plugin: Check internet connection. Abort\
@@ -371,8 +376,8 @@
   echo "Copy multi-site library to lib directory"
   cp -f $DEPLOYMENT_LOCATION/multi-site.jar $LOCATION_TEST_SITE_1/lib/multi-site.jar
 
-  echo "Copy websession-flatfile plugin"
-  cp -f $DEPLOYMENT_LOCATION/websession-flatfile.jar $LOCATION_TEST_SITE_1/plugins/websession-flatfile.jar
+  echo "Copy websession-broker plugin"
+  cp -f $DEPLOYMENT_LOCATION/websession-broker.jar $LOCATION_TEST_SITE_1/plugins/websession-broker.jar
 
   echo "Copy healthcheck plugin"
   cp -f $DEPLOYMENT_LOCATION/healthcheck.jar $LOCATION_TEST_SITE_1/plugins/healthcheck.jar
@@ -380,6 +385,9 @@
   echo "Copy zookeeper plugin"
   cp -f $DEPLOYMENT_LOCATION/zookeeper.jar $LOCATION_TEST_SITE_1/plugins/zookeeper.jar
 
+  echo "Copy events broker library"
+  cp -f $DEPLOYMENT_LOCATION/events-broker.jar $LOCATION_TEST_SITE_1/lib/events-broker.jar
+
   echo "Copy kafka events plugin"
   cp -f $DEPLOYMENT_LOCATION/kafka-events.jar $LOCATION_TEST_SITE_1/plugins/kafka-events.jar
 
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 920cf41..b171c74 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Module.java
@@ -24,11 +24,10 @@
 import com.google.inject.Scopes;
 import com.google.inject.Singleton;
 import com.google.inject.spi.Message;
-import com.googlesource.gerrit.plugins.multisite.broker.BrokerModule;
 import com.googlesource.gerrit.plugins.multisite.cache.CacheModule;
+import com.googlesource.gerrit.plugins.multisite.consumer.SubscriberModule;
 import com.googlesource.gerrit.plugins.multisite.event.EventModule;
 import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderModule;
-import com.googlesource.gerrit.plugins.multisite.forwarder.broker.BrokerForwarderModule;
 import com.googlesource.gerrit.plugins.multisite.forwarder.router.RouterModule;
 import com.googlesource.gerrit.plugins.multisite.index.IndexModule;
 import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.NoopSharedRefDatabase;
@@ -46,12 +45,10 @@
 public class Module extends LifecycleModule {
   private static final Logger log = LoggerFactory.getLogger(Module.class);
   private Configuration config;
-  private BrokerModule brokerModule;
 
   @Inject
-  public Module(Configuration config, BrokerModule brokerModule) {
+  public Module(Configuration config) {
     this.config = config;
-    this.brokerModule = brokerModule;
   }
 
   @Override
@@ -71,10 +68,9 @@
     listener().to(Log4jMessageLogger.class);
     bind(MessageLogger.class).to(Log4jMessageLogger.class);
 
-    install(brokerModule);
+    install(new SubscriberModule());
 
     install(new ForwarderModule());
-    install(new BrokerForwarderModule());
 
     if (config.cache().synchronize()) {
       install(new CacheModule());
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 bd90be4..6a5cbee 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/PluginModule.java
@@ -18,6 +18,10 @@
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.lifecycle.LifecycleModule;
 import com.google.inject.Inject;
+import com.google.inject.Scopes;
+import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
+import com.googlesource.gerrit.plugins.multisite.consumer.MultiSiteConsumerRunner;
+import com.googlesource.gerrit.plugins.multisite.forwarder.broker.BrokerForwarderModule;
 import com.googlesource.gerrit.plugins.multisite.validation.ProjectDeletedSharedDbCleanup;
 
 public class PluginModule extends LifecycleModule {
@@ -30,6 +34,10 @@
 
   @Override
   protected void configure() {
+    bind(BrokerApiWrapper.class).in(Scopes.SINGLETON);
+    install(new BrokerForwarderModule());
+    listener().to(MultiSiteConsumerRunner.class);
+
     if (config.getSharedRefDb().isEnabled()) {
       listener().to(PluginStartup.class);
       DynamicSet.bind(binder(), ProjectDeletedListener.class)
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerModule.java
deleted file mode 100644
index 093b920..0000000
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/broker/BrokerModule.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.googlesource.gerrit.plugins.multisite.broker;
-
-import com.gerritforge.gerrit.eventbroker.BrokerApi;
-import com.google.gerrit.extensions.registration.DynamicItem;
-import com.google.inject.AbstractModule;
-import com.google.inject.Scopes;
-import com.googlesource.gerrit.plugins.multisite.consumer.SubscriberModule;
-
-public class BrokerModule extends AbstractModule {
-
-  @Override
-  protected void configure() {
-    DynamicItem.itemOf(binder(), BrokerApi.class);
-    DynamicItem.bind(binder(), BrokerApi.class).to(BrokerApiNoOp.class).in(Scopes.SINGLETON);
-
-    bind(BrokerApiWrapper.class).in(Scopes.SINGLETON);
-
-    install(new SubscriberModule());
-  }
-}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberModule.java
index ee1430c..afd4d09 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/consumer/SubscriberModule.java
@@ -26,7 +26,6 @@
 
     DynamicSet.setOf(binder(), AbstractSubcriber.class);
     DynamicSet.setOf(binder(), DroppedEventListener.class);
-    listener().to(MultiSiteConsumerRunner.class);
 
     DynamicSet.bind(binder(), AbstractSubcriber.class).to(IndexEventSubscriber.class);
     DynamicSet.bind(binder(), AbstractSubcriber.class).to(StreamEventSubscriber.class);
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index ff6cdff..a868213 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -8,6 +8,8 @@
 
 The masters must be:
 
+* events-broker library must be installed as a library module in the
+  `$GERRIT_SITE/lib` directory of all the masters
 * 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 10b4adb..2df60dd 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/ModuleTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/ModuleTest.java
@@ -17,7 +17,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import com.google.gerrit.server.config.SitePaths;
-import com.googlesource.gerrit.plugins.multisite.broker.BrokerModule;
 import java.io.File;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -37,15 +36,13 @@
   @Mock(answer = Answers.RETURNS_DEEP_STUBS)
   private Configuration configMock;
 
-  @Mock private BrokerModule brokerModule;
-
   @Rule public TemporaryFolder tempFolder = new TemporaryFolder();
 
   private Module module;
 
   @Before
   public void setup() {
-    module = new Module(configMock, brokerModule);
+    module = new Module(configMock);
   }
 
   @Test