Consolidate time units in Configuration class, use Duration

Handling the time units for the methods in the Configruation like
timeout, retryInterval, delay, ... was inconsistent:
* most of the methods returned milliseconds as int
* some of the methods returned seconds as int
* some of the constants representing defaults contained the unit as
  their suffix i.e. "_MS"
* some of the constants with the defaults didn't contain the unit in
  their name

In addition, the caller had to know what the returned int represents.

With this change, all these methods in the Configuration class return
Duration. Duration is an amount of time that can be accessed using any
time unit as needed by the caller.

Change-Id: Idc9e16756967735d7db95448f25be1ba63128a01
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/Configuration.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/Configuration.java
index 1c68d7e..1165459 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/Configuration.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/Configuration.java
@@ -14,7 +14,6 @@
 
 package com.ericsson.gerrit.plugins.highavailability;
 
-import static java.util.concurrent.TimeUnit.HOURS;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
 import com.gerritforge.gerrit.globalrefdb.validation.SharedRefDbConfiguration;
@@ -33,13 +32,13 @@
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.time.Duration;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Config;
@@ -51,7 +50,7 @@
   private static final FluentLogger log = FluentLogger.forEnclosingClass();
 
   public static final int DEFAULT_NUM_STRIPED_LOCKS = 10;
-  public static final int DEFAULT_TIMEOUT_MS = 5000;
+  public static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(5);
   public static final String PLUGIN_NAME = "high-availability";
   public static final String PLUGIN_CONFIG_FILE = PLUGIN_NAME + ".config";
 
@@ -202,8 +201,10 @@
     }
   }
 
