Add resource name param to diskMetrics and networkMetrics method

- Enable to add metrics of multiple disks
- Enable to add metrics of multiple network interfaces

Change-Id: I6e91d63b7a02f0d2f63fe445712a23e72d208789
diff --git a/apps/cpman/app/src/main/java/org/onosproject/cpman/rest/ControlMetricsCollectorWebResource.java b/apps/cpman/app/src/main/java/org/onosproject/cpman/rest/ControlMetricsCollectorWebResource.java
index ec04372..f7a60dc 100644
--- a/apps/cpman/app/src/main/java/org/onosproject/cpman/rest/ControlMetricsCollectorWebResource.java
+++ b/apps/cpman/app/src/main/java/org/onosproject/cpman/rest/ControlMetricsCollectorWebResource.java
@@ -16,12 +16,13 @@
 package org.onosproject.cpman.rest;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.onosproject.cpman.ControlMetric;
 import org.onosproject.cpman.ControlMetricType;
-import org.onosproject.cpman.impl.ControlMetricsSystemSpec;
 import org.onosproject.cpman.ControlPlaneMonitorService;
 import org.onosproject.cpman.MetricValue;
+import org.onosproject.cpman.impl.ControlMetricsSystemSpec;
 import org.onosproject.rest.AbstractWebResource;
 
 import javax.ws.rs.Consumes;
@@ -34,6 +35,8 @@
 import java.io.InputStream;
 import java.util.Optional;
 
+import static org.onlab.util.Tools.nullIsIllegal;
+
 /**
  * Collect control plane metrics.
  */
@@ -43,6 +46,7 @@
     final ControlPlaneMonitorService service = get(ControlPlaneMonitorService.class);
     public static final int UPDATE_INTERVAL = 1;           // 1 minute update interval
     public static final String INVALID_SYSTEM_SPECS = "Invalid system specifications";
