Set the timestamps by using the absolute epoch time in milliseconds
(i.e., ms from the Epoch):
 System.currentTimeMillis()

The previous solution System.nanoTime() starts from a fixed, but
arbitrary time and cannot be used to compare timestamps across
different systems.

For now, the System.currentTimeMillis() granularity should be good enough
for end-to-end measurements.

In the follow-up iterations, if we need breakdown of the execution path
on a single machine, we can utilize System.nanoTime() if necessary.

As part of the update, the names of the timestamp metrics are now updated
to include ".EpochMs" suffix:

"Topology.EventNotification.LastEventTimestamp" ->
"Topology.EventNotification.LastEventTimestamp.EpochMs"

"Intents.AddOperation.BeginOperationTimestamp" ->
"Intents.AddOperation.BeginOperationTimestamp.EpochMs"

"Intents.AddOperation.EndOperationTimestamp" ->
"Intents.AddOperation.EndOperationTimestamp.EpochMs"

"Intents.RemoveOperation.BeginOperationTimestamp" ->
"Intents.RemoveOperation.BeginOperationTimestamp.EpochMs"

"Intents.RemoveOperation.EndOperationTimestamp" ->
"Intents.RemoveOperation.EndOperationTimestamp.EpochMs"

Change-Id: I9ebf067bb8aa8055fd445781213ca741b5df5e74
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java b/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
index f27cb1a..740a33c 100644
--- a/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
@@ -140,7 +140,7 @@
                             break;
                         case INST_ACK:
                             intentAddProcessingRate.mark(1);
-                            intentAddEndTimestamp = System.nanoTime();
+                            intentAddEndTimestampEpochMs = System.currentTimeMillis();
                             break;
                         case INST_NACK:
                             break;
@@ -148,7 +148,7 @@
                             break;
                         case DEL_ACK:
                             intentRemoveProcessingRate.mark(1);
-                            intentRemoveEndTimestamp = System.nanoTime();
+                            intentRemoveEndTimestampEpochMs = System.currentTimeMillis();
                             break;
                         case DEL_PENDING:
                             break;
@@ -282,52 +282,52 @@
     private static final MetricsFeature METRICS_FEATURE_REMOVE_OPERATION =
         METRICS_COMPONENT.registerFeature("RemoveOperation");
     //
-    // Timestamp of the incoming Add Intent API operation (system nanoseconds)
-    private volatile long intentAddBeginTimestamp = 0;
-    private final Gauge<Long> gaugeIntentAddBeginTimestamp =
+    // Timestamp of the incoming Add Intent API operation (ms from the Epoch)
+    private volatile long intentAddBeginTimestampEpochMs = 0;
+    private final Gauge<Long> gaugeIntentAddBeginTimestampEpochMs =
         OnosMetrics.registerMetric(METRICS_COMPONENT,
                                    METRICS_FEATURE_ADD_OPERATION,
-                                   "BeginOperationTimestamp",
+                                   "BeginOperationTimestamp.EpochMs",
                                    new Gauge<Long>() {
                                        @Override
                                        public Long getValue() {
-                                           return intentAddBeginTimestamp;
+                                           return intentAddBeginTimestampEpochMs;
                                        }
                                    });
-    // Timestamp of the Add Intent operation completion (system nanoseconds)
-    private volatile long intentAddEndTimestamp = 0;
-    private final Gauge<Long> gaugeIntentAddEndTimestamp =
+    // Timestamp of the Add Intent operation completion (ms from the Epoch)
+    private volatile long intentAddEndTimestampEpochMs = 0;
+    private final Gauge<Long> gaugeIntentAddEndTimestampEpochMs =
         OnosMetrics.registerMetric(METRICS_COMPONENT,
                                    METRICS_FEATURE_ADD_OPERATION,
-                                   "EndOperationTimestamp",
+                                   "EndOperationTimestamp.EpochMs",
                                    new Gauge<Long>() {
                                        @Override
                                        public Long getValue() {
-                                           return intentAddEndTimestamp;
+                                           return intentAddEndTimestampEpochMs;
                                        }
                                    });
-    // Timestamp of the incoming Remove Intent API operation (system nanoseconds)
-    private volatile long intentRemoveBeginTimestamp = 0;
-    private final Gauge<Long> gaugeIntentRemoveBeginTimestamp =
+    // Timestamp of the incoming Remove Intent API operation (ms from the Epoch)
+    private volatile long intentRemoveBeginTimestampEpochMs = 0;
+    private final Gauge<Long> gaugeIntentRemoveBeginTimestampEpochMs =
         OnosMetrics.registerMetric(METRICS_COMPONENT,
                                    METRICS_FEATURE_REMOVE_OPERATION,
-                                   "BeginOperationTimestamp",
+                                   "BeginOperationTimestamp.EpochMs",
                                    new Gauge<Long>() {
                                        @Override
                                        public Long getValue() {
-                                           return intentRemoveBeginTimestamp;
+                                           return intentRemoveBeginTimestampEpochMs;
                                        }
                                    });
-    // Timestamp of the Remove Intent operation completion (system nanoseconds)
-    private volatile long intentRemoveEndTimestamp = 0;
-    private final Gauge<Long> gaugeIntentRemoveEndTimestamp =
+    // Timestamp of the Remove Intent operation completion (ms from the Epoch)
+    private volatile long intentRemoveEndTimestampEpochMs = 0;
+    private final Gauge<Long> gaugeIntentRemoveEndTimestampEpochMs =
         OnosMetrics.registerMetric(METRICS_COMPONENT,
                                    METRICS_FEATURE_REMOVE_OPERATION,
-                                   "EndOperationTimestamp",
+                                   "EndOperationTimestamp.EpochMs",
                                    new Gauge<Long>() {
                                        @Override
                                        public Long getValue() {
-                                           return intentRemoveEndTimestamp;
+                                           return intentRemoveEndTimestampEpochMs;
                                        }
                                    });
     //
