Merge branch 'stable-2.16' into stable-3.0

* stable-2.16:
  EventsLogCleaner: Don't use lambda to create tasks
  Add unified prefix '[pluginName]' to both queues and task
  Upgrade bazlets to latest stable-2.15 to build with 2.15.18 API
  Upgrade bazlets to latest stable-2.15
  Upgrade bazlets to latest stable-2.14
  Bazel: Migrate workspace status script to python
  Upgrade bazlets to latest stable-2.16
  Upgrade bazlets to latest stable-2.15
  Upgrade bazlets to latest stable-2.14
  Bump Bazel version to 1.1.0

Change-Id: I7b6a4ebb1782b0a69937cf3e1d76bc043f596625
diff --git a/.bazelrc b/.bazelrc
index 4ed16cf..3ae03ff 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -1,2 +1,2 @@
-build --workspace_status_command=./tools/workspace-status.sh
+build --workspace_status_command="python ./tools/workspace_status.py"
 test --build_tests_only
diff --git a/.bazelversion b/.bazelversion
index 3eefcb9..9084fa2 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-1.0.0
+1.1.0
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventCleanerQueue.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventCleanerQueue.java
index b457018..66fcc81 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventCleanerQueue.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventCleanerQueue.java
@@ -14,6 +14,7 @@
 
 package com.ericsson.gerrit.plugins.eventslog;
 
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.inject.Inject;
@@ -23,16 +24,18 @@
 @Singleton
 public class EventCleanerQueue implements LifecycleListener {
   private final WorkQueue workQueue;
+  private final String pluginName;
   private ScheduledExecutorService pool;
 
   @Inject
-  public EventCleanerQueue(WorkQueue workQueue) {
+  public EventCleanerQueue(WorkQueue workQueue, @PluginName String pluginName) {
     this.workQueue = workQueue;
+    this.pluginName = pluginName;
   }
 
   @Override
   public void start() {
-    pool = workQueue.createQueue(1, "[events-log] Remove events");
+    pool = workQueue.createQueue(1, String.format("[%s] Remove events", pluginName));
   }
 
   @Override
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventQueue.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventQueue.java
index 72c3c5a..4d2ba5d 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventQueue.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventQueue.java
@@ -14,6 +14,7 @@
 
 package com.ericsson.gerrit.plugins.eventslog;
 
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.inject.Inject;
@@ -22,17 +23,19 @@
 /** A queue for events to store. */
 public class EventQueue implements LifecycleListener {
   private final WorkQueue workQueue;
+  private final String pluginName;
   private ScheduledExecutorService pool;
 
   @Inject
-  EventQueue(WorkQueue workQueue) {
+  EventQueue(WorkQueue workQueue, @PluginName String pluginName) {
     this.workQueue = workQueue;
+    this.pluginName = pluginName;
   }
 
   /** {@inheritDoc} Create a new executor queue in WorkQueue for storing events. */
   @Override
   public void start() {
-    pool = workQueue.createQueue(1, "Store events");
+    pool = workQueue.createQueue(1, String.format("[%s] Store events", pluginName));
   }
 
   @Override
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/EventsLogCleaner.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/EventsLogCleaner.java
index b092829..efff521 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/EventsLogCleaner.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/EventsLogCleaner.java
@@ -15,6 +15,7 @@
 package com.ericsson.gerrit.plugins.eventslog.sql;
 
 import com.ericsson.gerrit.plugins.eventslog.EventCleanerPool;
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.events.ProjectDeletedListener;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -31,12 +32,17 @@
   private static final long INTERVAL = TimeUnit.DAYS.toSeconds(1);
 
   private final SQLClient eventsDb;
+  private final String pluginName;
 
   private ScheduledExecutorService pool;
 
   @Inject
-  EventsLogCleaner(@EventsDb SQLClient eventsDb, @EventCleanerPool ScheduledExecutorService pool) {
+  EventsLogCleaner(
+      @EventsDb SQLClient eventsDb,
+      @EventCleanerPool ScheduledExecutorService pool,
+      @PluginName String pluginName) {
     this.eventsDb = eventsDb;
+    this.pluginName = pluginName;
     this.pool = pool;
   }
 
@@ -46,12 +52,12 @@
   }
 
   public void removeProjectEventsAsync(String projectName) {
-    pool.submit(() -> eventsDb.removeProjectEvents(projectName));
+    pool.submit(new RemoveProjectEventsTask(pluginName, projectName));
   }
 
   public void scheduleCleaningWith(int maxAge) {
     pool.scheduleAtFixedRate(
-        () -> eventsDb.removeOldEvents(maxAge), getInitialDelay(), INTERVAL, TimeUnit.SECONDS);
+        new RemoveOldEventsTask(pluginName, maxAge), getInitialDelay(), INTERVAL, TimeUnit.SECONDS);
   }
 
   private long getInitialDelay() {
@@ -62,4 +68,44 @@
     }
     return Duration.between(now, next).getSeconds();
   }
+
+  private class RemoveProjectEventsTask implements Runnable {
+    private final String projectName;
+    private final String taskName;
+
+    RemoveProjectEventsTask(String prefix, String projectName) {
+      this.projectName = projectName;
+      this.taskName = String.format("[%s] Remove events for project %s", prefix, projectName);
+    }
+
+    @Override
+    public void run() {
+      eventsDb.removeProjectEvents(projectName);
+    }
+
+    @Override
+    public String toString() {
+      return taskName;
+    }
+  }
+
+  private class RemoveOldEventsTask implements Runnable {
+    private final int maxAge;
+    private final String taskName;
+
+    RemoveOldEventsTask(String prefix, int maxAge) {
+      this.maxAge = maxAge;
+      this.taskName = String.format("[%s] Remove old events", prefix);
+    }
+
+    @Override
+    public void run() {
+      eventsDb.removeOldEvents(maxAge);
+    }
+
+    @Override
+    public String toString() {
+      return taskName;
+    }
+  }
 }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java
index 6289c2d..1717570 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java
@@ -23,6 +23,7 @@
 import com.ericsson.gerrit.plugins.eventslog.EventsLogException;
 import com.ericsson.gerrit.plugins.eventslog.ServiceUnavailableException;
 import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.events.LifecycleListener;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.reviewdb.client.Project;
@@ -62,6 +63,7 @@
   private boolean copyLocal;
   private final ScheduledExecutorService pool;
   private final PermissionBackend permissionBackend;
+  private final String pluginName;
   private ScheduledFuture<?> checkConnTask;
   private Path localPath;
 
@@ -72,7 +74,8 @@
       @LocalEventsDb SQLClient localEventsDb,
       @EventPool ScheduledExecutorService pool,
       PermissionBackend permissionBackend,
-      EventsLogCleaner eventsLogCleaner) {
+      EventsLogCleaner eventsLogCleaner,
+      @PluginName String pluginName) {
     this.maxAge = cfg.getMaxAge();
     this.maxTries = cfg.getMaxTries();
     this.waitTime = cfg.getWaitTime();
@@ -84,6 +87,7 @@
     this.pool = pool;
     this.permissionBackend = permissionBackend;
     this.localPath = cfg.getLocalStorePath();
+    this.pluginName = pluginName;
   }
 
   @Override