-  private static int getMilliseconds(Config cfg, String section, String setting, int defaultValue) {
-    return (int) ConfigUtil.getTimeUnit(cfg, section, null, setting, defaultValue, MILLISECONDS);
+  private static Duration getDuration(
+      Config cfg, String section, String setting, Duration defaultValue) {
+    return Duration.ofMillis(
+        ConfigUtil.getTimeUnit(cfg, section, null, setting, defaultValue.toMillis(), MILLISECONDS));
   }
 
   public static class Main {
@@ -246,38 +247,29 @@
     static final String DELAY = "delay";
     static final String POLL_INTERVAL = "pollInterval";
     static final boolean DEFAULT_AUTO_REINDEX = false;
-    static final long DEFAULT_DELAY = 10L;
-    static final long DEFAULT_POLL_INTERVAL = 0L;
+    static final Duration DEFAULT_DELAY = Duration.ofSeconds(10);
+    static final Duration DEFAULT_POLL_INTERVAL = Duration.ZERO;
 
     private final boolean enabled;
-    private final long delaySec;
-    private final long pollSec;
+    private final Duration delay;
+    private final Duration pollInterval;
 
     public AutoReindex(Config cfg) {
       enabled = cfg.getBoolean(AUTO_REINDEX_SECTION, ENABLED, DEFAULT_AUTO_REINDEX);
-      delaySec =
-          ConfigUtil.getTimeUnit(
-              cfg, AUTO_REINDEX_SECTION, null, DELAY, DEFAULT_DELAY, TimeUnit.SECONDS);
-      pollSec =
-          ConfigUtil.getTimeUnit(
-              cfg,
-              AUTO_REINDEX_SECTION,
-              null,
-              POLL_INTERVAL,
-              DEFAULT_POLL_INTERVAL,
-              TimeUnit.SECONDS);
+      delay = getDuration(cfg, AUTO_REINDEX_SECTION, DELAY, DEFAULT_DELAY);
+      pollInterval = getDuration(cfg, AUTO_REINDEX_SECTION, POLL_INTERVAL, DEFAULT_POLL_INTERVAL);
     }
 
     public boolean enabled() {
       return enabled;
     }
 
-    public long delaySec() {
-      return delaySec;
+    public Duration delay() {
+      return delay;
     }
 
-    public long pollSec() {
-      return pollSec;
+    public Duration pollInterval() {
+      return pollInterval;
     }
   }
 
@@ -341,7 +333,7 @@
 
   public static class JGroups {
     static final int DEFAULT_MAX_TRIES = 720;
-    static final int DEFAULT_RETRY_INTERVAL = 10000;
+    static final Duration DEFAULT_RETRY_INTERVAL = Duration.ofSeconds(10);
 
     static final String SKIP_INTERFACE_KEY = "skipInterface";
     static final String CLUSTER_NAME_KEY = "clusterName";
@@ -356,9 +348,9 @@
 
     private final ImmutableList<String> skipInterface;
     private final String clusterName;
-    private final int timeout;
+    private final Duration timeout;
     private final int maxTries;
-    private final int retryInterval;
+    private final Duration retryInterval;
     private final boolean useKubernetes;
     private final Optional<Path> protocolStack;
 
@@ -368,10 +360,9 @@
       log.atFine().log("Skip interface(s): %s", skipInterface);
       clusterName = getString(cfg, JGROUPS_SECTION, null, CLUSTER_NAME_KEY, DEFAULT_CLUSTER_NAME);
       log.atFine().log("Cluster name: %s", clusterName);
-      timeout = getMilliseconds(cfg, JGROUPS_SECTION, TIMEOUT_KEY, DEFAULT_TIMEOUT_MS);
+      timeout = getDuration(cfg, JGROUPS_SECTION, TIMEOUT_KEY, DEFAULT_TIMEOUT);
       maxTries = getInt(cfg, JGROUPS_SECTION, MAX_TRIES_KEY, DEFAULT_MAX_TRIES);
-      retryInterval =
-          getMilliseconds(cfg, JGROUPS_SECTION, RETRY_INTERVAL_KEY, DEFAULT_RETRY_INTERVAL);
+      retryInterval = getDuration(cfg, JGROUPS_SECTION, RETRY_INTERVAL_KEY, DEFAULT_RETRY_INTERVAL);
       useKubernetes = cfg.getBoolean(JGROUPS_SECTION, KUBERNETES_KEY, false);
       protocolStack = getProtocolStack(cfg, site);
       log.atFine().log(
@@ -402,7 +393,7 @@
       return clusterName;
     }
 
-    public int timeout() {
+    public Duration timeout() {
       return timeout;
     }
 
@@ -410,7 +401,7 @@
       return maxTries;
     }
 
-    public int retryInterval() {
+    public Duration retryInterval() {
       return retryInterval;
     }
 
@@ -443,7 +434,7 @@
 
   public static class Http {
     public static final int DEFAULT_MAX_TRIES = 360;
-    public static final int DEFAULT_RETRY_INTERVAL = 10000;
+    public static final Duration DEFAULT_RETRY_INTERVAL = Duration.ofSeconds(10);
 
     static final String HTTP_SECTION = "http";
     static final String USER_KEY = "user";
@@ -455,20 +446,18 @@
 
     private final String user;
     private final String password;
-    private final int connectionTimeout;
-    private final int socketTimeout;
+    private final Duration connectionTimeout;
+    private final Duration socketTimeout;
     private final int maxTries;
-    private final int retryInterval;
+    private final Duration retryInterval;
 
     private Http(Config cfg) {
       user = Strings.nullToEmpty(cfg.getString(HTTP_SECTION, null, USER_KEY));
       password = Strings.nullToEmpty(cfg.getString(HTTP_SECTION, null, PASSWORD_KEY));
-      connectionTimeout =
-          getMilliseconds(cfg, HTTP_SECTION, CONNECTION_TIMEOUT_KEY, DEFAULT_TIMEOUT_MS);
-      socketTimeout = getMilliseconds(cfg, HTTP_SECTION, SOCKET_TIMEOUT_KEY, DEFAULT_TIMEOUT_MS);
+      connectionTimeout = getDuration(cfg, HTTP_SECTION, CONNECTION_TIMEOUT_KEY, DEFAULT_TIMEOUT);
+      socketTimeout = getDuration(cfg, HTTP_SECTION, SOCKET_TIMEOUT_KEY, DEFAULT_TIMEOUT);
       maxTries = getInt(cfg, HTTP_SECTION, MAX_TRIES_KEY, DEFAULT_MAX_TRIES);
-      retryInterval =
-          getMilliseconds(cfg, HTTP_SECTION, RETRY_INTERVAL_KEY, DEFAULT_RETRY_INTERVAL);
+      retryInterval = getDuration(cfg, HTTP_SECTION, RETRY_INTERVAL_KEY, DEFAULT_RETRY_INTERVAL);
     }
 
     public String user() {
@@ -479,11 +468,11 @@
       return password;
     }
 
-    public int connectionTimeout() {
+    public Duration connectionTimeout() {
       return connectionTimeout;
     }
 
-    public int socketTimeout() {
+    public Duration socketTimeout() {
       return socketTimeout;
     }
 
@@ -491,7 +480,7 @@
       return maxTries;
     }
 
-    public int retryInterval() {
+    public Duration retryInterval() {
       return retryInterval;
     }
   }
@@ -564,7 +553,7 @@
 
   public static class Index extends Forwarding {
     static final int DEFAULT_MAX_TRIES = 2;
-    static final int DEFAULT_RETRY_INTERVAL = 30000;
+    static final Duration DEFAULT_RETRY_INTERVAL = Duration.ofSeconds(30);
 
     static final String INDEX_SECTION = "index";
     static final String MAX_TRIES_KEY = "maxTries";
@@ -574,7 +563,7 @@
 
     private final int threadPoolSize;
     private final int batchThreadPoolSize;
-    private final int retryInterval;
+    private final Duration retryInterval;
     private final int maxTries;
     private final int numStripedLocks;
     private final boolean synchronizeForced;
@@ -584,8 +573,7 @@
       threadPoolSize = getInt(cfg, INDEX_SECTION, THREAD_POOL_SIZE_KEY, DEFAULT_THREAD_POOL_SIZE);
       batchThreadPoolSize = getInt(cfg, INDEX_SECTION, BATCH_THREAD_POOL_SIZE_KEY, threadPoolSize);
       numStripedLocks = getInt(cfg, INDEX_SECTION, NUM_STRIPED_LOCKS, DEFAULT_NUM_STRIPED_LOCKS);
-      retryInterval =
-          getMilliseconds(cfg, INDEX_SECTION, RETRY_INTERVAL_KEY, DEFAULT_RETRY_INTERVAL);
+      retryInterval = getDuration(cfg, INDEX_SECTION, RETRY_INTERVAL_KEY, DEFAULT_RETRY_INTERVAL);
       maxTries = getInt(cfg, INDEX_SECTION, MAX_TRIES_KEY, DEFAULT_MAX_TRIES);
       synchronizeForced =
           cfg.getBoolean(INDEX_SECTION, SYNCHRONIZE_FORCED_KEY, DEFAULT_SYNCHRONIZE_FORCED);
@@ -603,7 +591,7 @@
       return numStripedLocks;
     }
 
-    public int retryInterval() {
+    public Duration retryInterval() {
       return retryInterval;
     }
 
@@ -619,21 +607,18 @@
   public static class Websession extends Forwarding {
     static final String WEBSESSION_SECTION = "websession";
     static final String CLEANUP_INTERVAL_KEY = "cleanupInterval";
-    static final String DEFAULT_CLEANUP_INTERVAL = "24 hours";
-    static final long DEFAULT_CLEANUP_INTERVAL_MS = HOURS.toMillis(24);
+    static final String DEFAULT_CLEANUP_INTERVAL_AS_STRING = "24 hours";
+    static final Duration DEFAULT_CLEANUP_INTERVAL = Duration.ofHours(24);
 
-    private final long cleanupInterval;
+    private final Duration cleanupInterval;
 
     private Websession(Config cfg) {
       super(cfg, WEBSESSION_SECTION);
       cleanupInterval =
-          ConfigUtil.getTimeUnit(
-              Strings.nullToEmpty(cfg.getString(WEBSESSION_SECTION, null, CLEANUP_INTERVAL_KEY)),
-              DEFAULT_CLEANUP_INTERVAL_MS,
-              MILLISECONDS);
+          getDuration(cfg, WEBSESSION_SECTION, CLEANUP_INTERVAL_KEY, DEFAULT_CLEANUP_INTERVAL);
     }
 
-    public long cleanupInterval() {
+    public Duration cleanupInterval() {
       return cleanupInterval;
     }
   }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/Setup.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/Setup.java
index 8a267d6..a089b23 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/Setup.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/Setup.java
@@ -24,7 +24,7 @@
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Cache.CACHE_SECTION;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Cache.PATTERN_KEY;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_THREAD_POOL_SIZE;
-import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_TIMEOUT_MS;
+import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_TIMEOUT;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Event.EVENT_SECTION;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Forwarding.DEFAULT_SYNCHRONIZE;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Forwarding.SYNCHRONIZE_KEY;
@@ -55,7 +55,7 @@
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.PeerInfoStatic.URL_KEY;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.THREAD_POOL_SIZE_KEY;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Websession.CLEANUP_INTERVAL_KEY;
-import static com.ericsson.gerrit.plugins.highavailability.Configuration.Websession.DEFAULT_CLEANUP_INTERVAL;
+import static com.ericsson.gerrit.plugins.highavailability.Configuration.Websession.DEFAULT_CLEANUP_INTERVAL_AS_STRING;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Websession.WEBSESSION_SECTION;
 
 import com.ericsson.gerrit.plugins.highavailability.Configuration.PeerInfoStrategy;
@@ -135,7 +135,8 @@
     config.setBoolean(AUTO_REINDEX_SECTION, null, ENABLED, autoReindex);
 
     String delay =
-        promptAndSetString("Delay", AUTO_REINDEX_SECTION, DELAY, numberToString(DEFAULT_DELAY));
+        promptAndSetString(
+            "Delay", AUTO_REINDEX_SECTION, DELAY, numberToString(DEFAULT_DELAY.toMillis()));
     config.setLong(AUTO_REINDEX_SECTION, null, DELAY, Long.valueOf(delay));
 
     String pollInterval =
@@ -143,7 +144,7 @@
             "Poll interval",
             AUTO_REINDEX_SECTION,
             POLL_INTERVAL,
-            numberToString(DEFAULT_POLL_INTERVAL));
+            numberToString(DEFAULT_POLL_INTERVAL.toMillis()));
     config.setLong(AUTO_REINDEX_SECTION, null, POLL_INTERVAL, Long.valueOf(pollInterval));
   }
 
@@ -203,17 +204,17 @@
         "Retry interval [ms]",
         HTTP_SECTION,
         RETRY_INTERVAL_KEY,
-        numberToString(DEFAULT_RETRY_INTERVAL));
+        numberToString(DEFAULT_RETRY_INTERVAL.toMillis()));
     promptAndSetString(
         "Connection timeout [ms]",
         HTTP_SECTION,
         CONNECTION_TIMEOUT_KEY,
-        numberToString(DEFAULT_TIMEOUT_MS));
+        numberToString(DEFAULT_TIMEOUT.toMillis()));
     promptAndSetString(
         "Socket timeout [ms]",
         HTTP_SECTION,
         SOCKET_TIMEOUT_KEY,
-        numberToString(DEFAULT_TIMEOUT_MS));
+        numberToString(DEFAULT_TIMEOUT.toMillis()));
   }
 
   private void configureCacheSection() {
@@ -247,7 +248,10 @@
     ui.header("Websession section");
     promptAndSetSynchronize("Websession", WEBSESSION_SECTION);
     promptAndSetString(
-        "Cleanup interval", WEBSESSION_SECTION, CLEANUP_INTERVAL_KEY, DEFAULT_CLEANUP_INTERVAL);
+        "Cleanup interval",
+        WEBSESSION_SECTION,
+        CLEANUP_INTERVAL_KEY,
+        DEFAULT_CLEANUP_INTERVAL_AS_STRING);
   }
 
   private void configureHealthCheckSection() {
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/autoreindex/AutoReindexScheduler.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/autoreindex/AutoReindexScheduler.java
index ef7ae86..e948ba4 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/autoreindex/AutoReindexScheduler.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/autoreindex/AutoReindexScheduler.java
@@ -20,6 +20,7 @@
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Future;
@@ -55,27 +56,24 @@
 
   @Override
   public void start() {
-    if (cfg.pollSec() > 0) {
+    if (cfg.pollInterval().compareTo(Duration.ZERO) > 0) {
       log.atInfo().log(
-          "Scheduling auto-reindex after %ds and every %ds", cfg.delaySec(), cfg.pollSec());
-      futureTasks.add(
-          executor.scheduleAtFixedRate(
-              changeReindex, cfg.delaySec(), cfg.pollSec(), TimeUnit.SECONDS));
-      futureTasks.add(
-          executor.scheduleAtFixedRate(
-              accountReindex, cfg.delaySec(), cfg.pollSec(), TimeUnit.SECONDS));
-      futureTasks.add(
-          executor.scheduleAtFixedRate(
-              groupReindex, cfg.delaySec(), cfg.pollSec(), TimeUnit.SECONDS));
-      futureTasks.add(
-          executor.scheduleAtFixedRate(
-              projectReindex, cfg.delaySec(), cfg.pollSec(), TimeUnit.SECONDS));
+          "Scheduling auto-reindex after %s and every %s", cfg.delay(), cfg.pollInterval());
+      for (Runnable reindexTask :
+          List.of(changeReindex, accountReindex, groupReindex, projectReindex)) {
+        futureTasks.add(
+            executor.scheduleAtFixedRate(
+                reindexTask,
+                cfg.delay().toSeconds(),
+                cfg.pollInterval().toSeconds(),
+                TimeUnit.SECONDS));
+      }
     } else {
-      log.atInfo().log("Scheduling auto-reindex after %ds", cfg.delaySec());
-      futureTasks.add(executor.schedule(changeReindex, cfg.delaySec(), TimeUnit.SECONDS));
-      futureTasks.add(executor.schedule(accountReindex, cfg.delaySec(), TimeUnit.SECONDS));
-      futureTasks.add(executor.schedule(groupReindex, cfg.delaySec(), TimeUnit.SECONDS));
-      futureTasks.add(executor.schedule(projectReindex, cfg.delaySec(), TimeUnit.SECONDS));
+      log.atInfo().log("Scheduling auto-reindex after %s", cfg.delay());
+      for (Runnable reindexTask :
+          List.of(changeReindex, accountReindex, groupReindex, projectReindex)) {
+        futureTasks.add(executor.schedule(reindexTask, cfg.delay().toSeconds(), TimeUnit.SECONDS));
+      }
     }
   }
 
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedIndexChangeHandler.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedIndexChangeHandler.java
index 770259d..ab8895b 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedIndexChangeHandler.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/ForwardedIndexChangeHandler.java
@@ -31,6 +31,7 @@
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
+import java.time.Duration;
 import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.ScheduledExecutorService;
@@ -47,7 +48,7 @@
   private final ChangeIndexer indexer;
   private final ScheduledExecutorService indexExecutor;
   private final OneOffRequestContext oneOffCtx;
-  private final int retryInterval;
+  private final Duration retryInterval;
   private final int maxTries;
   private final ChangeCheckerImpl.Factory changeCheckerFactory;
 
@@ -64,7 +65,7 @@
     this.changeCheckerFactory = changeCheckerFactory;
 
     Index indexConfig = config.index();
-    this.retryInterval = indexConfig != null ? indexConfig.retryInterval() : 0;
+    this.retryInterval = indexConfig != null ? indexConfig.retryInterval() : Duration.ZERO;
     this.maxTries = indexConfig != null ? indexConfig.maxTries() : 0;
   }
 
