Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2016 Open Networking Laboratory |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | package org.onosproject.cpman.rest; |
| 17 | |
| 18 | import com.fasterxml.jackson.databind.JsonNode; |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 19 | import com.fasterxml.jackson.databind.node.ArrayNode; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
| 21 | import org.onosproject.cpman.ControlMetric; |
| 22 | import org.onosproject.cpman.ControlMetricType; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 23 | import org.onosproject.cpman.ControlPlaneMonitorService; |
| 24 | import org.onosproject.cpman.MetricValue; |
Jian Li | 1a42469 | 2016-02-03 16:21:18 -0800 | [diff] [blame] | 25 | import org.onosproject.cpman.SystemInfo; |
| 26 | import org.onosproject.cpman.impl.DefaultSystemInfo; |
| 27 | import org.onosproject.cpman.impl.SystemInfoFactory; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 28 | import org.onosproject.rest.AbstractWebResource; |
| 29 | |
| 30 | import javax.ws.rs.Consumes; |
| 31 | import javax.ws.rs.POST; |
| 32 | import javax.ws.rs.Path; |
| 33 | import javax.ws.rs.Produces; |
| 34 | import javax.ws.rs.core.MediaType; |
| 35 | import javax.ws.rs.core.Response; |
| 36 | import java.io.IOException; |
| 37 | import java.io.InputStream; |
| 38 | import java.util.Optional; |
| 39 | |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 40 | import static org.onlab.util.Tools.nullIsIllegal; |
| 41 | |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 42 | /** |
Jian Li | 80c1270 | 2016-02-20 08:58:19 +0900 | [diff] [blame] | 43 | * Collect system metrics. |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 44 | */ |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 45 | @Path("collector") |
Jian Li | 80c1270 | 2016-02-20 08:58:19 +0900 | [diff] [blame] | 46 | public class SystemMetricsCollectorWebResource extends AbstractWebResource { |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 47 | |
Jian Li | 80c1270 | 2016-02-20 08:58:19 +0900 | [diff] [blame] | 48 | private final ControlPlaneMonitorService service = get(ControlPlaneMonitorService.class); |
| 49 | private static final int UPDATE_INTERVAL_IN_MINUTE = 1; |
| 50 | private static final String INVALID_SYSTEM_SPECS = "Invalid system specifications"; |
| 51 | private static final String INVALID_RESOURCE_NAME = "Invalid resource name"; |
| 52 | private static final String INVALID_REQUEST = "Invalid request"; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 53 | |
| 54 | /** |
| 55 | * Collects CPU metrics. |
| 56 | * |
| 57 | * @param stream JSON stream |
| 58 | * @return 200 OK |
| 59 | * @onos.rsModel CpuMetricsPost |
| 60 | */ |
| 61 | @POST |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 62 | @Path("cpu_metrics") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 63 | @Consumes(MediaType.APPLICATION_JSON) |
| 64 | @Produces(MediaType.APPLICATION_JSON) |
| 65 | public Response cpuMetrics(InputStream stream) { |
| 66 | ObjectNode root = mapper().createObjectNode(); |
| 67 | ControlMetric cm; |
| 68 | try { |
| 69 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 70 | long cpuLoad = nullIsIllegal(jsonTree.get("cpuLoad").asLong(), INVALID_REQUEST); |
| 71 | long totalCpuTime = nullIsIllegal(jsonTree.get("totalCpuTime").asLong(), INVALID_REQUEST); |
| 72 | long sysCpuTime = nullIsIllegal(jsonTree.get("sysCpuTime").asLong(), INVALID_REQUEST); |
| 73 | long userCpuTime = nullIsIllegal(jsonTree.get("userCpuTime").asLong(), INVALID_REQUEST); |
| 74 | long cpuIdleTime = nullIsIllegal(jsonTree.get("cpuIdleTime").asLong(), INVALID_REQUEST); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 75 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 76 | cm = new ControlMetric(ControlMetricType.CPU_LOAD, |
| 77 | new MetricValue.Builder().load(cpuLoad).add()); |
| 78 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 79 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 80 | cm = new ControlMetric(ControlMetricType.TOTAL_CPU_TIME, |
| 81 | new MetricValue.Builder().load(totalCpuTime).add()); |
| 82 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 83 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 84 | cm = new ControlMetric(ControlMetricType.SYS_CPU_TIME, |
| 85 | new MetricValue.Builder().load(sysCpuTime).add()); |
| 86 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 87 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 88 | cm = new ControlMetric(ControlMetricType.USER_CPU_TIME, |
| 89 | new MetricValue.Builder().load(userCpuTime).add()); |
| 90 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 91 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 92 | cm = new ControlMetric(ControlMetricType.CPU_IDLE_TIME, |
| 93 | new MetricValue.Builder().load(cpuIdleTime).add()); |
| 94 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 95 | |
| 96 | } catch (IOException e) { |
| 97 | throw new IllegalArgumentException(e.getMessage()); |
| 98 | } |
| 99 | return ok(root).build(); |
| 100 | } |
| 101 | |
| 102 | /** |
| 103 | * Collects memory metrics. |
| 104 | * |
| 105 | * @param stream JSON stream |
| 106 | * @return 200 OK |
| 107 | * @onos.rsModel MemoryMetricsPost |
| 108 | */ |
| 109 | @POST |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 110 | @Path("memory_metrics") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 111 | @Consumes(MediaType.APPLICATION_JSON) |
| 112 | @Produces(MediaType.APPLICATION_JSON) |
| 113 | public Response memoryMetrics(InputStream stream) { |
| 114 | ObjectNode root = mapper().createObjectNode(); |
| 115 | ControlMetric cm; |
| 116 | try { |
| 117 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 118 | long memUsedRatio = nullIsIllegal(jsonTree.get("memoryUsedRatio").asLong(), INVALID_REQUEST); |
| 119 | long memFreeRatio = nullIsIllegal(jsonTree.get("memoryFreeRatio").asLong(), INVALID_REQUEST); |
| 120 | long memUsed = nullIsIllegal(jsonTree.get("memoryUsed").asLong(), INVALID_REQUEST); |
| 121 | long memFree = nullIsIllegal(jsonTree.get("memoryFree").asLong(), INVALID_REQUEST); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 122 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 123 | cm = new ControlMetric(ControlMetricType.MEMORY_USED_RATIO, |
| 124 | new MetricValue.Builder().load(memUsedRatio).add()); |
| 125 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 126 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 127 | cm = new ControlMetric(ControlMetricType.MEMORY_FREE_RATIO, |
| 128 | new MetricValue.Builder().load(memFreeRatio).add()); |
| 129 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 130 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 131 | cm = new ControlMetric(ControlMetricType.MEMORY_USED, |
| 132 | new MetricValue.Builder().load(memUsed).add()); |
| 133 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 134 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 135 | cm = new ControlMetric(ControlMetricType.MEMORY_FREE, |
| 136 | new MetricValue.Builder().load(memFree).add()); |
| 137 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 138 | |
| 139 | } catch (IOException e) { |
| 140 | throw new IllegalArgumentException(e.getMessage()); |
| 141 | } |
| 142 | return ok(root).build(); |
| 143 | } |
| 144 | |
| 145 | /** |
| 146 | * Collects disk metrics. |
| 147 | * |
| 148 | * @param stream JSON stream |
| 149 | * @return 200 OK |
| 150 | * @onos.rsModel DiskMetricsPost |
| 151 | */ |
| 152 | @POST |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 153 | @Path("disk_metrics") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 154 | @Consumes(MediaType.APPLICATION_JSON) |
| 155 | @Produces(MediaType.APPLICATION_JSON) |
| 156 | public Response diskMetrics(InputStream stream) { |
| 157 | ObjectNode root = mapper().createObjectNode(); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 158 | ControlMetric cm; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 159 | try { |
| 160 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 161 | ArrayNode diskRes = (ArrayNode) jsonTree.get("disks"); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 162 | for (JsonNode node : diskRes) { |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 163 | JsonNode resourceName = node.get("resourceName"); |
| 164 | nullIsIllegal(resourceName, INVALID_RESOURCE_NAME); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 165 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 166 | long readBytes = nullIsIllegal(node.get("readBytes").asLong(), INVALID_REQUEST); |
| 167 | long writeBytes = nullIsIllegal(node.get("writeBytes").asLong(), INVALID_REQUEST); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 168 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 169 | cm = new ControlMetric(ControlMetricType.DISK_READ_BYTES, |
| 170 | new MetricValue.Builder().load(readBytes).add()); |
| 171 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 172 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 173 | cm = new ControlMetric(ControlMetricType.DISK_WRITE_BYTES, |
| 174 | new MetricValue.Builder().load(writeBytes).add()); |
| 175 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
| 176 | } |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 177 | } catch (IOException e) { |
| 178 | throw new IllegalArgumentException(e.getMessage()); |
| 179 | } |
| 180 | return ok(root).build(); |
| 181 | } |
| 182 | |
| 183 | /** |
| 184 | * Collects network metrics. |
| 185 | * |
| 186 | * @param stream JSON stream |
| 187 | * @return 200 OK |
| 188 | * @onos.rsModel NetworkMetricsPost |
| 189 | */ |
| 190 | @POST |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 191 | @Path("network_metrics") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 192 | @Consumes(MediaType.APPLICATION_JSON) |
| 193 | @Produces(MediaType.APPLICATION_JSON) |
| 194 | public Response networkMetrics(InputStream stream) { |
| 195 | ObjectNode root = mapper().createObjectNode(); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 196 | ControlMetric cm; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 197 | try { |
| 198 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 199 | ArrayNode networkRes = (ArrayNode) jsonTree.get("networks"); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 200 | for (JsonNode node : networkRes) { |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 201 | JsonNode resourceName = node.get("resourceName"); |
| 202 | nullIsIllegal(resourceName, INVALID_RESOURCE_NAME); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 203 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 204 | long inBytes = nullIsIllegal(node.get("incomingBytes").asLong(), INVALID_REQUEST); |
| 205 | long outBytes = nullIsIllegal(node.get("outgoingBytes").asLong(), INVALID_REQUEST); |
| 206 | long inPackets = nullIsIllegal(node.get("incomingPackets").asLong(), INVALID_REQUEST); |
| 207 | long outPackets = nullIsIllegal(node.get("outgoingPackets").asLong(), INVALID_REQUEST); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 208 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 209 | cm = new ControlMetric(ControlMetricType.NW_INCOMING_BYTES, |
| 210 | new MetricValue.Builder().load(inBytes).add()); |
| 211 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 212 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 213 | cm = new ControlMetric(ControlMetricType.NW_OUTGOING_BYTES, |
| 214 | new MetricValue.Builder().load(outBytes).add()); |
| 215 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 216 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 217 | cm = new ControlMetric(ControlMetricType.NW_INCOMING_PACKETS, |
| 218 | new MetricValue.Builder().load(inPackets).add()); |
| 219 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 220 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame] | 221 | cm = new ControlMetric(ControlMetricType.NW_OUTGOING_PACKETS, |
| 222 | new MetricValue.Builder().load(outPackets).add()); |
| 223 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
| 224 | } |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 225 | } catch (IOException e) { |
| 226 | throw new IllegalArgumentException(e.getMessage()); |
| 227 | } |
| 228 | return ok(root).build(); |
| 229 | } |
| 230 | |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 231 | /** |
Jian Li | 1a42469 | 2016-02-03 16:21:18 -0800 | [diff] [blame] | 232 | * Collects system information. |
| 233 | * The system information includes the various control metrics |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 234 | * which do not require aggregation. |
| 235 | * |
| 236 | * @param stream JSON stream |
| 237 | * @return 200 OK |
Jian Li | 1a42469 | 2016-02-03 16:21:18 -0800 | [diff] [blame] | 238 | * @onos.rsModel SystemInfoPost |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 239 | */ |
| 240 | @POST |
Jian Li | 1a42469 | 2016-02-03 16:21:18 -0800 | [diff] [blame] | 241 | @Path("system_info") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 242 | @Consumes(MediaType.APPLICATION_JSON) |
| 243 | @Produces(MediaType.APPLICATION_JSON) |
Jian Li | 1a42469 | 2016-02-03 16:21:18 -0800 | [diff] [blame] | 244 | public Response systemInfo(InputStream stream) { |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 245 | ObjectNode root = mapper().createObjectNode(); |
| 246 | |
| 247 | try { |
| 248 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
| 249 | JsonNode numOfCores = jsonTree.get("numOfCores"); |
| 250 | JsonNode numOfCpus = jsonTree.get("numOfCpus"); |
| 251 | JsonNode cpuSpeed = jsonTree.get("cpuSpeed"); |
| 252 | JsonNode totalMemory = jsonTree.get("totalMemory"); |
| 253 | |
Jian Li | 1a42469 | 2016-02-03 16:21:18 -0800 | [diff] [blame] | 254 | if (numOfCores != null && numOfCpus != null && |
| 255 | cpuSpeed != null && totalMemory != null) { |
| 256 | SystemInfo systemInfo = new DefaultSystemInfo.Builder() |
| 257 | .numOfCores(numOfCores.asInt()) |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 258 | .numOfCpus(numOfCpus.asInt()) |
| 259 | .cpuSpeed(cpuSpeed.asInt()) |
Jian Li | 1a42469 | 2016-02-03 16:21:18 -0800 | [diff] [blame] | 260 | .totalMemory(totalMemory.asInt()) |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 261 | .build(); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 262 | |
Jian Li | 1a42469 | 2016-02-03 16:21:18 -0800 | [diff] [blame] | 263 | // try to store the system info. |
| 264 | SystemInfoFactory.getInstance().setSystemInfo(systemInfo); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 265 | } else { |
| 266 | throw new IllegalArgumentException(INVALID_SYSTEM_SPECS); |
| 267 | } |
| 268 | |
| 269 | } catch (IOException e) { |
| 270 | throw new IllegalArgumentException(e.getMessage()); |
| 271 | } |
| 272 | return ok(root).build(); |
| 273 | } |
Jian Li | 9d61649 | 2016-03-09 10:52:49 -0800 | [diff] [blame] | 274 | } |