Jian Li
Committed by Gerrit Code Review

Implement updateMetric and getLoad methods of ControlPlaneMonitor

- Add rrd4j jar, and wrap it as a bundle for karaf
- Implement updateMetric and getLoad methods
- Add unit test for two methods
- Revise the DefaultMetricDatabase to make it generate unique in
  memory storage space
- Revise the ControlPlaneMonitor interface
- Rename percentage to ratio, due to long string unsupport
  issue in RRD

Change-Id: Ia9d56f8e4f4bcd7ef7a29732668caa9c6a885ecf
...@@ -28,11 +28,11 @@ public class ControlMetric { ...@@ -28,11 +28,11 @@ public class ControlMetric {
28 this.metricValue = metricValue; 28 this.metricValue = metricValue;
29 } 29 }
30 30
31 - ControlMetricType metricType() { 31 + public ControlMetricType metricType() {
32 return metricType; 32 return metricType;
33 } 33 }
34 34
35 - MetricValue metricValue() { 35 + public MetricValue metricValue() {
36 return metricValue; 36 return metricValue;
37 } 37 }
38 } 38 }
......
...@@ -62,11 +62,11 @@ public enum ControlMetricType { ...@@ -62,11 +62,11 @@ public enum ControlMetricType {
62 /* CPU Idle Time. **/ 62 /* CPU Idle Time. **/
63 CPU_IDLE_TIME, 63 CPU_IDLE_TIME,
64 64
65 - /* Percentage of Used Memory Amount. */ 65 + /* Ratio of Used Memory Amount. */
66 - MEMORY_USED_PERCENTAGE, 66 + MEMORY_USED_RATIO,
67 67
68 - /* Percentage of Free Memory Amount. **/ 68 + /* Ratio of Free Memory Amount. **/
69 - MEMORY_FREE_PERCENTAGE, 69 + MEMORY_FREE_RATIO,
70 70
71 /* Used Memory Amount. **/ 71 /* Used Memory Amount. **/
72 MEMORY_USED, 72 MEMORY_USED,
......
...@@ -19,7 +19,6 @@ import org.onosproject.cluster.NodeId; ...@@ -19,7 +19,6 @@ import org.onosproject.cluster.NodeId;
19 import org.onosproject.net.DeviceId; 19 import org.onosproject.net.DeviceId;
20 20
21 import java.util.Optional; 21 import java.util.Optional;
22 -import java.util.concurrent.TimeUnit;
23 22
24 /** 23 /**
25 * Control Plane Statistics Service Interface. 24 * Control Plane Statistics Service Interface.
...@@ -46,6 +45,8 @@ public interface ControlPlaneMonitorService { ...@@ -46,6 +45,8 @@ public interface ControlPlaneMonitorService {
46 45
47 /** 46 /**
48 * Obtains the control plane load of a specific device. 47 * Obtains the control plane load of a specific device.
48 + * The metrics range from control messages and system metrics
49 + * (e.g., CPU and memory info)
49 * 50 *
50 * @param nodeId node id {@link org.onosproject.cluster.NodeId} 51 * @param nodeId node id {@link org.onosproject.cluster.NodeId}
51 * @param type control metric type 52 * @param type control metric type
...@@ -55,15 +56,13 @@ public interface ControlPlaneMonitorService { ...@@ -55,15 +56,13 @@ public interface ControlPlaneMonitorService {
55 ControlLoad getLoad(NodeId nodeId, ControlMetricType type, Optional<DeviceId> deviceId); 56 ControlLoad getLoad(NodeId nodeId, ControlMetricType type, Optional<DeviceId> deviceId);
56 57
57 /** 58 /**
58 - * Obtains the control plane load of a specific device with a specific time duration. 59 + * Obtains the control plane load of a specific device.
60 + * The metrics range from I/O device metrics (e.g., disk and network interface)
59 * 61 *
60 - * @param nodeId node id {@link org.onosproject.cluster.NodeId} 62 + * @param nodeId node id {@link org.onosproject.cluster.NodeId}
61 - * @param type control metric type 63 + * @param type control metric type
62 - * @param duration time duration 64 + * @param resourceName resource name
63 - * @param unit time unit
64 - * @param deviceId device id {@link org.onosproject.net.Device}
65 * @return control plane load 65 * @return control plane load
66 */ 66 */
67 - ControlLoad getLoad(NodeId nodeId, ControlMetricType type, Optional<DeviceId> deviceId, 67 + ControlLoad getLoad(NodeId nodeId, ControlMetricType type, String resourceName);
68 - int duration, TimeUnit unit);
69 } 68 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -20,5 +20,6 @@ ...@@ -20,5 +20,6 @@
20 <feature>onos-api</feature> 20 <feature>onos-api</feature>
21 <bundle>mvn:${project.groupId}/onos-app-cpman-api/${project.version}</bundle> 21 <bundle>mvn:${project.groupId}/onos-app-cpman-api/${project.version}</bundle>
22 <bundle>mvn:${project.groupId}/onos-app-cpman/${project.version}</bundle> 22 <bundle>mvn:${project.groupId}/onos-app-cpman/${project.version}</bundle>
23 + <bundle>wrap:mvn:org.rrd4j/rrd4j/2.2$Bundle-SymbolicName=rrd4j&amp;Bundle-Version=2.2</bundle>
23 </feature> 24 </feature>
24 </features> 25 </features>
......
...@@ -108,6 +108,7 @@ ...@@ -108,6 +108,7 @@
108 <groupId>org.rrd4j</groupId> 108 <groupId>org.rrd4j</groupId>
109 <artifactId>rrd4j</artifactId> 109 <artifactId>rrd4j</artifactId>
110 <version>2.2</version> 110 <version>2.2</version>
111 + <scope>provided</scope>
111 </dependency> 112 </dependency>
112 <dependency> 113 <dependency>
113 <groupId>com.sun.jersey</groupId> 114 <groupId>com.sun.jersey</groupId>
...@@ -184,7 +185,8 @@ ...@@ -184,7 +185,8 @@
184 org.onlab.rest.*, 185 org.onlab.rest.*,
185 org.onosproject.*, 186 org.onosproject.*,
186 org.onlab.util.*, 187 org.onlab.util.*,
187 - org.jboss.netty.util.* 188 + org.jboss.netty.util.*,
189 + org.rrd4j.*
188 </Import-Package> 190 </Import-Package>
189 <Web-ContextPath>${web.context}</Web-ContextPath> 191 <Web-ContextPath>${web.context}</Web-ContextPath>
190 </instructions> 192 </instructions>
......
...@@ -48,8 +48,8 @@ public final class ControlMetricsFactory { ...@@ -48,8 +48,8 @@ public final class ControlMetricsFactory {
48 private MetricsAggregator cpuIdleTime; 48 private MetricsAggregator cpuIdleTime;
49 private MetricsAggregator memoryUsed; 49 private MetricsAggregator memoryUsed;
50 private MetricsAggregator memoryFree; 50 private MetricsAggregator memoryFree;
51 - private MetricsAggregator memoryUsedPercentage; 51 + private MetricsAggregator memoryUsedRatio;
52 - private MetricsAggregator memoryFreePercentage; 52 + private MetricsAggregator memoryFreeRatio;
53 private Map<String, MetricsAggregator> diskReadBytes; 53 private Map<String, MetricsAggregator> diskReadBytes;
54 private Map<String, MetricsAggregator> diskWriteBytes; 54 private Map<String, MetricsAggregator> diskWriteBytes;
55 private Map<String, MetricsAggregator> nwIncomingBytes; 55 private Map<String, MetricsAggregator> nwIncomingBytes;
...@@ -283,10 +283,10 @@ public final class ControlMetricsFactory { ...@@ -283,10 +283,10 @@ public final class ControlMetricsFactory {
283 /* Memory */ 283 /* Memory */
284 memoryFree = new MetricsAggregator(metricsService, ControlMetricType.MEMORY_FREE); 284 memoryFree = new MetricsAggregator(metricsService, ControlMetricType.MEMORY_FREE);
285 memoryUsed = new MetricsAggregator(metricsService, ControlMetricType.MEMORY_USED); 285 memoryUsed = new MetricsAggregator(metricsService, ControlMetricType.MEMORY_USED);
286 - memoryFreePercentage = new MetricsAggregator(metricsService, 286 + memoryFreeRatio = new MetricsAggregator(metricsService,
287 - ControlMetricType.MEMORY_FREE_PERCENTAGE); 287 + ControlMetricType.MEMORY_FREE_RATIO);
288 - memoryUsedPercentage = new MetricsAggregator(metricsService, 288 + memoryUsedRatio = new MetricsAggregator(metricsService,
289 - ControlMetricType.MEMORY_USED_PERCENTAGE); 289 + ControlMetricType.MEMORY_USED_RATIO);
290 290
291 /* Disk I/O */ 291 /* Disk I/O */
292 diskReadBytes = new ConcurrentHashMap<>(); 292 diskReadBytes = new ConcurrentHashMap<>();
...@@ -350,12 +350,12 @@ public final class ControlMetricsFactory { ...@@ -350,12 +350,12 @@ public final class ControlMetricsFactory {
350 return cpuIdleTime; 350 return cpuIdleTime;
351 } 351 }
352 352
353 - public MetricsAggregator memoryFreePercentage() { 353 + public MetricsAggregator memoryFreeRatio() {
354 - return memoryFreePercentage; 354 + return memoryFreeRatio;
355 } 355 }
356 356
357 - public MetricsAggregator memoryUsedPercentage() { 357 + public MetricsAggregator memoryUsedRatio() {
358 - return memoryUsedPercentage; 358 + return memoryUsedRatio;
359 } 359 }
360 360
361 public MetricsAggregator diskReadBytes(String partitionName) { 361 public MetricsAggregator diskReadBytes(String partitionName) {
......
...@@ -53,5 +53,4 @@ public class ControlPlaneManager { ...@@ -53,5 +53,4 @@ public class ControlPlaneManager {
53 protected void deactivate() { 53 protected void deactivate() {
54 log.info("Stopped"); 54 log.info("Stopped");
55 } 55 }
56 -
57 } 56 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -15,22 +15,50 @@ ...@@ -15,22 +15,50 @@
15 */ 15 */
16 package org.onosproject.cpman.impl; 16 package org.onosproject.cpman.impl;
17 17
18 +import com.google.common.collect.ImmutableSet;
18 import org.apache.felix.scr.annotations.Activate; 19 import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 20 import org.apache.felix.scr.annotations.Component;
20 import org.apache.felix.scr.annotations.Deactivate; 21 import org.apache.felix.scr.annotations.Deactivate;
22 +import org.apache.felix.scr.annotations.Reference;
23 +import org.apache.felix.scr.annotations.ReferenceCardinality;
21 import org.apache.felix.scr.annotations.Service; 24 import org.apache.felix.scr.annotations.Service;
25 +import org.onosproject.cluster.ClusterService;
26 +import org.onosproject.cluster.ControllerNode;
22 import org.onosproject.cluster.NodeId; 27 import org.onosproject.cluster.NodeId;
23 import org.onosproject.cpman.ControlLoad; 28 import org.onosproject.cpman.ControlLoad;
24 import org.onosproject.cpman.ControlMetric; 29 import org.onosproject.cpman.ControlMetric;
25 import org.onosproject.cpman.ControlMetricType; 30 import org.onosproject.cpman.ControlMetricType;
26 import org.onosproject.cpman.ControlPlaneMonitorService; 31 import org.onosproject.cpman.ControlPlaneMonitorService;
32 +import org.onosproject.cpman.MetricsDatabase;
27 import org.onosproject.net.DeviceId; 33 import org.onosproject.net.DeviceId;
28 import org.slf4j.Logger; 34 import org.slf4j.Logger;
35 +import org.slf4j.LoggerFactory;
29 36
37 +import java.util.Map;
30 import java.util.Optional; 38 import java.util.Optional;
31 -import java.util.concurrent.TimeUnit; 39 +import java.util.concurrent.ConcurrentHashMap;
32 40
33 -import static org.slf4j.LoggerFactory.getLogger; 41 +import static org.onosproject.cpman.ControlMetricType.CPU_IDLE_TIME;
42 +import static org.onosproject.cpman.ControlMetricType.CPU_LOAD;
43 +import static org.onosproject.cpman.ControlMetricType.DISK_READ_BYTES;
44 +import static org.onosproject.cpman.ControlMetricType.DISK_WRITE_BYTES;
45 +import static org.onosproject.cpman.ControlMetricType.FLOW_MOD_PACKET;
46 +import static org.onosproject.cpman.ControlMetricType.FLOW_REMOVED_PACKET;
47 +import static org.onosproject.cpman.ControlMetricType.INBOUND_PACKET;
48 +import static org.onosproject.cpman.ControlMetricType.MEMORY_FREE;
49 +import static org.onosproject.cpman.ControlMetricType.MEMORY_FREE_RATIO;
50 +import static org.onosproject.cpman.ControlMetricType.MEMORY_USED;
51 +import static org.onosproject.cpman.ControlMetricType.MEMORY_USED_RATIO;
52 +import static org.onosproject.cpman.ControlMetricType.NW_INCOMING_BYTES;
53 +import static org.onosproject.cpman.ControlMetricType.NW_INCOMING_PACKETS;
54 +import static org.onosproject.cpman.ControlMetricType.NW_OUTGOING_BYTES;
55 +import static org.onosproject.cpman.ControlMetricType.NW_OUTGOING_PACKETS;
56 +import static org.onosproject.cpman.ControlMetricType.OUTBOUND_PACKET;
57 +import static org.onosproject.cpman.ControlMetricType.REPLY_PACKET;
58 +import static org.onosproject.cpman.ControlMetricType.REQUEST_PACKET;
59 +import static org.onosproject.cpman.ControlMetricType.SYS_CPU_TIME;
60 +import static org.onosproject.cpman.ControlMetricType.TOTAL_CPU_TIME;
61 +import static org.onosproject.cpman.ControlMetricType.USER_CPU_TIME;
34 62
35 /** 63 /**
36 * Control plane monitoring service class. 64 * Control plane monitoring service class.
...@@ -39,37 +67,219 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -39,37 +67,219 @@ import static org.slf4j.LoggerFactory.getLogger;
39 @Service 67 @Service
40 public class ControlPlaneMonitor implements ControlPlaneMonitorService { 68 public class ControlPlaneMonitor implements ControlPlaneMonitorService {
41 69
42 - private final Logger log = getLogger(getClass()); 70 + private final Logger log = LoggerFactory.getLogger(getClass());
71 + private MetricsDatabase cpuMetrics;
72 + private MetricsDatabase memoryMetrics;
73 + private Map<DeviceId, MetricsDatabase> controlMessageMap;
74 + private Map<String, MetricsDatabase> diskMetricsMap;
75 + private Map<String, MetricsDatabase> networkMetricsMap;
76 +
77 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
78 + protected ClusterService clusterService;
79 +
80 + private static final String CPU = "Cpu";
81 + private static final String MEMORY = "Memory";
82 + private static final String CTRL_MSG = "ControlMessage";
83 + private static final String DISK = "Disk";
84 + private static final String NETWORK = "Network";
85 +
86 + private static final ImmutableSet<ControlMetricType> CPU_METRICS =
87 + ImmutableSet.of(CPU_IDLE_TIME, CPU_LOAD, SYS_CPU_TIME,
88 + USER_CPU_TIME, TOTAL_CPU_TIME);
89 + private static final ImmutableSet<ControlMetricType> MEMORY_METRICS =
90 + ImmutableSet.of(MEMORY_FREE, MEMORY_FREE_RATIO, MEMORY_USED,
91 + MEMORY_USED_RATIO);
92 + private static final ImmutableSet<ControlMetricType> DISK_METRICS =
93 + ImmutableSet.of(DISK_READ_BYTES, DISK_WRITE_BYTES);
94 + private static final ImmutableSet<ControlMetricType> NETWORK_METRICS =
95 + ImmutableSet.of(NW_INCOMING_BYTES, NW_OUTGOING_BYTES,
96 + NW_INCOMING_PACKETS, NW_OUTGOING_PACKETS);
97 + private static final ImmutableSet<ControlMetricType> CTRL_MSGS =
98 + ImmutableSet.of(INBOUND_PACKET, OUTBOUND_PACKET, FLOW_MOD_PACKET,
99 + FLOW_REMOVED_PACKET, REQUEST_PACKET, REPLY_PACKET);
100 + private Map<ControlMetricType, Double> cpuBuf;
101 + private Map<ControlMetricType, Double> memoryBuf;
102 + private Map<String, Map<ControlMetricType, Double>> diskBuf;
103 + private Map<String, Map<ControlMetricType, Double>> networkBuf;
104 + private Map<DeviceId, Map<ControlMetricType, Double>> ctrlMsgBuf;
43 105
44 @Activate 106 @Activate
45 public void activate() { 107 public void activate() {
108 + cpuMetrics = genMDbBuilder(CPU, CPU_METRICS);
109 + memoryMetrics = genMDbBuilder(MEMORY, MEMORY_METRICS);
110 + controlMessageMap = new ConcurrentHashMap<>();
111 + diskMetricsMap = new ConcurrentHashMap<>();
112 + networkMetricsMap = new ConcurrentHashMap<>();
113 +
114 + cpuBuf = new ConcurrentHashMap<>();
115 + memoryBuf = new ConcurrentHashMap<>();
116 + diskBuf = new ConcurrentHashMap<>();
117 + networkBuf = new ConcurrentHashMap<>();
118 + ctrlMsgBuf = new ConcurrentHashMap<>();
119 +
120 + log.info("Started");
46 } 121 }
47 122
48 @Deactivate 123 @Deactivate
49 public void deactivate() { 124 public void deactivate() {
125 +
126 + // TODO: need to handle the mdb close.
127 + cpuBuf.clear();
128 + memoryBuf.clear();
129 + diskBuf.clear();
130 + networkBuf.clear();
131 + ctrlMsgBuf.clear();
132 +
133 + log.info("Stopped");
50 } 134 }
51 135
52 @Override 136 @Override
53 - public void updateMetric(ControlMetric cpm, Integer updateInterval, 137 + public void updateMetric(ControlMetric cm, Integer updateInterval,
54 Optional<DeviceId> deviceId) { 138 Optional<DeviceId> deviceId) {
139 + if (deviceId.isPresent()) {
55 140
141 + // insert a new device entry if we cannot find any
142 + ctrlMsgBuf.putIfAbsent(deviceId.get(), new ConcurrentHashMap<>());
143 +
144 + // update control message metrics
145 + if (CTRL_MSGS.contains(cm.metricType())) {
146 +
147 + // we will accumulate the metric value into buffer first
148 + ctrlMsgBuf.get(deviceId.get()).putIfAbsent(cm.metricType(),
149 + (double) cm.metricValue().getLoad());
150 +
151 + // if buffer contains all control message metrics,
152 + // we simply set and update the values into MetricsDatabase.
153 + if (ctrlMsgBuf.get(deviceId.get()).keySet().containsAll(CTRL_MSGS)) {
154 + updateControlMessages(ctrlMsgBuf.get(deviceId.get()), deviceId.get());
155 + ctrlMsgBuf.get(deviceId.get()).clear();
156 + }
157 + }
158 + } else {
159 +
160 + // update cpu metrics
161 + if (CPU_METRICS.contains(cm.metricType())) {
162 + cpuBuf.putIfAbsent(cm.metricType(),
163 + (double) cm.metricValue().getLoad());
164 + if (cpuBuf.keySet().containsAll(CPU_METRICS)) {
165 + cpuMetrics.updateMetrics(convertMap(cpuBuf));
166 + cpuBuf.clear();
167 + }
168 + }
169 +
170 + // update memory metrics
171 + if (MEMORY_METRICS.contains(cm.metricType())) {
172 + memoryBuf.putIfAbsent(cm.metricType(),
173 + (double) cm.metricValue().getLoad());
174 + if (memoryBuf.keySet().containsAll(MEMORY_METRICS)) {
175 + memoryMetrics.updateMetrics(convertMap(memoryBuf));
176 + memoryBuf.clear();
177 + }
178 + }
179 + }
56 } 180 }
57 181
58 @Override 182 @Override
59 - public void updateMetric(ControlMetric controlMetric, Integer updateInterval, 183 + public void updateMetric(ControlMetric cm, Integer updateInterval,
60 String resourceName) { 184 String resourceName) {
185 + // update disk metrics
186 + if (DISK_METRICS.contains(cm.metricType())) {
187 + diskBuf.putIfAbsent(resourceName, new ConcurrentHashMap<>());
188 + diskBuf.get(resourceName).putIfAbsent(cm.metricType(),
189 + (double) cm.metricValue().getLoad());
190 + if (diskBuf.get(resourceName).keySet().containsAll(DISK_METRICS)) {
191 + updateDiskMetrics(diskBuf.get(resourceName), resourceName);
192 + diskBuf.clear();
193 + }
194 + }
61 195
196 + // update network metrics
197 + if (NETWORK_METRICS.contains(cm.metricType())) {
198 + networkBuf.putIfAbsent(resourceName, new ConcurrentHashMap<>());
199 + networkBuf.get(resourceName).putIfAbsent(cm.metricType(),
200 + (double) cm.metricValue().getLoad());
201 + if (networkBuf.get(resourceName).keySet().containsAll(NETWORK_METRICS)) {
202 + updateNetworkMetrics(networkBuf.get(resourceName), resourceName);
203 + networkBuf.clear();
204 + }
205 + }
62 } 206 }
63 207
64 @Override 208 @Override
65 public ControlLoad getLoad(NodeId nodeId, ControlMetricType type, 209 public ControlLoad getLoad(NodeId nodeId, ControlMetricType type,
66 Optional<DeviceId> deviceId) { 210 Optional<DeviceId> deviceId) {
211 + ControllerNode node = clusterService.getNode(nodeId);
212 + if (clusterService.getLocalNode().equals(node)) {
213 +
214 + if (deviceId.isPresent()) {
215 + if (CTRL_MSGS.contains(type)) {
216 + return new DefaultControlLoad(controlMessageMap.get(deviceId.get()), type);
217 + }
218 + } else {
219 + // returns controlLoad of CPU metrics
220 + if (CPU_METRICS.contains(type)) {
221 + return new DefaultControlLoad(cpuMetrics, type);
222 + }
223 +
224 + // returns memoryLoad of memory metrics
225 + if (MEMORY_METRICS.contains(type)) {
226 + return new DefaultControlLoad(memoryMetrics, type);
227 + }
228 + }
229 + } else {
230 + // TODO: currently only query the metrics of local node
231 + return null;
232 + }
67 return null; 233 return null;
68 } 234 }
69 235
70 @Override 236 @Override
71 public ControlLoad getLoad(NodeId nodeId, ControlMetricType type, 237 public ControlLoad getLoad(NodeId nodeId, ControlMetricType type,
72 - Optional<DeviceId> deviceId, int duration, TimeUnit unit) { 238 + String resourceName) {
239 + if (clusterService.getLocalNode().id().equals(nodeId)) {
240 + if (DISK_METRICS.contains(type)) {
241 + return new DefaultControlLoad(diskMetricsMap.get(resourceName), type);
242 + }
243 +
244 + if (NETWORK_METRICS.contains(type)) {
245 + return new DefaultControlLoad(networkMetricsMap.get(resourceName), type);
246 + }
247 + } else {
248 + // TODO: currently only query the metrics of local node
249 + return null;
250 + }
73 return null; 251 return null;
74 } 252 }
253 +
254 + private MetricsDatabase genMDbBuilder(String metricName,
255 + ImmutableSet<ControlMetricType> metricTypes) {
256 + MetricsDatabase.Builder builder = new DefaultMetricsDatabase.Builder();
257 + builder.withMetricName(metricName);
258 + metricTypes.forEach(type -> builder.addMetricType(type.toString()));
259 + return builder.build();
260 + }
261 +
262 + private void updateNetworkMetrics(Map<ControlMetricType, Double> metricMap,
263 + String resName) {
264 + networkMetricsMap.putIfAbsent(resName, genMDbBuilder(NETWORK, NETWORK_METRICS));
265 + networkMetricsMap.get(resName).updateMetrics(convertMap(metricMap));
266 + }
267 +
268 + private void updateDiskMetrics(Map<ControlMetricType, Double> metricMap,
269 + String resName) {
270 + diskMetricsMap.putIfAbsent(resName, genMDbBuilder(DISK, DISK_METRICS));
271 + diskMetricsMap.get(resName).updateMetrics(convertMap(metricMap));
272 + }
273 +
274 + private void updateControlMessages(Map<ControlMetricType, Double> metricMap,
275 + DeviceId devId) {
276 + controlMessageMap.putIfAbsent(devId, genMDbBuilder(CTRL_MSG, CTRL_MSGS));
277 + controlMessageMap.get(devId).updateMetrics(convertMap(metricMap));
278 + }
279 +
280 + private Map convertMap(Map<ControlMetricType, Double> map) {
281 + Map newMap = new ConcurrentHashMap<>();
282 + map.forEach((k, v) -> newMap.putIfAbsent(k.toString(), v));
283 + return newMap;
284 + }
75 } 285 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -243,10 +243,6 @@ public final class DefaultMetricsDatabase implements MetricsDatabase { ...@@ -243,10 +243,6 @@ public final class DefaultMetricsDatabase implements MetricsDatabase {
243 private String metricName; 243 private String metricName;
244 244
245 public Builder() { 245 public Builder() {
246 -
247 - // define the resolution of monitored metrics
248 - rrdDef = new RrdDef(DB_PATH, RESOLUTION);
249 -
250 // initialize data source definition list 246 // initialize data source definition list
251 dsDefs = new ArrayList<>(); 247 dsDefs = new ArrayList<>();
252 } 248 }
...@@ -254,6 +250,9 @@ public final class DefaultMetricsDatabase implements MetricsDatabase { ...@@ -254,6 +250,9 @@ public final class DefaultMetricsDatabase implements MetricsDatabase {
254 @Override 250 @Override
255 public Builder withMetricName(String metricName) { 251 public Builder withMetricName(String metricName) {
256 this.metricName = metricName; 252 this.metricName = metricName;
253 +
254 + // define the resolution of monitored metrics
255 + rrdDef = new RrdDef(DB_PATH + "_" + metricName, RESOLUTION);
257 return this; 256 return this;
258 } 257 }
259 258
......
...@@ -122,20 +122,20 @@ public class ControlMetricsCollectorWebResource extends AbstractWebResource { ...@@ -122,20 +122,20 @@ public class ControlMetricsCollectorWebResource extends AbstractWebResource {
122 ControlMetric cm; 122 ControlMetric cm;
123 try { 123 try {
124 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); 124 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
125 - JsonNode memUsedPerc = jsonTree.get("memoryUsedPercentage"); 125 + JsonNode memUsedRatio = jsonTree.get("memoryUsedRatio");
126 - JsonNode memFreePerc = jsonTree.get("memoryFreePercentage"); 126 + JsonNode memFreeRatio = jsonTree.get("memoryFreeRatio");
127 JsonNode memUsed = jsonTree.get("memoryUsed"); 127 JsonNode memUsed = jsonTree.get("memoryUsed");
128 JsonNode memFree = jsonTree.get("memoryFree"); 128 JsonNode memFree = jsonTree.get("memoryFree");
129 129
130 - if (memUsedPerc != null) { 130 + if (memUsedRatio != null) {
131 - cm = new ControlMetric(ControlMetricType.MEMORY_USED_PERCENTAGE, 131 + cm = new ControlMetric(ControlMetricType.MEMORY_USED_RATIO,
132 - new MetricValue.Builder().load(memUsedPerc.asLong()).add()); 132 + new MetricValue.Builder().load(memUsedRatio.asLong()).add());
133 service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null)); 133 service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
134 } 134 }
135 135
136 - if (memFreePerc != null) { 136 + if (memFreeRatio != null) {
137 - cm = new ControlMetric(ControlMetricType.MEMORY_FREE_PERCENTAGE, 137 + cm = new ControlMetric(ControlMetricType.MEMORY_FREE_RATIO,
138 - new MetricValue.Builder().load(memFreePerc.asLong()).add()); 138 + new MetricValue.Builder().load(memFreeRatio.asLong()).add());
139 service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null)); 139 service.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
140 } 140 }
141 141
......
1 { 1 {
2 "type": "object", 2 "type": "object",
3 "required": [ 3 "required": [
4 - "memoryUsedPercentage", 4 + "memoryUsedRatio",
5 - "memoryFreePercentage", 5 + "memoryFreeRatio",
6 "memoryUsed", 6 "memoryUsed",
7 "memoryFree" 7 "memoryFree"
8 ], 8 ],
9 "properties": { 9 "properties": {
10 - "memoryUsedPercentage": { 10 + "memoryUsedRatio": {
11 "type": "integer", 11 "type": "integer",
12 "format": "int64", 12 "format": "int64",
13 "example": "30" 13 "example": "30"
14 }, 14 },
15 - "memoryFreePercentage": { 15 + "memoryFreeRatio": {
16 "type": "integer", 16 "type": "integer",
17 "format": "int64", 17 "format": "int64",
18 "example": "70" 18 "example": "70"
......
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.impl;
17 +
18 +import com.google.common.collect.ImmutableSet;
19 +import org.junit.Before;
20 +import org.junit.Test;
21 +import org.onlab.packet.IpAddress;
22 +import org.onosproject.cluster.ClusterService;
23 +import org.onosproject.cluster.ControllerNode;
24 +import org.onosproject.cluster.NodeId;
25 +import org.onosproject.cpman.ControlMetric;
26 +import org.onosproject.cpman.ControlMetricType;
27 +import org.onosproject.cpman.MetricValue;
28 +import org.onosproject.net.DeviceId;
29 +
30 +import java.util.Optional;
31 +
32 +import static org.easymock.EasyMock.anyObject;
33 +import static org.easymock.EasyMock.createMock;
34 +import static org.easymock.EasyMock.expect;
35 +import static org.easymock.EasyMock.replay;
36 +import static org.hamcrest.Matchers.is;
37 +import static org.junit.Assert.assertThat;
38 +import static org.onosproject.cpman.ControlMetricType.CPU_IDLE_TIME;
39 +import static org.onosproject.cpman.ControlMetricType.CPU_LOAD;
40 +import static org.onosproject.cpman.ControlMetricType.DISK_READ_BYTES;
41 +import static org.onosproject.cpman.ControlMetricType.DISK_WRITE_BYTES;
42 +import static org.onosproject.cpman.ControlMetricType.FLOW_MOD_PACKET;
43 +import static org.onosproject.cpman.ControlMetricType.FLOW_REMOVED_PACKET;
44 +import static org.onosproject.cpman.ControlMetricType.INBOUND_PACKET;
45 +import static org.onosproject.cpman.ControlMetricType.MEMORY_FREE;
46 +import static org.onosproject.cpman.ControlMetricType.MEMORY_FREE_RATIO;
47 +import static org.onosproject.cpman.ControlMetricType.MEMORY_USED;
48 +import static org.onosproject.cpman.ControlMetricType.MEMORY_USED_RATIO;
49 +import static org.onosproject.cpman.ControlMetricType.NW_INCOMING_BYTES;
50 +import static org.onosproject.cpman.ControlMetricType.NW_INCOMING_PACKETS;
51 +import static org.onosproject.cpman.ControlMetricType.NW_OUTGOING_BYTES;
52 +import static org.onosproject.cpman.ControlMetricType.NW_OUTGOING_PACKETS;
53 +import static org.onosproject.cpman.ControlMetricType.OUTBOUND_PACKET;
54 +import static org.onosproject.cpman.ControlMetricType.REPLY_PACKET;
55 +import static org.onosproject.cpman.ControlMetricType.REQUEST_PACKET;
56 +import static org.onosproject.cpman.ControlMetricType.SYS_CPU_TIME;
57 +import static org.onosproject.cpman.ControlMetricType.TOTAL_CPU_TIME;
58 +import static org.onosproject.cpman.ControlMetricType.USER_CPU_TIME;
59 +
60 +/**
61 + * Unit test of control plane monitoring service.
62 + */
63 +public class ControlPlaneMonitorTest {
64 +
65 + private ControlPlaneMonitor monitor;
66 + private static final Integer UPDATE_INTERVAL = 1;
67 + private ClusterService mockClusterService;
68 + private ControllerNode mockControllerNode;
69 + private NodeId nodeId;
70 + private static final ImmutableSet<ControlMetricType> CPU_METRICS =
71 + ImmutableSet.of(CPU_IDLE_TIME, CPU_LOAD, SYS_CPU_TIME,
72 + USER_CPU_TIME, TOTAL_CPU_TIME);
73 + private static final ImmutableSet<ControlMetricType> MEMORY_METRICS =
74 + ImmutableSet.of(MEMORY_FREE, MEMORY_FREE_RATIO, MEMORY_USED,
75 + MEMORY_USED_RATIO);
76 + private static final ImmutableSet<ControlMetricType> DISK_METRICS =
77 + ImmutableSet.of(DISK_READ_BYTES, DISK_WRITE_BYTES);
78 + private static final ImmutableSet<ControlMetricType> NETWORK_METRICS =
79 + ImmutableSet.of(NW_INCOMING_BYTES, NW_OUTGOING_BYTES,
80 + NW_INCOMING_PACKETS, NW_OUTGOING_PACKETS);
81 + private static final ImmutableSet<ControlMetricType> CTRL_MSGS =
82 + ImmutableSet.of(INBOUND_PACKET, OUTBOUND_PACKET, FLOW_MOD_PACKET,
83 + FLOW_REMOVED_PACKET, REQUEST_PACKET, REPLY_PACKET);
84 +
85 + @Before
86 + public void setup() throws Exception {
87 + monitor = new ControlPlaneMonitor();
88 + monitor.activate();
89 +
90 + nodeId = new NodeId("1");
91 + mockControllerNode = new MockControllerNode(nodeId);
92 + mockClusterService = createMock(ClusterService.class);
93 + monitor.clusterService = mockClusterService;
94 +
95 + expect(mockClusterService.getNode(anyObject()))
96 + .andReturn(mockControllerNode).anyTimes();
97 + expect(mockClusterService.getLocalNode())
98 + .andReturn(mockControllerNode).anyTimes();
99 + replay(mockClusterService);
100 + }
101 +
102 + /**
103 + * Mock class for a controller node.
104 + */
105 + private static class MockControllerNode implements ControllerNode {
106 + final NodeId id;
107 +
108 + public MockControllerNode(NodeId id) {
109 + this.id = id;
110 + }
111 +
112 + @Override
113 + public NodeId id() {
114 + return this.id;
115 + }
116 +
117 + @Override
118 + public IpAddress ip() {
119 + return null;
120 + }
121 +
122 + @Override
123 + public int tcpPort() {
124 + return 0;
125 + }
126 + }
127 +
128 + private void testUpdateMetricWithoutId(ControlMetricType cmt, MetricValue mv) {
129 + ControlMetric cm = new ControlMetric(cmt, mv);
130 + monitor.updateMetric(cm, UPDATE_INTERVAL, Optional.ofNullable(null));
131 + }
132 +
133 + private void testLoadMetricWithoutId(ControlMetricType cmt, MetricValue mv) {
134 + assertThat(monitor.getLoad(nodeId, cmt, Optional.ofNullable(null)).latest(), is(mv.getLoad()));
135 + }
136 +
137 + private void testUpdateMetricWithResource(ControlMetricType cmt, MetricValue mv, String resoureName) {
138 + ControlMetric cm = new ControlMetric(cmt, mv);
139 + monitor.updateMetric(cm, UPDATE_INTERVAL, resoureName);
140 + }
141 +
142 + private void testLoadMetricWithResource(ControlMetricType cmt, MetricValue mv, String resoureName) {
143 + assertThat(monitor.getLoad(nodeId, cmt, resoureName).latest(), is(mv.getLoad()));
144 + }
145 +
146 + private void testUpdateMetricWithId(ControlMetricType cmt, MetricValue mv, DeviceId did) {
147 + ControlMetric cm = new ControlMetric(cmt, mv);
148 + monitor.updateMetric(cm, UPDATE_INTERVAL, Optional.of(did));
149 + }
150 +
151 + private void testLoadMetricWithId(ControlMetricType cmt, MetricValue mv, DeviceId did) {
152 + assertThat(monitor.getLoad(nodeId, cmt, Optional.of(did)).latest(), is(mv.getLoad()));
153 + }
154 +
155 + @Test
156 + public void testCpuMetric() {
157 + MetricValue mv = new MetricValue.Builder().load(30).add();
158 +
159 + CPU_METRICS.forEach(cmt -> testUpdateMetricWithoutId(cmt, mv));
160 + CPU_METRICS.forEach(cmt -> testLoadMetricWithoutId(cmt, mv));
161 + }
162 +
163 + @Test
164 + public void testMemoryMetric() {
165 + MetricValue mv = new MetricValue.Builder().load(40).add();
166 +
167 + MEMORY_METRICS.forEach(cmt -> testUpdateMetricWithoutId(cmt, mv));
168 + MEMORY_METRICS.forEach(cmt -> testLoadMetricWithoutId(cmt, mv));
169 + }
170 +
171 + @Test
172 + public void testDiskMetric() {
173 + MetricValue mv = new MetricValue.Builder().load(50).add();
174 +
175 + ImmutableSet<String> set = ImmutableSet.of("disk1", "disk2");
176 +
177 + set.forEach(disk -> DISK_METRICS.forEach(cmt ->
178 + testUpdateMetricWithResource(cmt, mv, disk)));
179 +
180 + set.forEach(disk -> DISK_METRICS.forEach(cmt ->
181 + testLoadMetricWithResource(cmt, mv, disk)));
182 + }
183 +
184 + @Test
185 + public void testNetworkMetric() {
186 + MetricValue mv = new MetricValue.Builder().load(10).add();
187 +
188 + ImmutableSet<String> set = ImmutableSet.of("eth0", "eth1");
189 +
190 + set.forEach(network -> NETWORK_METRICS.forEach(cmt ->
191 + testUpdateMetricWithResource(cmt, mv, network)));
192 +
193 + set.forEach(network -> NETWORK_METRICS.forEach(cmt ->
194 + testLoadMetricWithResource(cmt, mv, network)));
195 + }
196 +
197 + @Test
198 + public void testUpdateControlMessage() {
199 + MetricValue mv = new MetricValue.Builder().load(10).add();
200 +
201 + ImmutableSet<String> set = ImmutableSet.of("of:0000000000000001",
202 + "of:0000000000000002");
203 +
204 + set.forEach(ctrlMsg -> CTRL_MSGS.forEach(cmt ->
205 + testUpdateMetricWithId(cmt, mv, DeviceId.deviceId(ctrlMsg))));
206 +
207 + set.forEach(ctrlMsg -> CTRL_MSGS.forEach(cmt ->
208 + testLoadMetricWithId(cmt, mv, DeviceId.deviceId(ctrlMsg))));
209 + }
210 +}
1 { 1 {
2 - "memoryUsedPercentage": 30, 2 + "memoryUsedRatio": 30,
3 - "memoryFreePercentage": 70, 3 + "memoryFreeRatio": 70,
4 "memoryUsed": 1024, 4 "memoryUsed": 1024,
5 "memoryFree": 2048 5 "memoryFree": 2048
6 } 6 }
...\ No newline at end of file ...\ No newline at end of file
......