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 | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 25 | import org.onosproject.cpman.impl.ControlMetricsSystemSpec; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 26 | import org.onosproject.rest.AbstractWebResource; |
| 27 | |
| 28 | import javax.ws.rs.Consumes; |
| 29 | import javax.ws.rs.POST; |
| 30 | import javax.ws.rs.Path; |
| 31 | import javax.ws.rs.Produces; |
| 32 | import javax.ws.rs.core.MediaType; |
| 33 | import javax.ws.rs.core.Response; |
| 34 | import java.io.IOException; |
| 35 | import java.io.InputStream; |
| 36 | import java.util.Optional; |
| 37 | |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 38 | import static org.onlab.util.Tools.nullIsIllegal; |
| 39 | |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 40 | /** |
| 41 | * Collect control plane metrics. |
| 42 | */ |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 43 | @Path("collector") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 44 | public class ControlMetricsCollectorWebResource extends AbstractWebResource { |
| 45 | |
| 46 | final ControlPlaneMonitorService service = get(ControlPlaneMonitorService.class); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 47 | public static final int UPDATE_INTERVAL_IN_MINUTE = 1; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 48 | public static final String INVALID_SYSTEM_SPECS = "Invalid system specifications"; |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 49 | public static final String INVALID_RESOURCE_NAME = "Invalid resource name"; |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 50 | public static final String INVALID_REQUEST = "Invalid request"; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 51 | |
| 52 | /** |
| 53 | * Collects CPU metrics. |
| 54 | * |
| 55 | * @param stream JSON stream |
| 56 | * @return 200 OK |
| 57 | * @onos.rsModel CpuMetricsPost |
| 58 | */ |
| 59 | @POST |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 60 | @Path("cpu_metrics") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 61 | @Consumes(MediaType.APPLICATION_JSON) |
| 62 | @Produces(MediaType.APPLICATION_JSON) |
| 63 | public Response cpuMetrics(InputStream stream) { |
| 64 | ObjectNode root = mapper().createObjectNode(); |
| 65 | ControlMetric cm; |
| 66 | try { |
| 67 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 68 | long cpuLoad = nullIsIllegal(jsonTree.get("cpuLoad").asLong(), INVALID_REQUEST); |
| 69 | long totalCpuTime = nullIsIllegal(jsonTree.get("totalCpuTime").asLong(), INVALID_REQUEST); |
| 70 | long sysCpuTime = nullIsIllegal(jsonTree.get("sysCpuTime").asLong(), INVALID_REQUEST); |
| 71 | long userCpuTime = nullIsIllegal(jsonTree.get("userCpuTime").asLong(), INVALID_REQUEST); |
| 72 | long cpuIdleTime = nullIsIllegal(jsonTree.get("cpuIdleTime").asLong(), INVALID_REQUEST); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 73 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 74 | cm = new ControlMetric(ControlMetricType.CPU_LOAD, |
| 75 | new MetricValue.Builder().load(cpuLoad).add()); |
| 76 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 77 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 78 | cm = new ControlMetric(ControlMetricType.TOTAL_CPU_TIME, |
| 79 | new MetricValue.Builder().load(totalCpuTime).add()); |
| 80 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 81 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 82 | cm = new ControlMetric(ControlMetricType.SYS_CPU_TIME, |
| 83 | new MetricValue.Builder().load(sysCpuTime).add()); |
| 84 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 85 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 86 | cm = new ControlMetric(ControlMetricType.USER_CPU_TIME, |
| 87 | new MetricValue.Builder().load(userCpuTime).add()); |
| 88 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 89 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 90 | cm = new ControlMetric(ControlMetricType.CPU_IDLE_TIME, |
| 91 | new MetricValue.Builder().load(cpuIdleTime).add()); |
| 92 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 93 | |
| 94 | } catch (IOException e) { |
| 95 | throw new IllegalArgumentException(e.getMessage()); |
| 96 | } |
| 97 | return ok(root).build(); |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * Collects memory metrics. |
| 102 | * |
| 103 | * @param stream JSON stream |
| 104 | * @return 200 OK |
| 105 | * @onos.rsModel MemoryMetricsPost |
| 106 | */ |
| 107 | @POST |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 108 | @Path("memory_metrics") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 109 | @Consumes(MediaType.APPLICATION_JSON) |
| 110 | @Produces(MediaType.APPLICATION_JSON) |
| 111 | public Response memoryMetrics(InputStream stream) { |
| 112 | ObjectNode root = mapper().createObjectNode(); |
| 113 | ControlMetric cm; |
| 114 | try { |
| 115 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 116 | long memUsedRatio = nullIsIllegal(jsonTree.get("memoryUsedRatio").asLong(), INVALID_REQUEST); |
| 117 | long memFreeRatio = nullIsIllegal(jsonTree.get("memoryFreeRatio").asLong(), INVALID_REQUEST); |
| 118 | long memUsed = nullIsIllegal(jsonTree.get("memoryUsed").asLong(), INVALID_REQUEST); |
| 119 | long memFree = nullIsIllegal(jsonTree.get("memoryFree").asLong(), INVALID_REQUEST); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 120 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 121 | cm = new ControlMetric(ControlMetricType.MEMORY_USED_RATIO, |
| 122 | new MetricValue.Builder().load(memUsedRatio).add()); |
| 123 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 124 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 125 | cm = new ControlMetric(ControlMetricType.MEMORY_FREE_RATIO, |
| 126 | new MetricValue.Builder().load(memFreeRatio).add()); |
| 127 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 128 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 129 | cm = new ControlMetric(ControlMetricType.MEMORY_USED, |
| 130 | new MetricValue.Builder().load(memUsed).add()); |
| 131 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 132 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 133 | cm = new ControlMetric(ControlMetricType.MEMORY_FREE, |
| 134 | new MetricValue.Builder().load(memFree).add()); |
| 135 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, Optional.ofNullable(null)); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 136 | |
| 137 | } catch (IOException e) { |
| 138 | throw new IllegalArgumentException(e.getMessage()); |
| 139 | } |
| 140 | return ok(root).build(); |
| 141 | } |
| 142 | |
| 143 | /** |
| 144 | * Collects disk metrics. |
| 145 | * |
| 146 | * @param stream JSON stream |
| 147 | * @return 200 OK |
| 148 | * @onos.rsModel DiskMetricsPost |
| 149 | */ |
| 150 | @POST |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 151 | @Path("disk_metrics") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 152 | @Consumes(MediaType.APPLICATION_JSON) |
| 153 | @Produces(MediaType.APPLICATION_JSON) |
| 154 | public Response diskMetrics(InputStream stream) { |
| 155 | ObjectNode root = mapper().createObjectNode(); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 156 | ControlMetric cm; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 157 | try { |
| 158 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 159 | ArrayNode diskRes = (ArrayNode) jsonTree.get("disks"); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 160 | for (JsonNode node : diskRes) { |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 161 | JsonNode resourceName = node.get("resourceName"); |
| 162 | nullIsIllegal(resourceName, INVALID_RESOURCE_NAME); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 163 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 164 | long readBytes = nullIsIllegal(node.get("readBytes").asLong(), INVALID_REQUEST); |
| 165 | long writeBytes = nullIsIllegal(node.get("writeBytes").asLong(), INVALID_REQUEST); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 166 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 167 | cm = new ControlMetric(ControlMetricType.DISK_READ_BYTES, |
| 168 | new MetricValue.Builder().load(readBytes).add()); |
| 169 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 170 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 171 | cm = new ControlMetric(ControlMetricType.DISK_WRITE_BYTES, |
| 172 | new MetricValue.Builder().load(writeBytes).add()); |
| 173 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
| 174 | } |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 175 | } catch (IOException e) { |
| 176 | throw new IllegalArgumentException(e.getMessage()); |
| 177 | } |
| 178 | return ok(root).build(); |
| 179 | } |
| 180 | |
| 181 | /** |
| 182 | * Collects network metrics. |
| 183 | * |
| 184 | * @param stream JSON stream |
| 185 | * @return 200 OK |
| 186 | * @onos.rsModel NetworkMetricsPost |
| 187 | */ |
| 188 | @POST |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 189 | @Path("network_metrics") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 190 | @Consumes(MediaType.APPLICATION_JSON) |
| 191 | @Produces(MediaType.APPLICATION_JSON) |
| 192 | public Response networkMetrics(InputStream stream) { |
| 193 | ObjectNode root = mapper().createObjectNode(); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 194 | ControlMetric cm; |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 195 | try { |
| 196 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 197 | ArrayNode networkRes = (ArrayNode) jsonTree.get("networks"); |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 198 | for (JsonNode node : networkRes) { |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 199 | JsonNode resourceName = node.get("resourceName"); |
| 200 | nullIsIllegal(resourceName, INVALID_RESOURCE_NAME); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 201 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 202 | long inBytes = nullIsIllegal(node.get("incomingBytes").asLong(), INVALID_REQUEST); |
| 203 | long outBytes = nullIsIllegal(node.get("outgoingBytes").asLong(), INVALID_REQUEST); |
| 204 | long inPackets = nullIsIllegal(node.get("incomingPackets").asLong(), INVALID_REQUEST); |
| 205 | long outPackets = nullIsIllegal(node.get("outgoingPackets").asLong(), INVALID_REQUEST); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 206 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 207 | cm = new ControlMetric(ControlMetricType.NW_INCOMING_BYTES, |
| 208 | new MetricValue.Builder().load(inBytes).add()); |
| 209 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 210 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 211 | cm = new ControlMetric(ControlMetricType.NW_OUTGOING_BYTES, |
| 212 | new MetricValue.Builder().load(outBytes).add()); |
| 213 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 214 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 215 | cm = new ControlMetric(ControlMetricType.NW_INCOMING_PACKETS, |
| 216 | new MetricValue.Builder().load(inPackets).add()); |
| 217 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 218 | |
Jian Li | 1fdd224 | 2016-02-05 10:01:19 -0800 | [diff] [blame^] | 219 | cm = new ControlMetric(ControlMetricType.NW_OUTGOING_PACKETS, |
| 220 | new MetricValue.Builder().load(outPackets).add()); |
| 221 | service.updateMetric(cm, UPDATE_INTERVAL_IN_MINUTE, resourceName.asText()); |
| 222 | } |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 223 | } catch (IOException e) { |
| 224 | throw new IllegalArgumentException(e.getMessage()); |
| 225 | } |
| 226 | return ok(root).build(); |
| 227 | } |
| 228 | |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 229 | /** |
| 230 | * Collects system specifications. |
| 231 | * The system specs include the various control metrics |
| 232 | * which do not require aggregation. |
| 233 | * |
| 234 | * @param stream JSON stream |
| 235 | * @return 200 OK |
| 236 | * @onos.rsModel SystemSpecsPost |
| 237 | */ |
| 238 | @POST |
Jian Li | 54df73e | 2016-02-01 17:09:03 -0800 | [diff] [blame] | 239 | @Path("system_specs") |
Jian Li | c132c11 | 2016-01-28 20:27:34 -0800 | [diff] [blame] | 240 | @Consumes(MediaType.APPLICATION_JSON) |
| 241 | @Produces(MediaType.APPLICATION_JSON) |
| 242 | public Response systemSpecs(InputStream stream) { |
| 243 | ObjectNode root = mapper().createObjectNode(); |
| 244 | |
| 245 | try { |
| 246 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
| 247 | JsonNode numOfCores = jsonTree.get("numOfCores"); |
| 248 | JsonNode numOfCpus = jsonTree.get("numOfCpus"); |
| 249 | JsonNode cpuSpeed = jsonTree.get("cpuSpeed"); |
| 250 | JsonNode totalMemory = jsonTree.get("totalMemory"); |
| 251 | |
| 252 | if (numOfCores != null && numOfCpus != null && cpuSpeed != null && totalMemory != null) { |
| 253 | ControlMetricsSystemSpec.Builder builder = new ControlMetricsSystemSpec.Builder(); |
| 254 | ControlMetricsSystemSpec cmss = builder.numOfCores(numOfCores.asInt()) |
| 255 | .numOfCpus(numOfCpus.asInt()) |
| 256 | .cpuSpeed(cpuSpeed.asInt()) |
| 257 | .totalMemory(totalMemory.asLong()) |
| 258 | .build(); |
| 259 | // TODO: need to implement spec store |
| 260 | |
| 261 | } else { |
| 262 | throw new IllegalArgumentException(INVALID_SYSTEM_SPECS); |
| 263 | } |
| 264 | |
| 265 | } catch (IOException e) { |
| 266 | throw new IllegalArgumentException(e.getMessage()); |
| 267 | } |
| 268 | return ok(root).build(); |
| 269 | } |
Jian Li | ba6b117 | 2016-02-01 22:40:42 -0800 | [diff] [blame] | 270 | } |