[ONOS-3663] Implement control metrics REST API
Change-Id: Ifc901863e55cdd161d704ecd584242786671af87
diff --git a/apps/cpman/app/src/main/java/org/onosproject/cpman/rest/SystemMetricsCollectorWebResource.java b/apps/cpman/app/src/main/java/org/onosproject/cpman/rest/SystemMetricsCollectorWebResource.java
new file mode 100644
index 0000000..6a6e50f
--- /dev/null
+++ b/apps/cpman/app/src/main/java/org/onosproject/cpman/rest/SystemMetricsCollectorWebResource.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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.ControlPlaneMonitorService;
+import org.onosproject.cpman.MetricValue;
+import org.onosproject.cpman.SystemInfo;
+import org.onosproject.cpman.impl.DefaultSystemInfo;
+import org.onosproject.cpman.impl.SystemInfoFactory;
+import org.onosproject.rest.AbstractWebResource;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Optional;
+
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * Collect system metrics.
+ */
+@Path("collector")
+public class SystemMetricsCollectorWebResource extends AbstractWebResource {
+
+ private final ControlPlaneMonitorService service = get(ControlPlaneMonitorService.class);
+ private static final int UPDATE_INTERVAL_IN_MINUTE = 1;
+ private static final String INVALID_SYSTEM_SPECS = "Invalid system specifications";
+ private static final String INVALID_RESOURCE_NAME = "Invalid resource name";
+ private static final String INVALID_REQUEST = "Invalid request";
+
+ /**
+ * Collects CPU metrics.
+ *
+ * @param stream JSON stream
+ * @return 200 OK
+ * @onos.rsModel CpuMetricsPost
+ */
+ @POST
+ @Path("cpu_metrics")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response cpuMetrics(InputStream stream) {
+ ObjectNode root = mapper().createObjectNode();
+ ControlMetric cm;
+ try {
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+ long cpuLoad = nullIsIllegal(jsonTree.get("cpuLoad").asLong(), INVALID_REQUEST);
+ long totalCpuTime = nullIsIllegal(jsonTree.get("totalCpuTime").asLong(), INVALID_REQUEST);
+ long sysCpuTime = nullIsIllegal(jsonTree.get("sysCpuTime").asLong(), INVALID_REQUEST);
+ long userCpuTime = nullIsIllegal(jsonTree.get("userCpuTime").asLong(), INVALID_REQUEST);
+ long cpuIdleTime = nullIsIllegal(jsonTree.get("cpuIdleTime").asLong(), INVALID_REQUEST);
+
+ cm = new ControlMetric(ControlMetricType.CPU_LOAD,
+ new MetricValue.Builder().load(cpuLoad).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null));
+
+ cm = new ControlMetric(ControlMetricType.TOTAL_CPU_TIME,
+ new MetricValue.Builder().load(totalCpuTime).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null));
+
+ cm = new ControlMetric(ControlMetricType.SYS_CPU_TIME,
+ new MetricValue.Builder().load(sysCpuTime).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null));
+
+ cm = new ControlMetric(ControlMetricType.USER_CPU_TIME,
+ new MetricValue.Builder().load(userCpuTime).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null));
+
+ cm = new ControlMetric(ControlMetricType.CPU_IDLE_TIME,
+ new MetricValue.Builder().load(cpuIdleTime).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null));
+
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ return ok(root).build();
+ }
+
+ /**
+ * Collects memory metrics.
+ *
+ * @param stream JSON stream
+ * @return 200 OK
+ * @onos.rsModel MemoryMetricsPost
+ */
+ @POST
+ @Path("memory_metrics")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response memoryMetrics(InputStream stream) {
+ ObjectNode root = mapper().createObjectNode();
+ ControlMetric cm;
+ try {
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+ long memUsedRatio = nullIsIllegal(jsonTree.get("memoryUsedRatio").asLong(), INVALID_REQUEST);
+ long memFreeRatio = nullIsIllegal(jsonTree.get("memoryFreeRatio").asLong(), INVALID_REQUEST);
+ long memUsed = nullIsIllegal(jsonTree.get("memoryUsed").asLong(), INVALID_REQUEST);
+ long memFree = nullIsIllegal(jsonTree.get("memoryFree").asLong(), INVALID_REQUEST);
+
+ cm = new ControlMetric(ControlMetricType.MEMORY_USED_RATIO,
+ new MetricValue.Builder().load(memUsedRatio).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null));
+
+ cm = new ControlMetric(ControlMetricType.MEMORY_FREE_RATIO,
+ new MetricValue.Builder().load(memFreeRatio).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null));
+
+ cm = new ControlMetric(ControlMetricType.MEMORY_USED,
+ new MetricValue.Builder().load(memUsed).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null));
+
+ cm = new ControlMetric(ControlMetricType.MEMORY_FREE,
+ new MetricValue.Builder().load(memFree).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null));
+
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ return ok(root).build();
+ }
+
+ /**
+ * Collects disk metrics.
+ *
+ * @param stream JSON stream
+ * @return 200 OK
+ * @onos.rsModel DiskMetricsPost
+ */
+ @POST
+ @Path("disk_metrics")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response diskMetrics(InputStream stream) {
+ ObjectNode root = mapper().createObjectNode();
+ ControlMetric cm;
+ try {
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+ ArrayNode diskRes = (ArrayNode) jsonTree.get("disks");
+ for (JsonNode node : diskRes) {
+ JsonNode resourceName = node.get("resourceName");
+ nullIsIllegal(resourceName, INVALID_RESOURCE_NAME);
+
+ long readBytes = nullIsIllegal(node.get("readBytes").asLong(), INVALID_REQUEST);
+ long writeBytes = nullIsIllegal(node.get("writeBytes").asLong(), INVALID_REQUEST);
+
+ cm = new ControlMetric(ControlMetricType.DISK_READ_BYTES,
+ new MetricValue.Builder().load(readBytes).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText());
+
+ cm = new ControlMetric(ControlMetricType.DISK_WRITE_BYTES,
+ new MetricValue.Builder().load(writeBytes).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText());
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ return ok(root).build();
+ }
+
+ /**
+ * Collects network metrics.
+ *
+ * @param stream JSON stream
+ * @return 200 OK
+ * @onos.rsModel NetworkMetricsPost
+ */
+ @POST
+ @Path("network_metrics")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response networkMetrics(InputStream stream) {
+ ObjectNode root = mapper().createObjectNode();
+ ControlMetric cm;
+ try {
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+ ArrayNode networkRes = (ArrayNode) jsonTree.get("networks");
+ for (JsonNode node : networkRes) {
+ JsonNode resourceName = node.get("resourceName");
+ nullIsIllegal(resourceName, INVALID_RESOURCE_NAME);
+
+ long inBytes = nullIsIllegal(node.get("incomingBytes").asLong(), INVALID_REQUEST);
+ long outBytes = nullIsIllegal(node.get("outgoingBytes").asLong(), INVALID_REQUEST);
+ long inPackets = nullIsIllegal(node.get("incomingPackets").asLong(), INVALID_REQUEST);
+ long outPackets = nullIsIllegal(node.get("outgoingPackets").asLong(), INVALID_REQUEST);
+
+ cm = new ControlMetric(ControlMetricType.NW_INCOMING_BYTES,
+ new MetricValue.Builder().load(inBytes).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText());
+
+ cm = new ControlMetric(ControlMetricType.NW_OUTGOING_BYTES,
+ new MetricValue.Builder().load(outBytes).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText());
+
+ cm = new ControlMetric(ControlMetricType.NW_INCOMING_PACKETS,
+ new MetricValue.Builder().load(inPackets).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText());
+
+ cm = new ControlMetric(ControlMetricType.NW_OUTGOING_PACKETS,
+ new MetricValue.Builder().load(outPackets).add());
+ service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText());
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ return ok(root).build();
+ }
+
+ /**
+ * Collects system information.
+ * The system information includes the various control metrics
+ * which do not require aggregation.
+ *
+ * @param stream JSON stream
+ * @return 200 OK
+ * @onos.rsModel SystemInfoPost
+ */
+ @POST
+ @Path("system_info")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response systemInfo(InputStream stream) {
+ ObjectNode root = mapper().createObjectNode();
+
+ try {
+ ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+ JsonNode numOfCores = jsonTree.get("numOfCores");
+ JsonNode numOfCpus = jsonTree.get("numOfCpus");
+ JsonNode cpuSpeed = jsonTree.get("cpuSpeed");
+ JsonNode totalMemory = jsonTree.get("totalMemory");
+
+ if (numOfCores != null && numOfCpus != null &&
+ cpuSpeed != null && totalMemory != null) {
+ SystemInfo systemInfo = new DefaultSystemInfo.Builder()
+ .numOfCores(numOfCores.asInt())
+ .numOfCpus(numOfCpus.asInt())
+ .cpuSpeed(cpuSpeed.asInt())
+ .totalMemory(totalMemory.asInt())
+ .build();
+
+ // try to store the system info.
+ SystemInfoFactory.getInstance().setSystemInfo(systemInfo);
+ } else {
+ throw new IllegalArgumentException(INVALID_SYSTEM_SPECS);
+ }
+
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ return ok(root).build();
+ }
+}