@@ -545,7 +545,7 @@
         // Update the metrics
         //
         if (!appIntents.isEmpty()) {
-            this.intentAddBeginTimestamp = System.nanoTime();
+            this.intentAddBeginTimestampEpochMs = System.currentTimeMillis();
             this.intentAddIncomingRate.mark(appIntents.size());
         }
 
@@ -614,7 +614,7 @@
         //
         // Prepare the timestamp for metrics
         //
-        long nanoTimeTimestamp = System.nanoTime();
+        long timestampEpochMs = System.currentTimeMillis();
 
         IntentMap intentMap = getHighLevelIntents();
         List<String> removeIntentIds = new LinkedList<String>();
@@ -641,7 +641,7 @@
         // Update the metrics
         //
         if (!operations.isEmpty()) {
-            this.intentRemoveBeginTimestamp = nanoTimeTimestamp;
+            this.intentRemoveBeginTimestampEpochMs = timestampEpochMs;
             this.intentRemoveIncomingRate.mark(operations.size());
         }
 
@@ -671,7 +671,7 @@
         //
         // Prepare the timestamp for metrics
         //
-        long nanoTimeTimestamp = System.nanoTime();
+        long timestampEpochMs = System.currentTimeMillis();
 
         Collection<Intent> allHighLevelIntents =
             getHighLevelIntents().getAllIntents();
@@ -695,7 +695,7 @@
         // Update the metrics
         //
         if (!operations.isEmpty()) {
-            this.intentRemoveBeginTimestamp = nanoTimeTimestamp;
+            this.intentRemoveBeginTimestampEpochMs = timestampEpochMs;
             this.intentRemoveIncomingRate.mark(operations.size());
         }
 
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyEvents.java b/src/main/java/net/onrc/onos/core/topology/TopologyEvents.java
index 9726269..25efa95 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyEvents.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyEvents.java
@@ -30,7 +30,7 @@
  */
 @JsonSerialize(using = TopologyEventsSerializer.class)
 public final class TopologyEvents {
-    private final long timestamp;       // Topology event timestamp (system ns)
+    private final long timestamp;       // Topology event timestamp (Epoch ms)
     private final Collection<SwitchEvent> addedSwitchEvents;
     private final Collection<SwitchEvent> removedSwitchEvents;
     private final Collection<PortEvent> addedPortEvents;
@@ -43,7 +43,7 @@
     /**
      * Constructor.
      *
-     * @param timestamp the timestamp for the event (system nanoseconds)
+     * @param timestamp the timestamp for the event (Epoch ms)
      * @param addedSwitchEvents the collection of added Switch Events.
      * @param removedSwitchEvents the collection of removed Switch Events.
      * @param addedPortEvents the collection of added Port Events.
@@ -84,9 +84,9 @@
     }
 
     /**
-     * Gets the timestamp for the events (system nanoseconds).
+     * Gets the timestamp for the events (Epoch ms).
      *
-     * @return the timestamp for the events (system nanoseconds).
+     * @return the timestamp for the events (Epoch ms).
      */
     public long getTimestamp() {
         return timestamp;
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
index aeb06c2..dccef16 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
@@ -81,16 +81,16 @@
     private static final MetricsFeature METRICS_FEATURE_EVENT_NOTIFICATION =
         METRICS_COMPONENT.registerFeature("EventNotification");
     //
-    // Timestamp of the last Topology event (system nanoseconds)
-    private volatile long lastEventTimestamp = 0;
-    private final Gauge<Long> gaugeLastEventTimestamp =
+    // Timestamp of the last Topology event (ms from the Epoch)
+    private volatile long lastEventTimestampEpochMs = 0;
+    private final Gauge<Long> gaugeLastEventTimestampEpochMs =
         OnosMetrics.registerMetric(METRICS_COMPONENT,
                                    METRICS_FEATURE_EVENT_NOTIFICATION,
-                                   "LastEventTimestamp",
+                                   "LastEventTimestamp.EpochMs",
                                    new Gauge<Long>() {
                                        @Override
                                        public Long getValue() {
-                                           return lastEventTimestamp;
+                                           return lastEventTimestampEpochMs;
                                        }
                                    });
     // Rate of the Topology events published to the Topology listeners
@@ -506,14 +506,14 @@
             apiAddedLinkEvents.size() + apiRemovedLinkEvents.size() +
             apiAddedHostEvents.size() + apiRemovedHostEvents.size();
         this.listenerEventRate.mark(totalEvents);
-        this.lastEventTimestamp = System.nanoTime();
+        this.lastEventTimestampEpochMs = System.currentTimeMillis();
 
         //
         // Deliver the events
         //
         for (ITopologyListener listener : this.topologyListeners) {
             TopologyEvents events =
-                new TopologyEvents(lastEventTimestamp,
+                new TopologyEvents(lastEventTimestampEpochMs,
                                    kryo.copy(apiAddedSwitchEvents),
                                    kryo.copy(apiRemovedSwitchEvents),
                                    kryo.copy(apiAddedPortEvents),