Work toward fixing ONOS-1138: Batching topo event may cause event loss

Added another metric to the onos-app-metrics-topology application
to collect and display the number and rate of the Reasons for the
Topology Events.

Example:

onos> topology-events-metrics
...
Topology Graph Event Timestamp (ms from epoch)=1426699861509
Topology Graph Events count=6 rate(events/sec) mean=0.002315 m1=0.000000 m5=0.000004 m15=0.000378
Topology Graph Reasons Event Timestamp (ms from epoch)=1426699861509
Topology Graph Reasons Events count=9 rate(events/sec) mean=0.003472 m1=0.000000 m5=0.000005 m15=0.000567

The corresponding object names in the JSON output are:
  topologyGraphReasonsEventRate
  topologyGraphReasonsEventTimestamp

Change-Id: Ib1aeb83c38b3b72d0ae8a4f49bc1e14badc0199d
diff --git a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetrics.java b/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetrics.java
index ed446dc..a2f0d5c 100644
--- a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetrics.java
+++ b/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetrics.java
@@ -91,17 +91,20 @@
     private static final String FEATURE_HOST_NAME = "HostEvent";
     private static final String FEATURE_LINK_NAME = "LinkEvent";
     private static final String FEATURE_GRAPH_NAME = "GraphEvent";
+    private static final String FEATURE_GRAPH_REASONS_NAME = "GraphReasonsEvent";
     //
     // Event metrics:
     //  - Device events
     //  - Host events
     //  - Link events
     //  - Topology Graph events
+    //  - Topology Graph Reasons events
     //
     private EventMetric topologyDeviceEventMetric;
     private EventMetric topologyHostEventMetric;
     private EventMetric topologyLinkEventMetric;
     private EventMetric topologyGraphEventMetric;
+    private EventMetric topologyGraphReasonsEventMetric;
 
     @Activate
     protected void activate() {
@@ -160,6 +163,11 @@
         return topologyGraphEventMetric;
     }
 
+    @Override
+    public EventMetric topologyGraphReasonsEventMetric() {
+        return topologyGraphReasonsEventMetric;
+    }
+
     /**
      * Records an event.
      *
@@ -226,6 +234,7 @@
             log.debug("Topology Event: time = {} type = {} event = {}",
                       event.time(), event.type(), event);
             for (Event reason : event.reasons()) {
+                recordEvent(event, topologyGraphReasonsEventMetric);
                 log.debug("Topology Event Reason: time = {} type = {} event = {}",
                           reason.time(), reason.type(), reason);
             }
@@ -257,11 +266,15 @@
         topologyGraphEventMetric =
             new EventMetric(metricsService, COMPONENT_NAME,
                             FEATURE_GRAPH_NAME);
+        topologyGraphReasonsEventMetric =
+            new EventMetric(metricsService, COMPONENT_NAME,
+                            FEATURE_GRAPH_REASONS_NAME);
 
         topologyDeviceEventMetric.registerMetrics();
         topologyHostEventMetric.registerMetrics();
         topologyLinkEventMetric.registerMetrics();
         topologyGraphEventMetric.registerMetrics();
+        topologyGraphReasonsEventMetric.registerMetrics();
     }
 
     /**
@@ -272,5 +285,6 @@
         topologyHostEventMetric.removeMetrics();
         topologyLinkEventMetric.removeMetrics();
         topologyGraphEventMetric.removeMetrics();
+        topologyGraphReasonsEventMetric.removeMetrics();
     }
 }
diff --git a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetricsService.java b/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetricsService.java
index 77809ca..33c772d 100644
--- a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetricsService.java
+++ b/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/TopologyMetricsService.java
@@ -26,35 +26,42 @@
     /**
      * Gets the last saved topology events.
      *
-     * @return the last saved topology events.
+     * @return the last saved topology events
      */
     public List<Event> getEvents();
 
     /**
      * Gets the Event Metric for the Device Events.
      *
-     * @return the Event Metric for the Device Events.
+     * @return the Event Metric for the Device Events
      */
     public EventMetric topologyDeviceEventMetric();
 
     /**
      * Gets the Event Metric for the Host Events.
      *
-     * @return the Event Metric for the Host Events.
+     * @return the Event Metric for the Host Events
      */
     public EventMetric topologyHostEventMetric();
 
     /**
      * Gets the Event Metric for the Link Events.
      *
-     * @return the Event Metric for the Link Events.
+     * @return the Event Metric for the Link Events
      */
     public EventMetric topologyLinkEventMetric();
 
     /**
      * Gets the Event Metric for the Topology Graph Events.
      *
-     * @return the Event Metric for the Topology Graph Events.
+     * @return the Event Metric for the Topology Graph Events
      */
     public EventMetric topologyGraphEventMetric();
+
+    /**
+     * Gets the Event Metric for the Topology Graph Reasons Events.
+     *
+     * @return the Event Metric for the Topology Graph Reasons Events
+     */
+    public EventMetric topologyGraphReasonsEventMetric();
 }
diff --git a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsMetricsCommand.java b/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsMetricsCommand.java
index 274a14d..b87762a 100644
--- a/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsMetricsCommand.java
+++ b/apps/metrics/topology/src/main/java/org/onosproject/metrics/topology/cli/TopologyEventsMetricsCommand.java
@@ -60,12 +60,16 @@
                           service.topologyLinkEventMetric());
             result = json(mapper, result, "topologyGraphEvent",
                           service.topologyGraphEventMetric());
+            result = json(mapper, result, "topologyGraphReasonsEvent",
+                          service.topologyGraphReasonsEventMetric());
             print("%s", result);
         } else {
             printEventMetric("Device", service.topologyDeviceEventMetric());
             printEventMetric("Host", service.topologyHostEventMetric());
             printEventMetric("Link", service.topologyLinkEventMetric());
             printEventMetric("Graph", service.topologyGraphEventMetric());
+            printEventMetric("Graph Reasons",
+                             service.topologyGraphReasonsEventMetric());
         }
     }