Jian Li
Committed by Gerrit Code Review

Add a set of synchronous method for control plane monitor service

Change-Id: Ib060282dfe9a302a6cf88b9679555f4a2e8127a2
...@@ -73,6 +73,26 @@ public interface ControlPlaneMonitorService { ...@@ -73,6 +73,26 @@ public interface ControlPlaneMonitorService {
73 Optional<DeviceId> deviceId); 73 Optional<DeviceId> deviceId);
74 74
75 /** 75 /**
76 + * Synchronous version of getLoad.
77 + * Obtains snapshot of control plane load of a specific device.
78 + * The metrics range from control messages and system metrics
79 + * (e.g., CPU and memory info).
80 + * If the device id is not specified, it returns system metrics, otherwise,
81 + * it returns control message stats of the given device.
82 + *
83 + * @param nodeId node identifier
84 + * @param type control metric type
85 + * @param deviceId device identifier
86 + * @return control load snapshot
87 + */
88 + default ControlLoadSnapshot getLoadSync(NodeId nodeId,
89 + ControlMetricType type,
90 + Optional<DeviceId> deviceId) {
91 + return Tools.futureGetOrElse(getLoad(nodeId, type, deviceId),
92 + TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
93 + }
94 +
95 + /**
76 * Obtains snapshot of control plane load of a specific resource. 96 * Obtains snapshot of control plane load of a specific resource.
77 * The metrics include I/O device metrics (e.g., disk and network metrics). 97 * The metrics include I/O device metrics (e.g., disk and network metrics).
78 * 98 *
...@@ -86,6 +106,23 @@ public interface ControlPlaneMonitorService { ...@@ -86,6 +106,23 @@ public interface ControlPlaneMonitorService {
86 String resourceName); 106 String resourceName);
87 107
88 /** 108 /**
109 + * Synchronous version of getLoad.
110 + * Obtains snapshot of control plane load of a specific resource.
111 + * The metrics include I/O device metrics (e.g., disk and network metrics).
112 + *
113 + * @param nodeId node identifier
114 + * @param type control metric type
115 + * @param resourceName resource name
116 + * @return control load snapshot
117 + */
118 + default ControlLoadSnapshot getLoadSync(NodeId nodeId,
119 + ControlMetricType type,
120 + String resourceName) {
121 + return Tools.futureGetOrElse(getLoad(nodeId, type, resourceName),
122 + TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
123 + }
124 +
125 + /**
89 * Obtains snapshot of control plane load of a specific device with the 126 * Obtains snapshot of control plane load of a specific device with the
90 * projected range. 127 * projected range.
91 * 128 *
...@@ -102,6 +139,26 @@ public interface ControlPlaneMonitorService { ...@@ -102,6 +139,26 @@ public interface ControlPlaneMonitorService {
102 Optional<DeviceId> deviceId); 139 Optional<DeviceId> deviceId);
103 140
104 /** 141 /**
142 + * Synchronous version of getLoad.
143 + * Obtains snapshot of control plane load of a specific device with the
144 + * projected range.
145 + *
146 + * @param nodeId node identifier
147 + * @param type control metric type
148 + * @param duration projected duration
149 + * @param unit projected time unit
150 + * @param deviceId device identifier
151 + * @return control load snapshot
152 + */
153 + default ControlLoadSnapshot getLoadSync(NodeId nodeId,
154 + ControlMetricType type,
155 + int duration, TimeUnit unit,
156 + Optional<DeviceId> deviceId) {
157 + return Tools.futureGetOrElse(getLoad(nodeId, type, duration, unit, deviceId),
158 + TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
159 + }
160 +
161 + /**
105 * Obtains snapshot of control plane load of a specific resource with the 162 * Obtains snapshot of control plane load of a specific resource with the
106 * projected range. 163 * projected range.
107 * 164 *
...@@ -118,6 +175,26 @@ public interface ControlPlaneMonitorService { ...@@ -118,6 +175,26 @@ public interface ControlPlaneMonitorService {
118 String resourceName); 175 String resourceName);
119 176
120 /** 177 /**
178 + * Synchronous version of getLoad.
179 + * Obtains snapshot of control plane load of a specific resource with the
180 + * projected range.
181 + *
182 + * @param nodeId node identifier
183 + * @param type control metric type
184 + * @param duration projected duration
185 + * @param unit projected time unit
186 + * @param resourceName resource name
187 + * @return control load snapshot
188 + */
189 + default ControlLoadSnapshot getLoadSync(NodeId nodeId,
190 + ControlMetricType type,
191 + int duration, TimeUnit unit,
192 + String resourceName) {
193 + return Tools.futureGetOrElse(getLoad(nodeId, type, duration, unit, resourceName),
194 + TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
195 + }
196 +
197 + /**
121 * Obtains a list of names of available resources. 198 * Obtains a list of names of available resources.
122 * 199 *
123 * @param nodeId node identifier 200 * @param nodeId node identifier
......
...@@ -17,7 +17,6 @@ package org.onosproject.cpman.cli; ...@@ -17,7 +17,6 @@ package org.onosproject.cpman.cli;
17 17
18 import org.apache.karaf.shell.commands.Argument; 18 import org.apache.karaf.shell.commands.Argument;
19 import org.apache.karaf.shell.commands.Command; 19 import org.apache.karaf.shell.commands.Command;
20 -import org.onlab.util.Tools;
21 import org.onosproject.cli.AbstractShellCommand; 20 import org.onosproject.cli.AbstractShellCommand;
22 import org.onosproject.cluster.NodeId; 21 import org.onosproject.cluster.NodeId;
23 import org.onosproject.cpman.ControlLoadSnapshot; 22 import org.onosproject.cpman.ControlLoadSnapshot;
...@@ -27,8 +26,6 @@ import org.onosproject.net.DeviceId; ...@@ -27,8 +26,6 @@ import org.onosproject.net.DeviceId;
27 26
28 import java.util.Optional; 27 import java.util.Optional;
29 import java.util.Set; 28 import java.util.Set;
30 -import java.util.concurrent.CompletableFuture;
31 -import java.util.concurrent.TimeUnit;
32 29
33 import static org.onosproject.cpman.ControlResource.CONTROL_MESSAGE_METRICS; 30 import static org.onosproject.cpman.ControlResource.CONTROL_MESSAGE_METRICS;
34 import static org.onosproject.cpman.ControlResource.CPU_METRICS; 31 import static org.onosproject.cpman.ControlResource.CPU_METRICS;
...@@ -47,8 +44,6 @@ public class ControlMetricsStatsListCommand extends AbstractShellCommand { ...@@ -47,8 +44,6 @@ public class ControlMetricsStatsListCommand extends AbstractShellCommand {
47 "averageValue=%d, latestTime=%s"; 44 "averageValue=%d, latestTime=%s";
48 private static final String INVALID_TYPE = "Invalid control resource type."; 45 private static final String INVALID_TYPE = "Invalid control resource type.";
49 46
50 - private static final long TIMEOUT_MILLIS = 3000;
51 -
52 @Argument(index = 0, name = "node", description = "ONOS node identifier", 47 @Argument(index = 0, name = "node", description = "ONOS node identifier",
53 required = true, multiValued = false) 48 required = true, multiValued = false)
54 String node = null; 49 String node = null;
...@@ -91,51 +86,80 @@ public class ControlMetricsStatsListCommand extends AbstractShellCommand { ...@@ -91,51 +86,80 @@ public class ControlMetricsStatsListCommand extends AbstractShellCommand {
91 } 86 }
92 } 87 }
93 88
89 + /**
90 + * Prints system metric statistic information.
91 + *
92 + * @param service monitor service
93 + * @param nodeId node identifier
94 + * @param typeSet control metric type
95 + */
94 private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId, 96 private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
95 Set<ControlMetricType> typeSet) { 97 Set<ControlMetricType> typeSet) {
96 printMetricsStats(service, nodeId, typeSet, null, null); 98 printMetricsStats(service, nodeId, typeSet, null, null);
97 } 99 }
98 100
101 + /**
102 + * Prints disk and network metric statistic information.
103 + *
104 + * @param service monitor service
105 + * @param nodeId node identifier
106 + * @param typeSet control metric type
107 + * @param resName resource name
108 + */
99 private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId, 109 private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
100 Set<ControlMetricType> typeSet, String resName) { 110 Set<ControlMetricType> typeSet, String resName) {
101 printMetricsStats(service, nodeId, typeSet, resName, null); 111 printMetricsStats(service, nodeId, typeSet, resName, null);
102 } 112 }
103 113
114 + /**
115 + * Prints control message metric statistic information.
116 + *
117 + * @param service monitor service
118 + * @param nodeId node identifier
119 + * @param typeSet control metric type
120 + * @param did device identifier
121 + */
104 private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId, 122 private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
105 Set<ControlMetricType> typeSet, DeviceId did) { 123 Set<ControlMetricType> typeSet, DeviceId did) {
106 printMetricsStats(service, nodeId, typeSet, null, did); 124 printMetricsStats(service, nodeId, typeSet, null, did);
107 } 125 }
108 126
127 + /**
128 + * Prints control plane metric statistic information.
129 + *
130 + * @param service monitor service
131 + * @param nodeId node identifier
132 + * @param typeSet control metric type
133 + * @param resName resource name
134 + * @param did device identifier
135 + */
109 private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId, 136 private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
110 Set<ControlMetricType> typeSet, String resName, DeviceId did) { 137 Set<ControlMetricType> typeSet, String resName, DeviceId did) {
111 if (resName == null && did == null) { 138 if (resName == null && did == null) {
112 typeSet.forEach(s -> { 139 typeSet.forEach(s -> {
113 - CompletableFuture<ControlLoadSnapshot> cf = 140 + ControlLoadSnapshot cls = service.getLoadSync(nodeId, s, Optional.empty());
114 - service.getLoad(nodeId, s, Optional.empty()); 141 + printControlLoadSnapshot(s, cls);
115 - ControlLoadSnapshot cmr =
116 - Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
117 - printRemote(s, cmr);
118 }); 142 });
119 - } else if (resName == null && did != null) { 143 + } else if (resName == null) {
120 typeSet.forEach(s -> { 144 typeSet.forEach(s -> {
121 - CompletableFuture<ControlLoadSnapshot> cf = 145 + ControlLoadSnapshot cls = service.getLoadSync(nodeId, s, Optional.of(did));
122 - service.getLoad(nodeId, s, Optional.of(did)); 146 + printControlLoadSnapshot(s, cls);
123 - ControlLoadSnapshot cmr =
124 - Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
125 - printRemote(s, cmr);
126 }); 147 });
127 - } else if (resName != null && did == null) { 148 + } else if (did == null) {
128 typeSet.forEach(s -> { 149 typeSet.forEach(s -> {
129 - CompletableFuture<ControlLoadSnapshot> cf = 150 + ControlLoadSnapshot cls = service.getLoadSync(nodeId, s, resName);
130 - service.getLoad(nodeId, s, resName); 151 + printControlLoadSnapshot(s, cls);
131 - ControlLoadSnapshot cmr =
132 - Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
133 - printRemote(s, cmr);
134 }); 152 });
135 } 153 }
136 } 154 }
137 155
138 - private void printRemote(ControlMetricType cmType, ControlLoadSnapshot cls) { 156 + /**
157 + * Prints control load snapshot.
158 + *
159 + * @param cmType control metric type
160 + * @param cls control load snapshot
161 + */
162 + private void printControlLoadSnapshot(ControlMetricType cmType, ControlLoadSnapshot cls) {
139 if (cls != null) { 163 if (cls != null) {
140 print(FMT, cmType.toString(), cls.latest(), cls.average(), cls.time()); 164 print(FMT, cmType.toString(), cls.latest(), cls.average(), cls.time());
141 } else { 165 } else {
......
...@@ -149,21 +149,15 @@ public class CpmanViewMessageHandler extends UiMessageHandler { ...@@ -149,21 +149,15 @@ public class CpmanViewMessageHandler extends UiMessageHandler {
149 ClusterService cs, DeviceId deviceId) { 149 ClusterService cs, DeviceId deviceId) {
150 Map<ControlMetricType, Long[]> data = Maps.newHashMap(); 150 Map<ControlMetricType, Long[]> data = Maps.newHashMap();
151 for (ControlMetricType cmt : CONTROL_MESSAGE_METRICS) { 151 for (ControlMetricType cmt : CONTROL_MESSAGE_METRICS) {
152 - ControlLoadSnapshot cls; 152 + ControlLoadSnapshot cls = cpms.getLoadSync(cs.getLocalNode().id(),
153 - try { 153 + cmt, NUM_OF_DATA_POINTS, TimeUnit.MINUTES, Optional.of(deviceId));
154 - cls = cpms.getLoad(cs.getLocalNode().id(),
155 - cmt, NUM_OF_DATA_POINTS, TimeUnit.MINUTES,
156 - Optional.of(deviceId)).get();
157 154
158 - // TODO: in some cases, the number of returned dataset is 155 + // TODO: in some cases, the number of returned data set is
159 // less than what we expected (expected -1) 156 // less than what we expected (expected -1)
160 // As a workaround, we simply fill the slot with 0 values, 157 // As a workaround, we simply fill the slot with 0 values,
161 // such a bug should be fixed with updated RRD4J lib... 158 // such a bug should be fixed with updated RRD4J lib...
162 data.put(cmt, ArrayUtils.toObject(fillData(cls.recent(), NUM_OF_DATA_POINTS))); 159 data.put(cmt, ArrayUtils.toObject(fillData(cls.recent(), NUM_OF_DATA_POINTS)));
163 timestamp = cls.time(); 160 timestamp = cls.time();
164 - } catch (InterruptedException | ExecutionException e) {
165 - log.warn(e.getMessage());
166 - }
167 } 161 }
168 return data; 162 return data;
169 } 163 }
......
...@@ -18,7 +18,6 @@ package org.onosproject.cpman.rest; ...@@ -18,7 +18,6 @@ package org.onosproject.cpman.rest;
18 import com.fasterxml.jackson.databind.node.ArrayNode; 18 import com.fasterxml.jackson.databind.node.ArrayNode;
19 import com.fasterxml.jackson.databind.node.ObjectNode; 19 import com.fasterxml.jackson.databind.node.ObjectNode;
20 import org.apache.commons.lang3.StringUtils; 20 import org.apache.commons.lang3.StringUtils;
21 -import org.onlab.util.Tools;
22 import org.onosproject.cluster.ClusterService; 21 import org.onosproject.cluster.ClusterService;
23 import org.onosproject.cluster.NodeId; 22 import org.onosproject.cluster.NodeId;
24 import org.onosproject.cpman.ControlLoadSnapshot; 23 import org.onosproject.cpman.ControlLoadSnapshot;
...@@ -35,8 +34,6 @@ import javax.ws.rs.core.MediaType; ...@@ -35,8 +34,6 @@ import javax.ws.rs.core.MediaType;
35 import javax.ws.rs.core.Response; 34 import javax.ws.rs.core.Response;
36 import java.util.Optional; 35 import java.util.Optional;
37 import java.util.Set; 36 import java.util.Set;
38 -import java.util.concurrent.CompletableFuture;
39 -import java.util.concurrent.TimeUnit;
40 37
41 import static org.onosproject.cpman.ControlResource.CONTROL_MESSAGE_METRICS; 38 import static org.onosproject.cpman.ControlResource.CONTROL_MESSAGE_METRICS;
42 import static org.onosproject.cpman.ControlResource.CPU_METRICS; 39 import static org.onosproject.cpman.ControlResource.CPU_METRICS;
...@@ -58,7 +55,6 @@ public class ControlMetricsWebResource extends AbstractWebResource { ...@@ -58,7 +55,6 @@ public class ControlMetricsWebResource extends AbstractWebResource {
58 private final ClusterService clusterService = get(ClusterService.class); 55 private final ClusterService clusterService = get(ClusterService.class);
59 private final NodeId localNodeId = clusterService.getLocalNode().id(); 56 private final NodeId localNodeId = clusterService.getLocalNode().id();
60 private final ObjectNode root = mapper().createObjectNode(); 57 private final ObjectNode root = mapper().createObjectNode();
61 - private static final long TIMEOUT_MILLIS = 1000;
62 58
63 /** 59 /**
64 * Returns control message metrics of all devices. 60 * Returns control message metrics of all devices.
...@@ -251,59 +247,32 @@ public class ControlMetricsWebResource extends AbstractWebResource { ...@@ -251,59 +247,32 @@ public class ControlMetricsWebResource extends AbstractWebResource {
251 247
252 if (name == null && did == null) { 248 if (name == null && did == null) {
253 typeSet.forEach(type -> { 249 typeSet.forEach(type -> {
254 - ObjectNode metricNode = mapper().createObjectNode(); 250 + ControlLoadSnapshot cls = service.getLoadSync(nodeId, type, Optional.empty());
255 - CompletableFuture<ControlLoadSnapshot> cf = 251 + processRest(cls, type, metricsNode);
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 - }
267 - }
268 }); 252 });
269 } else if (name == null) { 253 } else if (name == null) {
270 typeSet.forEach(type -> { 254 typeSet.forEach(type -> {
271 - ObjectNode metricNode = mapper().createObjectNode(); 255 + ControlLoadSnapshot cls = service.getLoadSync(nodeId, type, Optional.of(did));
272 - CompletableFuture<ControlLoadSnapshot> cf = 256 + processRest(cls, type, metricsNode);
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 - }
283 - }
284 -
285 }); 257 });
286 } else if (did == null) { 258 } else if (did == null) {
287 typeSet.forEach(type -> { 259 typeSet.forEach(type -> {
288 - ObjectNode metricNode = mapper().createObjectNode(); 260 + ControlLoadSnapshot cls = service.getLoadSync(nodeId, type, name);
289 - CompletableFuture<ControlLoadSnapshot> cf = 261 + processRest(cls, type, metricsNode);
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 - }
300 - }
301 }); 262 });
302 } 263 }
303 264
304 return metricsNode; 265 return metricsNode;
305 } 266 }
306 267
268 + /**
269 + * Camelizes the input string.
270 + *
271 + * @param value original string
272 + * @param startWithLowerCase flag that determines whether to use lower case
273 + * for the camelized string
274 + * @return camelized string
275 + */
307 private String toCamelCase(String value, boolean startWithLowerCase) { 276 private String toCamelCase(String value, boolean startWithLowerCase) {
308 String[] strings = StringUtils.split(value.toLowerCase(), "_"); 277 String[] strings = StringUtils.split(value.toLowerCase(), "_");
309 for (int i = startWithLowerCase ? 1 : 0; i < strings.length; i++) { 278 for (int i = startWithLowerCase ? 1 : 0; i < strings.length; i++) {
...@@ -311,4 +280,21 @@ public class ControlMetricsWebResource extends AbstractWebResource { ...@@ -311,4 +280,21 @@ public class ControlMetricsWebResource extends AbstractWebResource {
311 } 280 }
312 return StringUtils.join(strings); 281 return StringUtils.join(strings);
313 } 282 }
283 +
284 + /**
285 + * Transforms control load snapshot object into JSON object.
286 + *
287 + * @param cls control load snapshot
288 + * @param type control metric type
289 + * @param metricsNode array of JSON node
290 + */
291 + private void processRest(ControlLoadSnapshot cls, ControlMetricType type, ArrayNode metricsNode) {
292 + ObjectNode metricNode = mapper().createObjectNode();
293 +
294 + if (cls != null) {
295 + metricNode.set(toCamelCase(type.toString(), true),
296 + codec(ControlLoadSnapshot.class).encode(cls, this));
297 + metricsNode.add(metricNode);
298 + }
299 + }
314 } 300 }
......
...@@ -183,7 +183,7 @@ public class ControlMetricsResourceTest extends ResourceTest { ...@@ -183,7 +183,7 @@ public class ControlMetricsResourceTest extends ResourceTest {
183 public void testResourcePopulatedArray() { 183 public void testResourcePopulatedArray() {
184 expect(mockControlPlaneMonitorService.availableResourcesSync(anyObject(), anyObject())) 184 expect(mockControlPlaneMonitorService.availableResourcesSync(anyObject(), anyObject()))
185 .andReturn(resourceSet).once(); 185 .andReturn(resourceSet).once();
186 - expect(mockControlPlaneMonitorService.getLoad(anyObject(), anyObject(), 186 + expect(mockControlPlaneMonitorService.getLoadSync(anyObject(), anyObject(),
187 anyString())).andReturn(null).times(4); 187 anyString())).andReturn(null).times(4);
188 replay(mockControlPlaneMonitorService); 188 replay(mockControlPlaneMonitorService);
189 189
......