@@ -136,8 +137,7 @@
     }
 
     log.atWarning().log(
-        "Retrying for the #%d time to index Change %s after %d msecs",
-        retryCount, id, retryInterval);
+        "Retrying for the #%d time to index Change %s after %s", retryCount, id, retryInterval);
     indexExecutor.schedule(
         () -> {
           try (ManualRequestContext ctx = oneOffCtx.open()) {
@@ -147,7 +147,7 @@
             log.atWarning().withCause(e).log("Change %s could not be indexed", id);
           }
         },
-        retryInterval,
+        retryInterval.toMillis(),
         TimeUnit.MILLISECONDS);
     return true;
   }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/jgroups/JGroupsForwarder.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/jgroups/JGroupsForwarder.java
index 117fec9..542e9cb 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/jgroups/JGroupsForwarder.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/jgroups/JGroupsForwarder.java
@@ -109,7 +109,7 @@
         return true;
       }
       try {
-        Thread.sleep(jgroupsConfig.retryInterval());
+        Thread.sleep(jgroupsConfig.retryInterval().toMillis());
       } catch (InterruptedException ie) {
         log.atSevere().withCause(ie).log("%s was interrupted, giving up", cmd);
         Thread.currentThread().interrupt();
@@ -132,7 +132,8 @@
       }
 
       log.atFine().log("Sending %s", json);
