blob: 5e985b03873781d77b3d5593c4e46673671ddfb7 [file] [log] [blame]
Jian Li80c12702016-02-20 08:58:19 +09001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Jian Li80c12702016-02-20 08:58:19 +09003 *
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 */
16package org.onosproject.cpman.rest;
17
18import com.fasterxml.jackson.databind.node.ArrayNode;
19import com.fasterxml.jackson.databind.node.ObjectNode;
Jian Li8b0ea962016-04-04 11:49:29 -070020import org.apache.commons.lang3.StringUtils;
Jian Li67e1e152016-04-18 17:52:58 -070021import org.onlab.util.Tools;
Jian Li80c12702016-02-20 08:58:19 +090022import org.onosproject.cluster.ClusterService;
23import org.onosproject.cluster.NodeId;
Jian Li67e1e152016-04-18 17:52:58 -070024import org.onosproject.cpman.ControlLoadSnapshot;
Jian Li80c12702016-02-20 08:58:19 +090025import org.onosproject.cpman.ControlMetricType;
26import org.onosproject.cpman.ControlPlaneMonitorService;
27import org.onosproject.net.DeviceId;
28import org.onosproject.rest.AbstractWebResource;
29
30import javax.ws.rs.GET;
31import javax.ws.rs.Path;
32import javax.ws.rs.PathParam;
33import javax.ws.rs.Produces;
34import javax.ws.rs.core.MediaType;
35import javax.ws.rs.core.Response;
36import java.util.Optional;
37import java.util.Set;
Jian Li67e1e152016-04-18 17:52:58 -070038import java.util.concurrent.CompletableFuture;
39import java.util.concurrent.TimeUnit;
Jian Li80c12702016-02-20 08:58:19 +090040
41import static org.onosproject.cpman.ControlResource.CONTROL_MESSAGE_METRICS;
42import static org.onosproject.cpman.ControlResource.CPU_METRICS;
43import static org.onosproject.cpman.ControlResource.DISK_METRICS;
44import static org.onosproject.cpman.ControlResource.MEMORY_METRICS;
45import static org.onosproject.cpman.ControlResource.NETWORK_METRICS;
46import static org.onosproject.cpman.ControlResource.Type.CONTROL_MESSAGE;
47import static org.onosproject.cpman.ControlResource.Type.DISK;
48import static org.onosproject.cpman.ControlResource.Type.NETWORK;
49
50/**
51 * Query control metrics.
52 */
Jian Lie277ebe2016-04-07 11:41:51 -070053@Path("controlmetrics")
Jian Li80c12702016-02-20 08:58:19 +090054public class ControlMetricsWebResource extends AbstractWebResource {
55
56 private final ControlPlaneMonitorService monitorService =
57 get(ControlPlaneMonitorService.class);
58 private final ClusterService clusterService = get(ClusterService.class);
59 private final NodeId localNodeId = clusterService.getLocalNode().id();
60 private final ObjectNode root = mapper().createObjectNode();
Jian Li67e1e152016-04-18 17:52:58 -070061 private static final long TIMEOUT_MILLIS = 1000;
Jian Li80c12702016-02-20 08:58:19 +090062
63 /**
64 * Returns control message metrics of all devices.
65 *
66 * @return array of all control message metrics
Jian Lid86fac32016-04-01 16:10:26 -070067 * @onos.rsModel ControlMessageMetrics
Jian Li80c12702016-02-20 08:58:19 +090068 */
69 @GET
70 @Path("messages")
71 @Produces(MediaType.APPLICATION_JSON)
72 public Response controlMessageMetrics() {
73
74 ArrayNode deviceNodes = root.putArray("devices");
75 monitorService.availableResources(CONTROL_MESSAGE).forEach(name -> {
76 ObjectNode deviceNode = mapper().createObjectNode();
77 ObjectNode valueNode = mapper().createObjectNode();
78
79 metricsStats(monitorService, localNodeId, CONTROL_MESSAGE_METRICS,
80 DeviceId.deviceId(name), valueNode);
81 deviceNode.put("name", name);
82 deviceNode.set("value", valueNode);
83
84 deviceNodes.add(deviceNode);
85 });
86
87 return ok(root).build();
88 }
89
90 /**
91 * Returns control message metrics of a given device.
92 *
93 * @param deviceId device identification
94 * @return control message metrics of a given device
Jian Lid86fac32016-04-01 16:10:26 -070095 * @onos.rsModel ControlMessageMetric
Jian Li80c12702016-02-20 08:58:19 +090096 */
97 @GET
98 @Produces(MediaType.APPLICATION_JSON)
99 @Path("messages/{deviceId}")
100 public Response controlMessageMetrics(@PathParam("deviceId") String deviceId) {
101
102 metricsStats(monitorService, localNodeId, CONTROL_MESSAGE_METRICS,
103 DeviceId.deviceId(deviceId), root);
104
105 return ok(root).build();
106 }
107
108 /**
109 * Returns cpu metrics.
110 *
111 * @return cpu metrics
Jian Lid86fac32016-04-01 16:10:26 -0700112 * @onos.rsModel CpuMetrics
Jian Li80c12702016-02-20 08:58:19 +0900113 */
114 @GET
115 @Path("cpu_metrics")
116 @Produces(MediaType.APPLICATION_JSON)
117 public Response cpuMetrics() {
118
119 metricsStats(monitorService, localNodeId, CPU_METRICS, root);
120 return ok(root).build();
121 }
122
123 /**
124 * Returns memory metrics.
125 *
126 * @return memory metrics
Jian Lid86fac32016-04-01 16:10:26 -0700127 * @onos.rsModel MemoryMetrics
Jian Li80c12702016-02-20 08:58:19 +0900128 */
129 @GET
130 @Path("memory_metrics")
131 @Produces(MediaType.APPLICATION_JSON)
132 public Response memoryMetrics() {
133
134 metricsStats(monitorService, localNodeId, MEMORY_METRICS, root);
135 return ok(root).build();
136 }
137
138 /**
139 * Returns disk metrics of all resources.
140 *
141 * @return disk metrics of all resources
Jian Lid86fac32016-04-01 16:10:26 -0700142 * @onos.rsModel DiskMetrics
Jian Li80c12702016-02-20 08:58:19 +0900143 */
144 @GET
145 @Path("disk_metrics")
146 @Produces(MediaType.APPLICATION_JSON)
147 public Response diskMetrics() {
148
149 ArrayNode diskNodes = root.putArray("disks");
150 monitorService.availableResources(DISK).forEach(name -> {
151 ObjectNode diskNode = mapper().createObjectNode();
152 ObjectNode valueNode = mapper().createObjectNode();
153
154 metricsStats(monitorService, localNodeId, DISK_METRICS, name, valueNode);
155 diskNode.put("name", name);
156 diskNode.set("value", valueNode);
157
158 diskNodes.add(diskNode);
159 });
160
161 return ok(root).build();
162 }
163
164 /**
165 * Returns network metrics of all resources.
166 *
167 * @return network metrics of all resources
Jian Lid86fac32016-04-01 16:10:26 -0700168 * @onos.rsModel NetworkMetrics
Jian Li80c12702016-02-20 08:58:19 +0900169 */
170 @GET
171 @Path("network_metrics")
172 @Produces(MediaType.APPLICATION_JSON)
173 public Response networkMetrics() {
174
175 ArrayNode networkNodes = root.putArray("networks");
176 monitorService.availableResources(NETWORK).forEach(name -> {
177 ObjectNode networkNode = mapper().createObjectNode();
178 ObjectNode valueNode = mapper().createObjectNode();
179
180 metricsStats(monitorService, localNodeId, NETWORK_METRICS, name, valueNode);
181 networkNode.put("name", name);
182 networkNode.set("value", valueNode);
183
184 networkNodes.add(networkNode);
185 });
186
187 return ok(root).build();
188 }
189
190 /**
191 * Returns a collection of control message stats.
192 *
193 * @param service control plane monitoring service
194 * @param nodeId node identification
195 * @param typeSet a set of control message types
196 * @param did device identification
197 * @param node object node
198 * @return a collection of control message stats
199 */
200 private ArrayNode metricsStats(ControlPlaneMonitorService service,
201 NodeId nodeId, Set<ControlMetricType> typeSet,
202 DeviceId did, ObjectNode node) {
203 return metricsStats(service, nodeId, typeSet, null, did, node);
204 }
205
206 /**
207 * Returns a collection of system metric stats.
208 *
209 * @param service control plane monitoring service
210 * @param nodeId node identification
211 * @param typeSet a set of system metric types
212 * @param node object node
213 * @return a collection of system metric stats
214 */
215 private ArrayNode metricsStats(ControlPlaneMonitorService service,
216 NodeId nodeId, Set<ControlMetricType> typeSet,
217 ObjectNode node) {
218 return metricsStats(service, nodeId, typeSet, null, null, node);
219 }
220
221 /**
222 * Returns a collection of system metric stats.
223 *
224 * @param service control plane monitoring service
225 * @param nodeId node identification
226 * @param typeSet a set of control message types
227 * @param resourceName device identification
228 * @param node object node
229 * @return a collection of system metric stats
230 */
231 private ArrayNode metricsStats(ControlPlaneMonitorService service,
232 NodeId nodeId, Set<ControlMetricType> typeSet,
233 String resourceName, ObjectNode node) {
234 return metricsStats(service, nodeId, typeSet, resourceName, null, node);
235 }
236
237 /**
238 * Returns a collection of control loads of the given control metric types.
239 *
240 * @param service control plane monitoring service
241 * @param nodeId node identification
242 * @param typeSet a group of control metric types
243 * @param name resource name
244 * @param did device identification
245 * @return a collection of control loads
246 */
247 private ArrayNode metricsStats(ControlPlaneMonitorService service,
248 NodeId nodeId, Set<ControlMetricType> typeSet,
249 String name, DeviceId did, ObjectNode node) {
250 ArrayNode metricsNode = node.putArray("metrics");
251
252 if (name == null && did == null) {
253 typeSet.forEach(type -> {
254 ObjectNode metricNode = mapper().createObjectNode();
Jian Li67e1e152016-04-18 17:52:58 -0700255 CompletableFuture<ControlLoadSnapshot> cf =
256 service.getLoad(nodeId, type, Optional.empty());
257
258 if (cf != null) {
259 ControlLoadSnapshot cmr =
260 Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
261
262 if (cmr != null) {
263 metricNode.set(toCamelCase(type.toString(), true),
264 codec(ControlLoadSnapshot.class).encode(cmr, this));
265 metricsNode.add(metricNode);
266 }
Jian Li80c12702016-02-20 08:58:19 +0900267 }
268 });
269 } else if (name == null) {
270 typeSet.forEach(type -> {
271 ObjectNode metricNode = mapper().createObjectNode();
Jian Li67e1e152016-04-18 17:52:58 -0700272 CompletableFuture<ControlLoadSnapshot> cf =
273 service.getLoad(nodeId, type, Optional.of(did));
274
275 if (cf != null) {
276 ControlLoadSnapshot cmr =
277 Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
278 if (cmr != null) {
279 metricNode.set(toCamelCase(type.toString(), true),
280 codec(ControlLoadSnapshot.class).encode(cmr, this));
281 metricsNode.add(metricNode);
282 }
Jian Li80c12702016-02-20 08:58:19 +0900283 }
Jian Li67e1e152016-04-18 17:52:58 -0700284
Jian Li80c12702016-02-20 08:58:19 +0900285 });
286 } else if (did == null) {
287 typeSet.forEach(type -> {
288 ObjectNode metricNode = mapper().createObjectNode();
Jian Li67e1e152016-04-18 17:52:58 -0700289 CompletableFuture<ControlLoadSnapshot> cf =
290 service.getLoad(nodeId, type, name);
291
292 if (cf != null) {
293 ControlLoadSnapshot cmr =
294 Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
295 if (cmr != null) {
296 metricNode.set(toCamelCase(type.toString(), true),
297 codec(ControlLoadSnapshot.class).encode(cmr, this));
298 metricsNode.add(metricNode);
299 }
Jian Li80c12702016-02-20 08:58:19 +0900300 }
301 });
302 }
303
304 return metricsNode;
305 }
Jian Li8b0ea962016-04-04 11:49:29 -0700306
307 private String toCamelCase(String value, boolean startWithLowerCase) {
308 String[] strings = StringUtils.split(value.toLowerCase(), "_");
309 for (int i = startWithLowerCase ? 1 : 0; i < strings.length; i++) {
310 strings[i] = StringUtils.capitalize(strings[i]);
311 }
312 return StringUtils.join(strings);
313 }
Jian Li80c12702016-02-20 08:58:19 +0900314}