Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  Allow to disable health check endpoint
  AbstractIndexRestApiServlet: Log operation type in lower case
  Make debug logging consistent in forwarder and cache servlet
  Use Logger's built-in string formatting
  Restrict endpoints to change health status to admins
  Add unit tests for HealthServlet
  Initial implementation of health servlet

Change-Id: Idb83c5beac343490b8cb7ea031b2fb40863c7f25
diff --git a/WORKSPACE b/WORKSPACE
index 6430d1d..ce8fcd5 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "c183e91a343af59e7bb021c19fee62a1dc6ea6ce",
+    commit = "cbddbc2b9571b1d692fb823ba8791ccd60b52421",
     #local_path = "/home/ehugare/workspaces/bazlets",
 )
 
@@ -18,8 +18,8 @@
 
 # Release Plugin API
 load(
-    "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
-    "gerrit_api",
+   "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
+   "gerrit_api",
 )
 
 # Load release Plugin API
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/ExecutorProvider.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/ExecutorProvider.java
index 666375f..91099b9 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/ExecutorProvider.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/ExecutorProvider.java
@@ -18,9 +18,10 @@
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.inject.Provider;
 import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
 
 public abstract class ExecutorProvider implements Provider<Executor>, LifecycleListener {
-  private WorkQueue.Executor executor;
+  private ExecutorService executor;
 
   protected ExecutorProvider(WorkQueue workQueue, int threadPoolSize, String threadNamePrefix) {
     executor = workQueue.createQueue(threadPoolSize, threadNamePrefix);
@@ -34,7 +35,6 @@
   @Override
   public void stop() {
     executor.shutdown();
-    executor.unregisterWorkQueue();
     executor = null;
   }
 
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedAwareEventBroker.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedAwareEventBroker.java
index 62186c7..fa277c2 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedAwareEventBroker.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedAwareEventBroker.java
@@ -21,6 +21,7 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.events.Event;
 import com.google.gerrit.server.notedb.ChangeNotes.Factory;
+import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -31,10 +32,17 @@
   ForwardedAwareEventBroker(
       DynamicSet<UserScopedEventListener> listeners,
       DynamicSet<EventListener> unrestrictedListeners,
+      PermissionBackend permissionBackend,
       ProjectCache projectCache,
       Factory notesFactory,
       Provider<ReviewDb> dbProvider) {
-    super(listeners, unrestrictedListeners, projectCache, notesFactory, dbProvider);
+    super(
+        listeners,
+        unrestrictedListeners,
+        permissionBackend,
+        projectCache,
+        notesFactory,
+        dbProvider);
   }
 
   @Override
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/EventRestApiServlet.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/EventRestApiServlet.java
index 14b611c..e25e7eb 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/EventRestApiServlet.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/EventRestApiServlet.java
@@ -28,6 +28,7 @@
 import com.google.gerrit.server.events.Event;
 import com.google.gerrit.server.events.EventDeserializer;
 import com.google.gerrit.server.events.SupplierDeserializer;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gwtorm.server.OrmException;
@@ -72,7 +73,7 @@
     } catch (OrmException e) {
       logger.debug("Error trying to find a change ", e);
       sendError(rsp, SC_NOT_FOUND, "Change not found\n");
-    } catch (IOException e) {
+    } catch (IOException | PermissionBackendException e) {
       logger.error("Unable to re-trigger event", e);
       sendError(rsp, SC_BAD_REQUEST, e.getMessage());
     } finally {
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/health/HealthServlet.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/health/HealthServlet.java
index bfdcc12..d01382b 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/health/HealthServlet.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/health/HealthServlet.java
@@ -14,12 +14,14 @@
 
 package com.ericsson.gerrit.plugins.highavailability.health;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
 import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
 import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
 import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
 import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
 
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
@@ -36,17 +38,19 @@
   private static final long serialVersionUID = -1L;
 
   private final Provider<CurrentUser> currentUserProvider;
+  private final PermissionBackend permissionBackend;
   private boolean healthy;
 
   @Inject
-  HealthServlet(Provider<CurrentUser> currentUserProvider) {
+  HealthServlet(Provider<CurrentUser> currentUserProvider, PermissionBackend permissionBackend) {
     this.currentUserProvider = currentUserProvider;
+    this.permissionBackend = permissionBackend;
     this.healthy = true;
   }
 
   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse rsp) {
-    if (!currentUserProvider.get().getCapabilities().canAdministrateServer()) {
+    if (!permissionBackend.user(currentUserProvider.get()).testOrFalse(ADMINISTRATE_SERVER)) {
       sendError(rsp, SC_FORBIDDEN);
       return;
     }
@@ -56,7 +60,7 @@
 
   @Override
   protected void doDelete(HttpServletRequest req, HttpServletResponse rsp) {
-    if (!currentUserProvider.get().getCapabilities().canAdministrateServer()) {
+    if (!permissionBackend.user(currentUserProvider.get()).testOrFalse(ADMINISTRATE_SERVER)) {
       sendError(rsp, SC_FORBIDDEN);
       return;
     }
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/cache/CacheExecutorProviderTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/cache/CacheExecutorProviderTest.java
index fbc11e0..cd90b65 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/cache/CacheExecutorProviderTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/cache/CacheExecutorProviderTest.java
@@ -21,6 +21,7 @@
 
 import com.ericsson.gerrit.plugins.highavailability.Configuration;
 import com.google.gerrit.server.git.WorkQueue;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -31,7 +32,7 @@
 @RunWith(MockitoJUnitRunner.class)
 public class CacheExecutorProviderTest {
 
-  @Mock private WorkQueue.Executor executorMock;
+  @Mock private ScheduledThreadPoolExecutor executorMock;
 
   private CacheExecutorProvider cacheExecutorProvider;
 
@@ -56,7 +57,6 @@
     assertThat(cacheExecutorProvider.get()).isEqualTo(executorMock);
     cacheExecutorProvider.stop();
     verify(executorMock).shutdown();
-    verify(executorMock).unregisterWorkQueue();
     assertThat(cacheExecutorProvider.get()).isNull();
   }
 }
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/event/EventExecutorProviderTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/event/EventExecutorProviderTest.java
index f72ddc9..ee541cc 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/event/EventExecutorProviderTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/event/EventExecutorProviderTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.Mockito.when;
 
 import com.google.gerrit.server.git.WorkQueue;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -28,7 +29,7 @@
 
 @RunWith(MockitoJUnitRunner.class)
 public class EventExecutorProviderTest {
-  @Mock private WorkQueue.Executor executorMock;
+  @Mock private ScheduledThreadPoolExecutor executorMock;
   private EventExecutorProvider eventsExecutorProvider;
 
   @Before
@@ -49,7 +50,6 @@
     assertThat(eventsExecutorProvider.get()).isEqualTo(executorMock);
     eventsExecutorProvider.stop();
     verify(executorMock).shutdown();
-    verify(executorMock).unregisterWorkQueue();
     assertThat(eventsExecutorProvider.get()).isNull();
   }
 }
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedAwareEventBrokerTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedAwareEventBrokerTest.java
index 2a3197d..1183b07 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedAwareEventBrokerTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedAwareEventBrokerTest.java
@@ -35,7 +35,7 @@
     listenerMock = mock(EventListener.class);
     DynamicSet<EventListener> listeners = DynamicSet.emptySet();
     listeners.add(listenerMock);
-    broker = new ForwardedAwareEventBroker(null, listeners, null, null, null);
+    broker = new ForwardedAwareEventBroker(null, listeners, null, null, null, null);
   }
 
   @Test
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/health/HealthServletTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/health/HealthServletTest.java
index 9d1bf2b..b8a69cb 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/health/HealthServletTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/health/HealthServletTest.java
@@ -14,6 +14,7 @@
 
 package com.ericsson.gerrit.plugins.highavailability.health;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
 import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
 import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
 import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
@@ -24,7 +25,8 @@
 import static org.mockito.Mockito.when;
 
 import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.CapabilityControl;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackend.WithUser;
 import com.google.inject.Provider;
 import java.io.IOException;
 import javax.servlet.http.HttpServletResponse;
@@ -39,16 +41,17 @@
 
   @Mock private Provider<CurrentUser> currentUserProviderMock;
   @Mock private CurrentUser currentUserMock;
-  @Mock private CapabilityControl capabilityControlMock;
+  @Mock private PermissionBackend permissionBackendMock;
+  @Mock private WithUser withUserMock;
 
   private HealthServlet servlet;
 
   @Before
   public void setUp() throws Exception {
     when(currentUserProviderMock.get()).thenReturn(currentUserMock);
-    when(currentUserMock.getCapabilities()).thenReturn(capabilityControlMock);
-    when(capabilityControlMock.canAdministrateServer()).thenReturn(true);
-    servlet = new HealthServlet(currentUserProviderMock);
+    when(permissionBackendMock.user(currentUserMock)).thenReturn(withUserMock);
+    when(withUserMock.testOrFalse(ADMINISTRATE_SERVER)).thenReturn(true);
+    servlet = new HealthServlet(currentUserProviderMock, permissionBackendMock);
   }
 
   @Test
@@ -77,7 +80,7 @@
   public void testTransitionToUnhealthyByNonAdmins() throws IOException {
     assertIsHealthy();
 
-    when(capabilityControlMock.canAdministrateServer()).thenReturn(false);
+    when(withUserMock.testOrFalse(ADMINISTRATE_SERVER)).thenReturn(false);
     HttpServletResponse responseMock = mock(HttpServletResponse.class);
     servlet.doDelete(null, responseMock);
     verify(responseMock).sendError(SC_FORBIDDEN);
@@ -109,7 +112,7 @@
     servlet.doDelete(null, mock(HttpServletResponse.class));
     assertIsUnhealthy();
 
-    when(capabilityControlMock.canAdministrateServer()).thenReturn(false);
+    when(withUserMock.testOrFalse(ADMINISTRATE_SERVER)).thenReturn(false);
     HttpServletResponse responseMock = mock(HttpServletResponse.class);
     servlet.doPost(null, responseMock);
     verify(responseMock).sendError(SC_FORBIDDEN);
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandlerTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandlerTest.java
index a8a568e..3f94f21 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandlerTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandlerTest.java
@@ -29,9 +29,9 @@
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.server.git.WorkQueue.Executor;
 import com.google.gwtorm.client.KeyUtil;
 import com.google.gwtorm.server.StandardKeyEncoder;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -120,7 +120,7 @@
 
   @Test
   public void duplicateChangeEventOfAQueuedEventShouldGetDiscarded() {
-    Executor poolMock = mock(Executor.class);
+    ScheduledThreadPoolExecutor poolMock = mock(ScheduledThreadPoolExecutor.class);
     indexEventHandler = new IndexEventHandler(poolMock, PLUGIN_NAME, forwarder);
     indexEventHandler.onChangeIndexed(changeId.get());
     indexEventHandler.onChangeIndexed(changeId.get());
@@ -129,7 +129,7 @@
 
   @Test
   public void duplicateAccountEventOfAQueuedEventShouldGetDiscarded() {
-    Executor poolMock = mock(Executor.class);
+    ScheduledThreadPoolExecutor poolMock = mock(ScheduledThreadPoolExecutor.class);
     indexEventHandler = new IndexEventHandler(poolMock, PLUGIN_NAME, forwarder);
     indexEventHandler.onAccountIndexed(accountId.get());
     indexEventHandler.onAccountIndexed(accountId.get());
@@ -138,7 +138,7 @@
 
   @Test
   public void duplicateGroupEventOfAQueuedEventShouldGetDiscarded() {
-    Executor poolMock = mock(Executor.class);
+    ScheduledThreadPoolExecutor poolMock = mock(ScheduledThreadPoolExecutor.class);
     indexEventHandler = new IndexEventHandler(poolMock, PLUGIN_NAME, forwarder);
     indexEventHandler.onGroupIndexed(accountGroupUUID.get());
     indexEventHandler.onGroupIndexed(accountGroupUUID.get());
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexExecutorProviderTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexExecutorProviderTest.java
index cc4ba99..e897c2c 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexExecutorProviderTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/index/IndexExecutorProviderTest.java
@@ -21,6 +21,7 @@
 
 import com.ericsson.gerrit.plugins.highavailability.Configuration;
 import com.google.gerrit.server.git.WorkQueue;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -30,12 +31,12 @@
 
 @RunWith(MockitoJUnitRunner.class)
 public class IndexExecutorProviderTest {
-  @Mock private WorkQueue.Executor executorMock;
+  @Mock private ScheduledThreadPoolExecutor executorMock;
   private IndexExecutorProvider indexExecutorProvider;
 
   @Before
   public void setUp() throws Exception {
-    executorMock = mock(WorkQueue.Executor.class);
+    executorMock = mock(ScheduledThreadPoolExecutor.class);
     WorkQueue workQueueMock = mock(WorkQueue.class);
     when(workQueueMock.createQueue(4, "Forward-index-event")).thenReturn(executorMock);
     Configuration configMock = mock(Configuration.class, Answers.RETURNS_DEEP_STUBS);
@@ -54,7 +55,6 @@
     assertThat(indexExecutorProvider.get()).isEqualTo(executorMock);
     indexExecutorProvider.stop();
     verify(executorMock).shutdown();
-    verify(executorMock).unregisterWorkQueue();
     assertThat(indexExecutorProvider.get()).isNull();
   }
 }
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheCleanerTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheCleanerTest.java
index 04c73d4..b85ee75 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheCleanerTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheCleanerTest.java
@@ -26,9 +26,9 @@
 
 import com.ericsson.gerrit.plugins.highavailability.Configuration;
 import com.google.gerrit.server.git.WorkQueue;
-import com.google.gerrit.server.git.WorkQueue.Executor;
 import com.google.inject.Provider;
 import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import org.junit.Before;
 import org.junit.Test;
@@ -43,7 +43,7 @@
   private static long CLEANUP_INTERVAL = 5000;
   private static String SOME_PLUGIN_NAME = "somePluginName";
 
-  @Mock private Executor executorMock;
+  @Mock private ScheduledThreadPoolExecutor executorMock;
   @Mock private ScheduledFuture<?> scheduledFutureMock;
   @Mock private WorkQueue workQueueMock;
   @Mock private Provider<CleanupTask> cleanupTaskProviderMock;