-      RequestOptions options = new RequestOptions(ResponseMode.GET_FIRST, jgroupsConfig.timeout());
+      RequestOptions options =
+          new RequestOptions(ResponseMode.GET_FIRST, jgroupsConfig.timeout().toMillis());
       RspList<Object> list = dispatcher.castMessage(null, new ObjectMessage(null, json), options);
 
       log.atFine().log("Received response list length = %s", list.size());
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpClientProvider.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpClientProvider.java
index 0510aed..a71e03f 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpClientProvider.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpClientProvider.java
@@ -68,10 +68,11 @@
   }
 
   private RequestConfig customRequestConfig() {
+    int connectionTimeout = (int) cfg.http().connectionTimeout().toMillis();
     return RequestConfig.custom()
-        .setConnectTimeout(cfg.http().connectionTimeout())
-        .setSocketTimeout(cfg.http().socketTimeout())
-        .setConnectionRequestTimeout(cfg.http().connectionTimeout())
+        .setConnectTimeout(connectionTimeout)
+        .setSocketTimeout((int) cfg.http().socketTimeout().toMillis())
+        .setConnectionRequestTimeout(connectionTimeout)
         .build();
   }
 
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/RestForwarderScheduler.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/RestForwarderScheduler.java
index ebbd940..da3d09f 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/RestForwarderScheduler.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/RestForwarderScheduler.java
@@ -22,6 +22,7 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
+import java.time.Duration;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
@@ -35,7 +36,7 @@
 public class RestForwarderScheduler {
   private static final FluentLogger log = FluentLogger.forEnclosingClass();
   private final ScheduledExecutorService executor;
-  private final long retryIntervalMs;
+  private final Duration retryInterval;
 
   public class CompletablePromise<V> extends CompletableFuture<V> {
     private Future<V> future;
@@ -70,29 +71,28 @@
   public RestForwarderScheduler(
       WorkQueue workQueue, Configuration cfg, Provider<Set<PeerInfo>> peerInfoProvider) {
     int executorSize = peerInfoProvider.get().size() * cfg.index().threadPoolSize();
-    retryIntervalMs = cfg.index().retryInterval();
+    retryInterval = cfg.index().retryInterval();
     this.executor = workQueue.createQueue(executorSize, "RestForwarderScheduler");
   }
 
   @VisibleForTesting
   public RestForwarderScheduler(ScheduledExecutorService executor) {
     this.executor = executor;
-    retryIntervalMs = 0;
+    retryInterval = Duration.ZERO;
   }
 
   public CompletableFuture<Boolean> execute(RestForwarder.Request request) {
-    return execute(request, 0);
+    return execute(request, Duration.ZERO);
   }
 
-  public CompletableFuture<Boolean> execute(RestForwarder.Request request, long delayMs) {
+  public CompletableFuture<Boolean> execute(RestForwarder.Request request, Duration delay) {
     return supplyAsync(
         request.toString(),
         () -> {
           try {
             if (!request.execute()) {
-              log.atWarning().log(
-                  "Rescheduling %s for retry after %d msec", request, retryIntervalMs);
-              return execute(request, retryIntervalMs);
+              log.atWarning().log("Rescheduling %s for retry after %s", request, retryInterval);
+              return execute(request, retryInterval);
             }
             return CompletableFuture.completedFuture(true);
           } catch (ForwardingException e) {
@@ -101,16 +101,16 @@
           }
         },
         executor,
-        delayMs);
+        delay);
   }
 
   private CompletableFuture<Boolean> supplyAsync(
       String taskName,
       Supplier<CompletableFuture<Boolean>> fn,
       ScheduledExecutorService executor,
-      long delayMs) {
+      Duration delay) {
     BooleanAsyncSupplier asyncSupplier = new BooleanAsyncSupplier(taskName, fn);
-    executor.schedule(asyncSupplier, delayMs, TimeUnit.MILLISECONDS);
+    executor.schedule(asyncSupplier, delay.toMillis(), TimeUnit.MILLISECONDS);
     return asyncSupplier.future();
   }
 
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandler.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandler.java
index 4f77508..e75b871 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandler.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/index/IndexEventHandler.java
@@ -26,6 +26,7 @@
 import com.google.gerrit.extensions.events.GroupIndexedListener;
 import com.google.gerrit.extensions.events.ProjectIndexedListener;
 import com.google.inject.Inject;
+import java.time.Duration;
 import java.util.Collections;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
@@ -48,7 +49,7 @@
   private final CurrentRequestContext currCtx;
   private final IndexEventLocks locks;
 
-  private final int retryInterval;
+  private final Duration retryInterval;
   private final int maxTries;
 
   @Inject
@@ -177,7 +178,7 @@
     private void reschedule() {
       if (++retryCount <= maxTries) {
         log.atFine().log("Retrying %d times to %s", retryCount, this);
-        executor.schedule(this, retryInterval, TimeUnit.MILLISECONDS);
+        executor.schedule(this, retryInterval.toMillis(), TimeUnit.MILLISECONDS);
       } else {
         log.atSevere().log("Failed to %s after %d tries; giving up", this, maxTries);
       }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheCleaner.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheCleaner.java
index afc6568..b4260a7 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheCleaner.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheCleaner.java
@@ -25,6 +25,7 @@
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
+import java.time.Duration;
 import java.util.concurrent.ScheduledFuture;
 
 @Singleton
@@ -32,7 +33,7 @@
 
   private final WorkQueue queue;
   private final Provider<CleanupTask> cleanupTaskProvider;
-  private final long cleanupIntervalMillis;
+  private final Duration cleanupInterval;
   private ScheduledFuture<?> scheduledCleanupTask;
 
   static class CleanupTask implements Runnable {
@@ -64,7 +65,7 @@
       WorkQueue queue, Provider<CleanupTask> cleanupTaskProvider, Configuration config) {
     this.queue = queue;
     this.cleanupTaskProvider = cleanupTaskProvider;
-    this.cleanupIntervalMillis = config.websession().cleanupInterval();
+    this.cleanupInterval = config.websession().cleanupInterval();
   }
 
   @Override
@@ -75,7 +76,7 @@
             .scheduleAtFixedRate(
                 cleanupTaskProvider.get(),
                 SECONDS.toMillis(1),
-                cleanupIntervalMillis,
+                cleanupInterval.toMillis(),
                 MILLISECONDS);
   }
 
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java
index b6986db..52d3674 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java
@@ -19,7 +19,7 @@
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Cache.PATTERN_KEY;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_NUM_STRIPED_LOCKS;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_THREAD_POOL_SIZE;
-import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_TIMEOUT_MS;
+import static com.ericsson.gerrit.plugins.highavailability.Configuration.DEFAULT_TIMEOUT;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Event.ALLOWED_LISTENERS;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Event.EVENT_SECTION;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Forwarding.DEFAULT_SYNCHRONIZE;
@@ -58,11 +58,10 @@
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.PeerInfoStatic.URL_KEY;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.THREAD_POOL_SIZE_KEY;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Websession.CLEANUP_INTERVAL_KEY;
-import static com.ericsson.gerrit.plugins.highavailability.Configuration.Websession.DEFAULT_CLEANUP_INTERVAL_MS;
+import static com.ericsson.gerrit.plugins.highavailability.Configuration.Websession.DEFAULT_CLEANUP_INTERVAL;
 import static com.ericsson.gerrit.plugins.highavailability.Configuration.Websession.WEBSESSION_SECTION;
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth8.assertThat;
-import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.junit.Assert.assertEquals;
 
 import com.ericsson.gerrit.plugins.highavailability.Configuration.PeerInfoStrategy;
@@ -74,6 +73,7 @@
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.time.Duration;
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -216,24 +216,24 @@
 
   @Test
   public void testGetConnectionTimeout() throws Exception {
-    assertThat(getConfiguration().http().connectionTimeout()).isEqualTo(DEFAULT_TIMEOUT_MS);
+    assertThat(getConfiguration().http().connectionTimeout()).isEqualTo(DEFAULT_TIMEOUT);
 
     globalPluginConfig.setInt(HTTP_SECTION, null, CONNECTION_TIMEOUT_KEY, TIMEOUT);
-    assertThat(getConfiguration().http().connectionTimeout()).isEqualTo(TIMEOUT);
+    assertThat(getConfiguration().http().connectionTimeout().toMillis()).isEqualTo(TIMEOUT);
 
     globalPluginConfig.setString(HTTP_SECTION, null, CONNECTION_TIMEOUT_KEY, INVALID_INT);
-    assertThat(getConfiguration().http().connectionTimeout()).isEqualTo(DEFAULT_TIMEOUT_MS);
+    assertThat(getConfiguration().http().connectionTimeout()).isEqualTo(DEFAULT_TIMEOUT);
   }
 
   @Test
   public void testGetSocketTimeout() throws Exception {
-    assertThat(getConfiguration().http().socketTimeout()).isEqualTo(DEFAULT_TIMEOUT_MS);
+    assertThat(getConfiguration().http().socketTimeout()).isEqualTo(DEFAULT_TIMEOUT);
 
     globalPluginConfig.setInt(HTTP_SECTION, null, SOCKET_TIMEOUT_KEY, TIMEOUT);
-    assertThat(getConfiguration().http().socketTimeout()).isEqualTo(TIMEOUT);
+    assertThat(getConfiguration().http().socketTimeout().toMillis()).isEqualTo(TIMEOUT);
 
     globalPluginConfig.setString(HTTP_SECTION, null, SOCKET_TIMEOUT_KEY, INVALID_INT);
-    assertThat(getConfiguration().http().socketTimeout()).isEqualTo(DEFAULT_TIMEOUT_MS);
+    assertThat(getConfiguration().http().socketTimeout()).isEqualTo(DEFAULT_TIMEOUT);
   }
 
   @Test
@@ -252,7 +252,7 @@
     assertThat(getConfiguration().http().retryInterval()).isEqualTo(DEFAULT_RETRY_INTERVAL);
 
     globalPluginConfig.setInt(HTTP_SECTION, null, RETRY_INTERVAL_KEY, RETRY_INTERVAL);
-    assertThat(getConfiguration().http().retryInterval()).isEqualTo(RETRY_INTERVAL);
+    assertThat(getConfiguration().http().retryInterval().toMillis()).isEqualTo(RETRY_INTERVAL);
 
     globalPluginConfig.setString(HTTP_SECTION, null, RETRY_INTERVAL_KEY, INVALID_INT);
     assertThat(getConfiguration().http().retryInterval()).isEqualTo(DEFAULT_RETRY_INTERVAL);
@@ -441,10 +441,10 @@
   @Test
   public void testGetCleanupInterval() throws Exception {
     assertThat(getConfiguration().websession().cleanupInterval())
-        .isEqualTo(DEFAULT_CLEANUP_INTERVAL_MS);
+        .isEqualTo(DEFAULT_CLEANUP_INTERVAL);
 
     globalPluginConfig.setString(WEBSESSION_SECTION, null, CLEANUP_INTERVAL_KEY, "30 seconds");
-    assertThat(getConfiguration().websession().cleanupInterval()).isEqualTo(SECONDS.toMillis(30));
+    assertThat(getConfiguration().websession().cleanupInterval()).isEqualTo(Duration.ofSeconds(30));
   }
 
   @Test
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/jgroups/JGroupsForwarderTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/jgroups/JGroupsForwarderTest.java
index 4465b17..3d284d0 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/jgroups/JGroupsForwarderTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/jgroups/JGroupsForwarderTest.java
@@ -25,6 +25,7 @@
 import com.ericsson.gerrit.plugins.highavailability.Configuration;
 import com.google.gerrit.server.events.EventGsonProvider;
 import com.google.gson.Gson;
+import java.time.Duration;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
@@ -54,7 +55,7 @@
     Gson gson = new JGroupsForwarderModule().buildJGroupsGson(eventGson);
     Configuration cfg = mock(Configuration.class, RETURNS_DEEP_STUBS);
     when(cfg.jgroups().maxTries()).thenReturn(MAX_TRIES);
-    when(cfg.jgroups().retryInterval()).thenReturn(1);
+    when(cfg.jgroups().retryInterval()).thenReturn(Duration.ofMillis(1));
 
     dispatcher = mock(MessageDispatcher.class, RETURNS_DEEP_STUBS);
     when(dispatcher.getChannel().getView().size()).thenReturn(2);
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpClientProviderTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpClientProviderTest.java
index 5f66550..5391d42 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpClientProviderTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpClientProviderTest.java
@@ -22,6 +22,7 @@
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Scopes;
+import java.time.Duration;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.junit.Before;
 import org.junit.Test;
@@ -32,7 +33,7 @@
 
 @RunWith(MockitoJUnitRunner.class)
 public class HttpClientProviderTest {
-  private static final int TIME_INTERVAL = 1000;
+  private static final Duration TIME_INTERVAL = Duration.ofMillis(1000);
   private static final String EMPTY = "";
 
   @Mock(answer = Answers.RETURNS_DEEP_STUBS)
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSessionTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSessionTest.java
index 1edcd43..4d874dd 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSessionTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSessionTest.java
@@ -30,6 +30,7 @@
 import com.github.tomakehurst.wiremock.stubbing.Scenario;
 import com.google.gson.Gson;
 import java.net.SocketTimeoutException;
+import java.time.Duration;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -38,8 +39,8 @@
 public class HttpSessionTest {
 
   private static final int MAX_TRIES = 3;
-  private static final int RETRY_INTERVAL = 250;
-  private static final int TIMEOUT = 500;
+  private static final Duration RETRY_INTERVAL = Duration.ofMillis(250);
+  private static final Duration TIMEOUT = Duration.ofMillis(500);
   private static final int ERROR = 500;
   private static final int NO_CONTENT = 204;
   private static final int NOT_FOUND = 404;
@@ -141,24 +142,24 @@
             .inScenario(RETRY_AT_DELAY)
             .whenScenarioStateIs(Scenario.STARTED)
             .willSetStateTo(REQUEST_MADE)
-            .willReturn(aResponse().withFixedDelay(TIMEOUT)));
+            .willReturn(aResponse().withFixedDelay((int) TIMEOUT.toMillis())));
     wireMockRule.givenThat(
         post(urlEqualTo(ENDPOINT))
             .inScenario(RETRY_AT_DELAY)
             .whenScenarioStateIs(REQUEST_MADE)
             .willSetStateTo(SECOND_TRY)
-            .willReturn(aResponse().withFixedDelay(TIMEOUT)));
+            .willReturn(aResponse().withFixedDelay((int) TIMEOUT.toMillis())));
     wireMockRule.givenThat(
         post(urlEqualTo(ENDPOINT))
             .inScenario(RETRY_AT_DELAY)
             .whenScenarioStateIs(SECOND_TRY)
             .willSetStateTo(THIRD_TRY)
-            .willReturn(aResponse().withFixedDelay(TIMEOUT)));
+            .willReturn(aResponse().withFixedDelay((int) TIMEOUT.toMillis())));
     wireMockRule.givenThat(
         post(urlEqualTo(ENDPOINT))
             .inScenario(RETRY_AT_DELAY)
             .whenScenarioStateIs(THIRD_TRY)
-            .willReturn(aResponse().withFixedDelay(TIMEOUT)));
+            .willReturn(aResponse().withFixedDelay((int) TIMEOUT.toMillis())));
 
     httpSession.post(uri);
   }
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/RestForwarderTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/RestForwarderTest.java
index 7908669..e9fab0c 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/RestForwarderTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/RestForwarderTest.java
@@ -36,6 +36,7 @@
 import com.google.gson.Gson;
 import com.google.inject.Provider;
 import java.io.IOException;
