Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  Remove Joda dependency

Change-Id: I676579d29d3bcfb699b4e0dde8286c26cc272ecd
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebsessionCache.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebsessionCache.java
index ca5e841..120c615 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebsessionCache.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebsessionCache.java
@@ -32,6 +32,9 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -41,12 +44,32 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
-import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
 public class FileBasedWebsessionCache implements Cache<String, WebSessionManager.Val> {
+  /** Provides static methods to set the system clock for testing purposes only. */
+  static class TimeMachine {
+    private static Clock clock = Clock.systemDefaultZone();
+
+    static Instant now() {
+      return Instant.now(getClock());
+    }
+
+    static void useFixedClockAt(Instant instant) {
+      clock = Clock.fixed(instant, ZoneId.systemDefault());
+    }
+
+    static void useSystemDefaultZoneClock() {
+      clock = Clock.systemDefaultZone();
+    }
+
+    private static Clock getClock() {
+      return clock;
+    }
+  }
+
   private static final Logger log = LoggerFactory.getLogger(FileBasedWebsessionCache.class);
 
   private final Path websessionsDir;
@@ -74,8 +97,8 @@
     for (Path path : listFiles()) {
       Val val = readFile(path);
       if (val != null) {
-        DateTime expires = new DateTime(val.getExpiresAt());
-        if (expires.isBefore(new DateTime())) {
+        Instant expires = Instant.ofEpochMilli(val.getExpiresAt());
+        if (expires.isBefore(TimeMachine.now())) {
           deleteFile(path);
         }
       }
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheTest.java
index a13575a..fbe732d 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/websession/file/FileBasedWebSessionCacheTest.java
@@ -16,6 +16,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import com.ericsson.gerrit.plugins.highavailability.websession.file.FileBasedWebsessionCache.TimeMachine;
 import com.google.common.collect.ImmutableMap;
 import com.google.gerrit.httpd.WebSessionManager.Val;
 import java.io.IOException;
@@ -24,14 +25,14 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
-import org.joda.time.DateTime;
-import org.joda.time.DateTimeUtils;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -78,17 +79,17 @@
     loadKeyToCacheDir(EXISTING_KEY);
     try {
       long existingKeyExpireAt = cache.getIfPresent(EXISTING_KEY).getExpiresAt();
-      DateTimeUtils.setCurrentMillisFixed(
-          new DateTime(existingKeyExpireAt).minusHours(1).getMillis());
+      TimeMachine.useFixedClockAt(
+          Instant.ofEpochMilli(existingKeyExpireAt).minus(1, ChronoUnit.HOURS));
       cache.cleanUp();
       assertThat(isDirEmpty(websessionDir)).isFalse();
 
-      DateTimeUtils.setCurrentMillisFixed(
-          new DateTime(existingKeyExpireAt).plusHours(1).getMillis());
+      TimeMachine.useFixedClockAt(
+          Instant.ofEpochMilli(existingKeyExpireAt).plus(1, ChronoUnit.HOURS));
       cache.cleanUp();
       assertThat(isDirEmpty(websessionDir)).isTrue();
     } finally {
-      DateTimeUtils.setCurrentMillisSystem();
+      TimeMachine.useSystemDefaultZoneClock();
     }
   }