Allow restricting event types using the global configuration

Allow admins to specify which event types can be posted to the
configured listeners. Unrestrictive remote configurations, where
events are not filtered, can cause too many events to be scheduled
on a busy server. With this new global configuration, admins will
have better control over which events can be configured in remote
configurations.

Change-Id: If863ec04eb1fbb0912e638ef9906901957068afb
diff --git a/src/main/java/com/googlesource/gerrit/plugins/webhooks/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/webhooks/Configuration.java
index 10e7110..44026fc 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/webhooks/Configuration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/webhooks/Configuration.java
@@ -22,6 +22,9 @@
 
 @Singleton
 public class Configuration {
+  public static final String THREAD_POOL_SIZE = "threadPoolSize";
+  public static final String ALLOWED_EVENT = "allowedEvent";
+
   public static final int DEFAULT_TIMEOUT_MS = 5000;
   public static final int DEFAULT_MAX_TRIES = 5;
   public static final int DEFAULT_RETRY_INTERVAL = 1000;
@@ -34,6 +37,7 @@
   private final int retryInterval;
   private final int threadPoolSize;
   private final boolean sslVerify;
+  private final String[] allowedEvents;
 
   @Inject
   protected Configuration(PluginConfigFactory config, @PluginName String pluginName) {
@@ -42,8 +46,9 @@
     socketTimeout = cfg.getInt(RemoteConfig.SOCKET_TIMEOUT, DEFAULT_TIMEOUT_MS);
     maxTries = cfg.getInt(RemoteConfig.MAX_TRIES, DEFAULT_MAX_TRIES);
     retryInterval = cfg.getInt(RemoteConfig.RETRY_INTERVAL, DEFAULT_RETRY_INTERVAL);
-    threadPoolSize = cfg.getInt("threadPoolSize", DEFAULT_THREAD_POOL_SIZE);
+    threadPoolSize = cfg.getInt(THREAD_POOL_SIZE, DEFAULT_THREAD_POOL_SIZE);
     sslVerify = cfg.getBoolean(RemoteConfig.SSL_VERIFY, DEFAULT_SSL_VERIFY);
+    allowedEvents = cfg.getStringList(ALLOWED_EVENT);
   }
 
   public int getConnectionTimeout() {
@@ -69,4 +74,8 @@
   public boolean getSslVerify() {
     return sslVerify;
   }
+
+  public String[] getAllowedEvents() {
+    return allowedEvents;
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/webhooks/RemoteConfig.java b/src/main/java/com/googlesource/gerrit/plugins/webhooks/RemoteConfig.java
index 80e40d2..542a3a9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/webhooks/RemoteConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/webhooks/RemoteConfig.java
@@ -16,6 +16,8 @@
 
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
+import java.util.Arrays;
+import java.util.List;
 import org.eclipse.jgit.lib.Config;
 
 public class RemoteConfig {
@@ -50,7 +52,19 @@
   }
 
   public String[] getEvents() {
-    return config.getStringList(REMOTE, name, "event");
+    String[] globalAllowedEvents = global.getAllowedEvents();
+    String[] remoteEvents = config.getStringList(REMOTE, name, "event");
+    if (globalAllowedEvents.length > 0) {
+      if (remoteEvents.length > 0) {
+        List<String> globalAllowedEventsList = Arrays.asList(globalAllowedEvents);
+        return Arrays.stream(remoteEvents)
+            .distinct()
+            .filter(globalAllowedEventsList::contains)
+            .toArray(String[]::new);
+      }
+      return globalAllowedEvents;
+    }
+    return remoteEvents;
   }
 
   public int getConnectionTimeout() {
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index b6614e9..88f99f1 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -66,6 +66,12 @@
     when payload is delivered.
     Default value is 'false'.
 
+@PLUGIN@.allowedEvent
+:   Type of the event which is allowed to be posted to the remote url.
+    Multiple event types can be provided. If not specified, then all event
+    types are allowed.
+
+
 File '@PLUGIN@.config'
 ----------------------
 
@@ -73,9 +79,11 @@
 : Address of the remote server to post events to.
 
 <a id="event"> remote.NAME.event
-: Type of the event which will be posted to the remote url. Multiple event
-  types can be specified, listing event types which should be posted.
-  When no event type is configured, all events will be posted.
+: Type of the event which will be posted to the remote url. If this event is
+  not an allowed one in the global configuration, then it won't be posted.
+  Multiple event types can be specified, listing event types which should be
+  posted. If no event type is configured, only the allowed events from the
+  global configuration will be posted.
 
 <a id="connectionTimeout"> remote.NAME.connectionTimeout
 : Maximum interval of time in milliseconds the plugin waits for a connection