Jian Li
Committed by Gerrit Code Review

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
......@@ -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.IOException;
import java.io.InputStream;
import java.util.Optional;
import static org.onlab.util.Tools.nullIsIllegal;
/**
* Collect control plane metrics.
*/
......@@ -43,6 +46,7 @@ public class ControlMetricsCollectorWebResource extends AbstractWebResource {
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 @@ public class ControlMetricsCollectorWebResource extends AbstractWebResource {
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 @@ public class ControlMetricsCollectorWebResource extends AbstractWebResource {
@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");
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));
}
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));
}
ArrayNode diskRes = (ArrayNode) jsonTree.get("disks");
diskRes.forEach(node-> {
JsonNode resourceName = node.get("resourceName");
nullIsIllegal(resourceName, INVALID_RESOURCE_NAME);
JsonNode readBytes = jsonTree.get("readBytes");
JsonNode writeBytes = jsonTree.get("writeBytes");
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 @@ public class ControlMetricsCollectorWebResource extends AbstractWebResource {
@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");
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));
}
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 (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 (outPackets != null) {
cm = new ControlMetric(ControlMetricType.NW_OUTGOING_PACKETS,
new MetricValue.Builder().load(outPackets.asLong()).add());
service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
}
ArrayNode networkRes = (ArrayNode) jsonTree.get("networks");
networkRes.forEach(node -> {
JsonNode resourceName = node.get("resourceName");
nullIsIllegal(resourceName, INVALID_RESOURCE_NAME);
JsonNode inBytes = jsonTree.get("incomingBytes");
JsonNode outBytes = jsonTree.get("outgoingBytes");
JsonNode inPackets = jsonTree.get("incomingPackets");
JsonNode outPackets = jsonTree.get("outgoingPackets");
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 (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 (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 @@ public class ControlMetricsCollectorWebResource extends AbstractWebResource {
}
return ok(root).build();
}
}
}
\ No newline at end of file
......
{
"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
......
{
"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
......
......@@ -37,6 +37,7 @@ import java.net.ServerSocket;
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 @@ public class ControlMetricsCollectorResourceTest extends JerseyTest {
}
@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 @@ public class ControlMetricsCollectorResourceTest extends JerseyTest {
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));
}
......
{
"readBytes": 500,
"writeBytes": 300
"disks": [
{
"resourceName": "disk1",
"readBytes": 500,
"writeBytes": 300
},
{
"resourceName": "disk2",
"readBytes": 500,
"writeBytes": 300
}
]
}
\ No newline at end of file
......
{
"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
......