+import java.time.Duration;
 import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
@@ -105,7 +106,7 @@
     httpSessionMock = mock(HttpSession.class);
     configMock = mock(Configuration.class, Answers.RETURNS_DEEP_STUBS);
     when(configMock.http().maxTries()).thenReturn(3);
-    when(configMock.http().retryInterval()).thenReturn(10);
+    when(configMock.http().retryInterval()).thenReturn(Duration.ofMillis(10));
     peersMock = mock(Provider.class);
     when(peersMock.get()).thenReturn(ImmutableSet.of(new PeerInfo(URL)));
     forwarder =
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 81f16e4..75c8a39 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
@@ -41,6 +41,7 @@
 import com.google.gerrit.server.util.OneOffRequestContext;
 import com.google.gerrit.server.util.RequestContext;
 import com.google.gerrit.server.util.ThreadLocalRequestContext;
+import java.time.Duration;
 import java.util.Collection;
 import java.util.List;
 import java.util.Optional;
@@ -277,6 +278,7 @@
     Configuration cfg = mock(Configuration.class);
     Configuration.Http httpCfg = mock(Configuration.Http.class);
     when(httpCfg.maxTries()).thenReturn(10);
+    when(httpCfg.retryInterval()).thenReturn(Duration.ZERO);
     when(cfg.http()).thenReturn(httpCfg);
     setUpIndexEventHandler(currCtx, locks, cfg);
     indexEventHandler.onChangeIndexed(PROJECT_NAME, changeId.get());
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 0a8fc92..19c9a51 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
@@ -28,6 +28,7 @@
 import com.ericsson.gerrit.plugins.highavailability.websession.file.FileBasedWebSessionCacheCleaner.CleanupTask;
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.inject.Provider;
+import java.time.Duration;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -41,7 +42,7 @@
 @RunWith(MockitoJUnitRunner.class)
 public class FileBasedWebSessionCacheCleanerTest {
 
-  private static long CLEANUP_INTERVAL = 5000;
+  private static Duration CLEANUP_INTERVAL = Duration.ofSeconds(5);
   private static String SOME_PLUGIN_NAME = "somePluginName";
 
   @Mock private ScheduledThreadPoolExecutor executorMock;
@@ -89,7 +90,10 @@
     cleaner.start();
     verify(executorMock, times(1))
         .scheduleAtFixedRate(
-            isA(CleanupTask.class), eq(1000l), eq(CLEANUP_INTERVAL), eq(TimeUnit.MILLISECONDS));
+            isA(CleanupTask.class),
+            eq(1000l),
+            eq(CLEANUP_INTERVAL.toMillis()),
+            eq(TimeUnit.MILLISECONDS));
   }
 
   @Test