+    public static final String INVALID_RESOURCE_NAME = "Invalid resource name";
 
     /**
      * Collects CPU metrics.
@@ -68,13 +72,13 @@
 
             if (cpuLoadJson != null) {
                 cm = new ControlMetric(ControlMetricType.CPU_LOAD,
-                     new MetricValue.Builder().load(cpuLoadJson.asLong()).add());
+                        new MetricValue.Builder().load(cpuLoadJson.asLong()).add());
                 service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
             }
 
             if (totalCpuTimeJson != null) {
                 cm = new ControlMetric(ControlMetricType.TOTAL_CPU_TIME,
-                     new MetricValue.Builder().load(totalCpuTimeJson.asLong()).add());
+                        new MetricValue.Builder().load(totalCpuTimeJson.asLong()).add());
                 service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
             }
 
@@ -166,24 +170,29 @@
     @Produces(MediaType.APPLICATION_JSON)
     public Response diskMetrics(InputStream stream) {
         ObjectNode root = mapper().createObjectNode();
-        ControlMetric cm;
+        final ControlMetric[] cm = new ControlMetric[1];
         try {
             ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
-            JsonNode readBytes = jsonTree.get("readBytes");
-            JsonNode writeBytes = jsonTree.get("writeBytes");
+            ArrayNode diskRes = (ArrayNode) jsonTree.get("disks");
+            diskRes.forEach(node-> {
+                JsonNode resourceName = node.get("resourceName");
+                nullIsIllegal(resourceName, INVALID_RESOURCE_NAME);
 
-            if (readBytes != null) {
-                cm = new ControlMetric(ControlMetricType.DISK_READ_BYTES,
-                        new MetricValue.Builder().load(readBytes.asLong()).add());
-                service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
-            }
+                JsonNode readBytes = jsonTree.get("readBytes");
+                JsonNode writeBytes = jsonTree.get("writeBytes");
 
-            if (writeBytes != null) {
-                cm = new ControlMetric(ControlMetricType.DISK_WRITE_BYTES,
-                        new MetricValue.Builder().load(writeBytes.asLong()).add());
-                service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
-            }
+                if (readBytes != null) {
+                    cm[0] = new ControlMetric(ControlMetricType.DISK_READ_BYTES,
+                            new MetricValue.Builder().load(readBytes.asLong()).add());
+                    service.updateMetric(cm[0], UPDATE_INTERVAL, resourceName.asText());
+                }
 
+                if (writeBytes != null) {
+                    cm[0] = new ControlMetric(ControlMetricType.DISK_WRITE_BYTES,
+                            new MetricValue.Builder().load(writeBytes.asLong()).add());
+                    service.updateMetric(cm[0], UPDATE_INTERVAL, resourceName.asText());
+                }
+            });
         } catch (IOException e) {
             throw new IllegalArgumentException(e.getMessage());
         }
@@ -203,45 +212,49 @@
     @Produces(MediaType.APPLICATION_JSON)
     public Response networkMetrics(InputStream stream) {
         ObjectNode root = mapper().createObjectNode();
-        ControlMetric cm;
+        final ControlMetric[] cm = new ControlMetric[1];
         try {
             ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
-            JsonNode inBytes = jsonTree.get("incomingBytes");
-            JsonNode outBytes = jsonTree.get("outgoingBytes");
-            JsonNode inPackets = jsonTree.get("incomingPackets");
-            JsonNode outPackets = jsonTree.get("outgoingPackets");
+            ArrayNode networkRes = (ArrayNode) jsonTree.get("networks");
+            networkRes.forEach(node -> {
+                JsonNode resourceName = node.get("resourceName");
+                nullIsIllegal(resourceName, INVALID_RESOURCE_NAME);
 
-            if (inBytes != null) {
-                cm = new ControlMetric(ControlMetricType.NW_INCOMING_BYTES,
-                        new MetricValue.Builder().load(inBytes.asLong()).add());
-                service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
-            }
+                JsonNode inBytes = jsonTree.get("incomingBytes");
+                JsonNode outBytes = jsonTree.get("outgoingBytes");
+                JsonNode inPackets = jsonTree.get("incomingPackets");
+                JsonNode outPackets = jsonTree.get("outgoingPackets");
 
-            if (outBytes != null) {
-                cm = new ControlMetric(ControlMetricType.NW_OUTGOING_BYTES,
-                        new MetricValue.Builder().load(outBytes.asLong()).add());
-                service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
-            }
+                if (inBytes != null) {
+                    cm[0] = new ControlMetric(ControlMetricType.NW_INCOMING_BYTES,
+                            new MetricValue.Builder().load(inBytes.asLong()).add());
+                    service.updateMetric(cm[0], UPDATE_INTERVAL, resourceName.asText());
+                }
 
-            if (inPackets != null) {
-                cm = new ControlMetric(ControlMetricType.NW_INCOMING_PACKETS,
-                        new MetricValue.Builder().load(inPackets.asLong()).add());
-                service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
-            }
+                if (outBytes != null) {
+                    cm[0] = new ControlMetric(ControlMetricType.NW_OUTGOING_BYTES,
+                            new MetricValue.Builder().load(outBytes.asLong()).add());
+                    service.updateMetric(cm[0], UPDATE_INTERVAL, resourceName.asText());
+                }
 
-            if (outPackets != null) {
-                cm = new ControlMetric(ControlMetricType.NW_OUTGOING_PACKETS,
-                        new MetricValue.Builder().load(outPackets.asLong()).add());
-                service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
-            }
+                if (inPackets != null) {
+                    cm[0] = new ControlMetric(ControlMetricType.NW_INCOMING_PACKETS,
+                            new MetricValue.Builder().load(inPackets.asLong()).add());
+                    service.updateMetric(cm[0], UPDATE_INTERVAL, resourceName.asText());
+                }
 
+                if (outPackets != null) {
+                    cm[0] = new ControlMetric(ControlMetricType.NW_OUTGOING_PACKETS,
+                            new MetricValue.Builder().load(outPackets.asLong()).add());
+                    service.updateMetric(cm[0], UPDATE_INTERVAL, resourceName.asText());
+                }
+            });
         } catch (IOException e) {
             throw new IllegalArgumentException(e.getMessage());
         }
         return ok(root).build();
     }
 
-
     /**
      * Collects system specifications.
      * The system specs include the various control metrics
@@ -283,4 +296,4 @@
         }
         return ok(root).build();
     }
-}
+}
\ No newline at end of file
diff --git a/apps/cpman/app/src/main/resources/definitions/DiskMetricsPost.json b/apps/cpman/app/src/main/resources/definitions/DiskMetricsPost.json
index fe0dab1..ea2bbd5 100644
--- a/apps/cpman/app/src/main/resources/definitions/DiskMetricsPost.json
+++ b/apps/cpman/app/src/main/resources/definitions/DiskMetricsPost.json
@@ -1,19 +1,41 @@
 {
   "type": "object",
+  "title": "disks",
   "required": [
-    "readBytes",
-    "writeBytes"
+    "disks"
   ],
   "properties": {
-    "readBytes": {
-      "type": "integer",
-      "format": "int64",
-      "example": "500"
-    },
-    "writeBytes": {
-      "type": "integer",
-      "format": "int64",
-      "example": "300"
+    "disks": {
+      "type": "array",
+      "xml": {
+        "name": "disks",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "disks",
+        "required": [
+          "resourceName",
+          "readBytes",
+          "writeBytes"
+        ],
+        "properties": {
+          "resourceName": {
+            "type": "string",
+            "example": "disk1"
+          },
+          "readBytes": {
+            "type": "integer",
+            "format": "int64",
+            "example": "500"
+          },
+          "writeBytes": {
+            "type": "integer",
+            "format": "int64",
+            "example": "300"
+          }
+        }
+      }
     }
   }
 }
\ No newline at end of file
diff --git a/apps/cpman/app/src/main/resources/definitions/NetworkMetricsPost.json b/apps/cpman/app/src/main/resources/definitions/NetworkMetricsPost.json
index f9ad7d3..a04bdd8 100644
--- a/apps/cpman/app/src/main/resources/definitions/NetworkMetricsPost.json
+++ b/apps/cpman/app/src/main/resources/definitions/NetworkMetricsPost.json
@@ -1,31 +1,53 @@
 {
   "type": "object",
+  "title": "networks",
   "required": [
-    "incomingBytes",
-    "outgoingBytes",
-    "incomingPackets",
-    "outgoingPackets"
+    "networks"
   ],
   "properties": {
-    "incomingBytes": {
-      "type": "integer",
-      "format": "int64",
-      "example": "1024"
-    },
-    "outgoingBytes": {
-      "type": "integer",
-      "format": "int64",
-      "example": "1024"
-    },
-    "incomingPackets": {
-      "type": "integer",
-      "format": "int64",
-      "example": "1000"
-    },
-    "outgoingPackets": {
-      "type": "integer",
-      "format": "int64",
-      "example": "2000"
+    "networks": {
+      "type": "array",
+      "xml": {
+        "name": "networks",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "networks",
+        "required": [
+          "resourceName",
+          "incomingBytes",
+          "outgoingBytes",
+          "incomingPackets",
+          "outgoingPackets"
+        ],
+        "properties": {
+          "resourceName": {
+            "type": "string",
+            "example": "eth0"
+          },
+          "incomingBytes": {
+            "type": "integer",
+            "format": "int64",
+            "example": "1024"
+          },
+          "outgoingBytes": {
+            "type": "integer",
+            "format": "int64",
+            "example": "1024"
+          },
+          "incomingPackets": {
+            "type": "integer",
+            "format": "int64",
+            "example": "1000"
+          },
+          "outgoingPackets": {
+            "type": "integer",
+            "format": "int64",
+            "example": "2000"
+          }
+        }
+      }
     }
   }
 }
\ No newline at end of file
diff --git a/apps/cpman/app/src/test/java/org/onosproject/cpman/rest/ControlMetricsCollectorResourceTest.java b/apps/cpman/app/src/test/java/org/onosproject/cpman/rest/ControlMetricsCollectorResourceTest.java
index edfc6d6..ad84f17 100644
--- a/apps/cpman/app/src/test/java/org/onosproject/cpman/rest/ControlMetricsCollectorResourceTest.java
+++ b/apps/cpman/app/src/test/java/org/onosproject/cpman/rest/ControlMetricsCollectorResourceTest.java
@@ -37,6 +37,7 @@
 import java.util.Optional;
 
 import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expectLastCall;
 import static org.easymock.EasyMock.replay;
@@ -84,19 +85,17 @@
     }
 
     @Test
-    public void testDiskMetricsPost() {
-        mockControlPlaneMonitorService.updateMetric(anyObject(), anyObject(),
-                (Optional<DeviceId>) anyObject());
-        expectLastCall().times(2);
+    public void testDiskMetricsWithNullName() {
+        mockControlPlaneMonitorService.updateMetric(anyObject(), anyObject(), anyString());
+        expectLastCall().times(4);
         replay(mockControlPlaneMonitorService);
         basePostTest("disk-metrics-post.json", PREFIX + "/disk_metrics");
     }
 
     @Test
-    public void testNetworkMetricsPost() {
-        mockControlPlaneMonitorService.updateMetric(anyObject(), anyObject(),
-                (Optional<DeviceId>) anyObject());
-        expectLastCall().times(4);
+    public void testNetworkMetricsWithNullName() {
+        mockControlPlaneMonitorService.updateMetric(anyObject(), anyObject(), anyString());
+        expectLastCall().times(8);
         replay(mockControlPlaneMonitorService);
         basePostTest("network-metrics-post.json", PREFIX + "/network_metrics");
     }
@@ -106,16 +105,20 @@
         basePostTest("system-spec-post.json", PREFIX + "/system_specs");
     }
 
-    private void basePostTest(String jsonFile, String path) {
+    private ClientResponse baseTest(String jsonFile, String path) {
         final WebResource rs = resource();
         InputStream jsonStream = ControlMetricsCollectorResourceTest.class
                 .getResourceAsStream(jsonFile);
 
         assertThat(jsonStream, notNullValue());
 
-        ClientResponse response = rs.path(path)
+        return rs.path(path)
                 .type(MediaType.APPLICATION_JSON_TYPE)
                 .post(ClientResponse.class, jsonStream);
+    }
+
+    private void basePostTest(String jsonFile, String path) {
+        ClientResponse response = baseTest(jsonFile, path);
         assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
     }
 
diff --git a/apps/cpman/app/src/test/resources/org/onosproject/cpman/rest/disk-metrics-post.json b/apps/cpman/app/src/test/resources/org/onosproject/cpman/rest/disk-metrics-post.json
index ebdf00a..3fc34e6 100644
--- a/apps/cpman/app/src/test/resources/org/onosproject/cpman/rest/disk-metrics-post.json
+++ b/apps/cpman/app/src/test/resources/org/onosproject/cpman/rest/disk-metrics-post.json
@@ -1,4 +1,14 @@
 {
-  "readBytes": 500,
-  "writeBytes": 300
+  "disks": [
+    {
+      "resourceName": "disk1",
+      "readBytes": 500,
+      "writeBytes": 300
+    },
+    {
+      "resourceName": "disk2",
+      "readBytes": 500,
+      "writeBytes": 300
+    }
+  ]
 }
\ No newline at end of file
diff --git a/apps/cpman/app/src/test/resources/org/onosproject/cpman/rest/network-metrics-post.json b/apps/cpman/app/src/test/resources/org/onosproject/cpman/rest/network-metrics-post.json
index bdf7c8d..dec521c 100644
--- a/apps/cpman/app/src/test/resources/org/onosproject/cpman/rest/network-metrics-post.json
+++ b/apps/cpman/app/src/test/resources/org/onosproject/cpman/rest/network-metrics-post.json
@@ -1,6 +1,18 @@
 {
-  "incomingBytes": 1024,
-  "outgoingBytes": 1024,
-  "incomingPackets": 1000,
-  "outgoingPackets": 2000
+  "networks": [
+    {
+      "resourceName": "eth0",
+      "incomingBytes": 1024,
+      "outgoingBytes": 1024,
+      "incomingPackets": 1000,
+      "outgoingPackets": 2000
+    },
+    {
+      "resourceName": "eth1",
+      "incomingBytes": 1024,
+      "outgoingBytes": 1024,
+      "incomingPackets": 1000,
+      "outgoingPackets": 2000
+    }
+  ]
 }
\ No newline at end of file