Do not rely on System.nanoTime for E2E metrics

The E2E metrics are calculated across JVMs where
the System.nanoTime cannot be trusted as source of
time as it is JVM-specific.

Use the System.currentTimeMillis and convert the
result into nanos for keeping the API compatibility
with the existing code.

Change-Id: I89fdcf7b5c8f50890be31476e2252ce796fbcf6a
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationApiRequestMetrics.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationApiRequestMetrics.java
index 8a97901..597b66f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationApiRequestMetrics.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/api/PullReplicationApiRequestMetrics.java
@@ -14,6 +14,8 @@
 
 package com.googlesource.gerrit.plugins.replication.pull.api;
 
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
 import com.google.inject.Inject;
 import com.googlesource.gerrit.plugins.replication.pull.FetchReplicationMetrics;
 import java.util.Optional;
@@ -51,18 +53,22 @@
     startTimeNanos =
         Optional.ofNullable(req.getHeader(HTTP_HEADER_X_START_TIME_NANOS))
             .map(Long::parseLong)
-            /* Adjust with System.nanoTime() for preventing negative execution times
+            /* Adjust with the system's nanotime for preventing negative execution times
              * due to a clock skew between the client and the server timestamp.
              */
-            .map(nanoTime -> Math.min(System.nanoTime(), nanoTime));
+            .map(nanoTime -> Math.min(currentTimeNanos(), nanoTime));
   }
 
   public Optional<Long> stop(String replicationSourceName) {
     return startTimeNanos.map(
         start -> {
-          long elapsed = System.nanoTime() - start;
+          long elapsed = currentTimeNanos() - start;
           metrics.recordEnd2End(replicationSourceName, elapsed);
           return elapsed;
         });
   }
+
+  private long currentTimeNanos() {
+    return MILLISECONDS.toNanos(System.currentTimeMillis());
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchApiClient.java b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchApiClient.java
index 6b23a9f..6000eb9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchApiClient.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/pull/client/FetchApiClient.java
@@ -14,6 +14,8 @@
 
 package com.googlesource.gerrit.plugins.replication.pull.client;
 
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
 import com.google.gerrit.entities.Project;
 import com.googlesource.gerrit.plugins.replication.pull.Source;
 import com.googlesource.gerrit.plugins.replication.pull.api.data.RevisionData;
@@ -34,7 +36,7 @@
 
   default HttpResult callFetch(Project.NameKey project, String refName, URIish targetUri)
       throws ClientProtocolException, IOException {
-    return callFetch(project, refName, targetUri, System.nanoTime());
+    return callFetch(project, refName, targetUri, MILLISECONDS.toNanos(System.currentTimeMillis()));
   }
 
   HttpResult initProject(Project.NameKey project, URIish uri) throws IOException;