Adding support for GUI TopologyView to visualize port packet stats as an alternative to port byte stats.

Change-Id: I323840c4fe98009759646eed0c4c66fa2bad0e61
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/PortStatisticsService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/PortStatisticsService.java
index 7888adb..f4c4fb1 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/PortStatisticsService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/PortStatisticsService.java
@@ -25,12 +25,32 @@
 @Beta
 public interface PortStatisticsService {
 
+    /** Specifies the type of metric. */
+    enum MetricType {
+        /** Load is to be given in bytes/second. */
+        BYTES,
+
+        /** Load is to be given in packets/second. */
+        PACKETS
+    }
+
     /**
-     * Obtain the egress load for the given port.
+     * Obtain the egress load for the given port in terms of bytes per second.
      *
      * @param connectPoint the port to query
      * @return egress traffic load
      */
     Load load(ConnectPoint connectPoint);
 
+    /**
+     * Obtain the egress load for the given port in terms of the specified metric.
+     *
+     * @param connectPoint the port to query
+     * @param metricType   metric type
+     * @return egress traffic load
+     */
+    default Load load(ConnectPoint connectPoint, MetricType metricType) {
+        return load(connectPoint);
+    }
+
 }
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java
index 40777da..596a835 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java
@@ -75,21 +75,28 @@
 
     @Override
     public Load load(ConnectPoint connectPoint) {
+        return load(connectPoint, MetricType.BYTES);
+    }
+
+    @Override
+    public Load load(ConnectPoint connectPoint, MetricType metricType) {
         DataPoint c = current.get(connectPoint);
         DataPoint p = previous.get(connectPoint);
         long now = System.currentTimeMillis();
 
         if (c != null && p != null && (now - c.time < STALE_LIMIT)) {
             if (c.time > p.time + SECOND) {
+                long cve = getEgressValue(c.stats, metricType);
+                long cvi = getIngressValue(c.stats, metricType);
+                long pve = getEgressValue(p.stats, metricType);
+                long pvi = getIngressValue(p.stats, metricType);
                 //Use max of either Tx or Rx load as the total load of a port
                 Load load = null;
-                if (c.stats.bytesSent() >= p.stats.bytesSent()) {
-                    load = new DefaultLoad(c.stats.bytesSent(), p.stats.bytesSent(),
-                                                    (int) (c.time - p.time) / SECOND);
+                if (cve >= pve) {
+                    load = new DefaultLoad(cve, pve, (int) (c.time - p.time) / SECOND);
                 }
-                if (c.stats.bytesReceived() >= p.stats.bytesReceived()) {
-                    Load rcvLoad = new DefaultLoad(c.stats.bytesReceived(), p.stats.bytesReceived(),
-                                                    (int) (c.time - p.time) / SECOND);
+                if (cvi >= pvi) {
+                    Load rcvLoad = new DefaultLoad(cvi, pvi, (int) (c.time - p.time) / SECOND);
                     load = ((load == null) || (rcvLoad.rate() > load.rate())) ? rcvLoad : load;
                 }
                 return load;
@@ -98,6 +105,14 @@
         return null;
     }
 
+    private long getEgressValue(PortStatistics stats, MetricType metricType) {
+        return metricType == MetricType.BYTES ? stats.bytesSent() : stats.packetsSent();
+    }
+
+    private long getIngressValue(PortStatistics stats, MetricType metricType) {
+        return metricType == MetricType.BYTES ? stats.bytesReceived() : stats.packetsReceived();
+    }
+
     // Monitors port stats update messages.
     private class InternalDeviceListener implements DeviceListener {
         @Override
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java b/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java
index e97b7dd..d324cc8 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java
@@ -18,6 +18,7 @@
 package org.onosproject.ui.impl;
 
 import com.google.common.collect.ImmutableList;
+import org.onosproject.incubator.net.PortStatisticsService.MetricType;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.ElementId;
@@ -67,10 +68,10 @@
 import java.util.Timer;
 import java.util.TimerTask;
 
+import static org.onosproject.incubator.net.PortStatisticsService.MetricType.BYTES;
+import static org.onosproject.incubator.net.PortStatisticsService.MetricType.PACKETS;
 import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
-import static org.onosproject.ui.impl.TrafficMonitor.Mode.IDLE;
-import static org.onosproject.ui.impl.TrafficMonitor.Mode.RELATED_INTENTS;
-import static org.onosproject.ui.impl.TrafficMonitor.Mode.SELECTED_INTENT;
+import static org.onosproject.ui.impl.TrafficMonitor.Mode.*;
 
 /**
  * Encapsulates the behavior of monitoring specific traffic patterns.
@@ -372,7 +373,9 @@
             if (type == StatsType.FLOW_STATS) {
                 attachFlowLoad(tlink);
             } else if (type == StatsType.PORT_STATS) {
-                attachPortLoad(tlink);
+                attachPortLoad(tlink, BYTES);
+            } else if (type == StatsType.PORT_PACKET_STATS) {
+                attachPortLoad(tlink, PACKETS);
             }
 
             // we only want to report on links deemed to have traffic
@@ -483,14 +486,14 @@
         link.addLoad(getLinkFlowLoad(link.two()));
     }
 
-    private void attachPortLoad(TrafficLink link) {
+    private void attachPortLoad(TrafficLink link, MetricType metricType) {
         // For bi-directional traffic links, use
         // the max link rate of either direction
         // (we choose 'one' since we know that is never null)
         Link one = link.one();
-        Load egressSrc = servicesBundle.portStatsService().load(one.src());
-        Load egressDst = servicesBundle.portStatsService().load(one.dst());
-        link.addLoad(maxLoad(egressSrc, egressDst), BPS_THRESHOLD);
+        Load egressSrc = servicesBundle.portStatsService().load(one.src(), metricType);
+        Load egressDst = servicesBundle.portStatsService().load(one.dst(), metricType);
+        link.addLoad(maxLoad(egressSrc, egressDst), metricType == BYTES ? BPS_THRESHOLD : 0);
 //        link.addLoad(maxLoad(egressSrc, egressDst), 10);    // DEBUG ONLY!!
     }
 
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TrafficLink.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TrafficLink.java
index 16d3db7..570fed4 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TrafficLink.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TrafficLink.java
@@ -243,6 +243,11 @@
         PORT_STATS,
 
         /**
+         * Number of packets per second.
+         */
+        PORT_PACKET_STATS,
+
+        /**
          * Custom tagged information.
          */
         TAGGED