@@ -197,7 +201,7 @@
     if (!online) {
       checkConnTask =
           pool.scheduleWithFixedDelay(
-              new CheckConnectionTask(), 0, connectTime, TimeUnit.MILLISECONDS);
+              new CheckConnectionTask(pluginName), 0, connectTime, TimeUnit.MILLISECONDS);
     } else {
       cancelCheckConnectionTaskIfScheduled(false);
     }
@@ -238,7 +242,11 @@
   }
 
   class CheckConnectionTask implements Runnable {
-    CheckConnectionTask() {}
+    private final String taskName;
+
+    CheckConnectionTask(String prefix) {
+      this.taskName = String.format("[%s] Connect to database", prefix);
+    }
 
     @Override
     public void run() {
@@ -250,7 +258,7 @@
 
     @Override
     public String toString() {
-      return "(Events-log) Connect to database";
+      return taskName;
     }
 
     private boolean checkConnection() {
diff --git a/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/EventsLogCleanerTest.java b/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/EventsLogCleanerTest.java
index 09c21dc..11fa891 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/EventsLogCleanerTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/EventsLogCleanerTest.java
@@ -32,6 +32,7 @@
 @RunWith(MockitoJUnitRunner.class)
 public class EventsLogCleanerTest {
   private static final String PROJECT = "testProject";
+  private static final String PLUGIN_NAME = "events-log";
 
   @Mock private EventsLogConfig cfgMock;
   @Mock private EventsLogCleaner logCleanerMock;
@@ -44,7 +45,7 @@
   @Before
   public void setUp() throws Exception {
     when(event.getProjectName()).thenReturn(PROJECT);
-    eventsLogCleaner = new EventsLogCleaner(eventsDb, executor);
+    eventsLogCleaner = new EventsLogCleaner(eventsDb, executor, PLUGIN_NAME);
   }
 
   @Test
diff --git a/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java b/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java
index 68b9801..89448e4 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java
@@ -66,6 +66,7 @@
   private static final String TERM_CONN_MSG = "terminating connection";
   private static final String MSG = "message";
   private static final String GENERIC_QUERY = "SELECT * FROM " + TABLE_NAME;
+  private static final String PLUGIN_NAME = "events-log";
 
   @Mock private EventsLogConfig cfgMock;
   @Mock private PermissionBackend permissionBackendMock;
@@ -159,7 +160,13 @@
     doThrow(exceptions).doNothing().when(eventsDb).queryOne();
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
     store.storeEvent(mockEvent);
@@ -178,7 +185,13 @@
 
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
     store.storeEvent(mockEvent);
@@ -194,7 +207,13 @@
 
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
     store.storeEvent(mockEvent);
@@ -212,7 +231,13 @@
 
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
     store.storeEvent(mockEvent);
@@ -227,7 +252,13 @@
 
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
     store.storeEvent(mockEvent);
@@ -249,7 +280,13 @@
     localEventsDb = new SQLClient(config);
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     localEventsDb.createDBIfNotCreated();
     localEventsDb.storeEvent(mockEvent);
@@ -274,7 +311,13 @@
 
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
     verify(localEventsDb).createDBIfNotCreated();
@@ -288,7 +331,13 @@
 
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
     store.storeEvent(mockEvent);
@@ -304,7 +353,13 @@
 
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
     store.storeEvent(mockEvent);
@@ -317,7 +372,13 @@
     localEventsDb = new SQLClient(config);
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
   }
@@ -343,10 +404,17 @@
 
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
-    poolMock.scheduleWithFixedDelay(store.new CheckConnectionTask(), 0, 0, TimeUnit.MILLISECONDS);
+    poolMock.scheduleWithFixedDelay(
+        store.new CheckConnectionTask(PLUGIN_NAME), 0, 0, TimeUnit.MILLISECONDS);
     verify(localEventsDb, times(2)).removeOldEvents(0);
   }
 
@@ -377,7 +445,13 @@
 
     store =
         new SQLStore(
-            cfgMock, eventsDb, localEventsDb, poolMock, permissionBackendMock, logCleanerMock);
+            cfgMock,
+            eventsDb,
+            localEventsDb,
+            poolMock,
+            permissionBackendMock,
+            logCleanerMock,
+            PLUGIN_NAME);
 
     store.start();
     verify(eventsDb).queryOne();
diff --git a/tools/workspace-status.sh b/tools/workspace-status.sh
deleted file mode 100755
index 4e63364..0000000
--- a/tools/workspace-status.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-#This script will be run by bazel when the build process starts to
-# generate key-value information that represents the status of the
-# workspace. The output should be like
-#
-# KEY1 VALUE1
-# KEY2 VALUE2
-#
-# If the script exits with non-zero code, it's considered as a failure
-# and the output will be discarded.
-
-function rev() {
-  cd $1; git describe --always --match "v[0-9].*" --dirty
-}
-
-echo STABLE_BUILD_EVENTS-LOG_LABEL $(rev .)
diff --git a/tools/workspace_status.py b/tools/workspace_status.py
new file mode 100644
index 0000000..0374813
--- /dev/null
+++ b/tools/workspace_status.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+# This script will be run by bazel when the build process starts to
+# generate key-value information that represents the status of the
+# workspace. The output should be like
+#
+# KEY1 VALUE1
+# KEY2 VALUE2
+#
+# If the script exits with non-zero code, it's considered as a failure
+# and the output will be discarded.
+
+from __future__ import print_function
+import subprocess
+import sys
+
+CMD = ['git', 'describe', '--always', '--match', 'v[0-9].*', '--dirty']
+
+
+def revision():
+    try:
+        return subprocess.check_output(CMD).strip().decode("utf-8")
+    except OSError as err:
+        print('could not invoke git: %s' % err, file=sys.stderr)
+        sys.exit(1)
+    except subprocess.CalledProcessError as err:
+        print('error using git: %s' % err, file=sys.stderr)
+        sys.exit(1)
+
+
+print("STABLE_BUILD_EVENTS-LOG_LABEL %s" % revision())