Jian Li
Committed by Gerrit Code Review

[ONOS-3536] Implement back-end metrics saving logic using RRD

Change-Id: I1b3c495380884571dc88d2f9fb3152fdf41ef655
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;
17 +
18 +import java.util.Map;
19 +import java.util.concurrent.TimeUnit;
20 +
21 +/**
22 + * Database for storing a metric.
23 + */
24 +public interface MetricsDatabase {
25 + /**
26 + * Returns the metric name of this database.
27 + *
28 + * @return metric name
29 + */
30 + String metricName();
31 +
32 + /**
33 + * Update metric value by specifying metric type.
34 + *
35 + * @param metricType metric type (e.g., load, usage, etc.)
36 + * @param value metric value
37 + */
38 + void updateMetric(String metricType, double value);
39 +
40 + /**
41 + * Update metric value by specifying metric type in a certain time.
42 + *
43 + * @param metricType metric type (e.g., load, usage, etc.)
44 + * @param value metric value
45 + * @param time update time in seconds
46 + */
47 + void updateMetric(String metricType, double value, long time);
48 +
49 + /**
50 + * Update metric values of a collection of metric types.
51 + *
52 + * @param metrics a collection of metrics which consists of a pair of
53 + * metric type and metric value
54 + * @param time update time in seconds
55 + */
56 + void updateMetrics(Map<String, Double> metrics, long time);
57 +
58 + /**
59 + * Update metric values of a collection of metric types.
60 + *
61 + * @param metrics a collection of metrics which consists of a pair of
62 + * metric type and metric value
63 + */
64 + void updateMetrics(Map<String, Double> metrics);
65 +
66 + /**
67 + * Returns most recent metric value of a given metric type.
68 + *
69 + * @param metricType metric type
70 + * @return metric value
71 + */
72 + double recentMetric(String metricType);
73 +
74 + /**
75 + * Return most recent metric values of a given metric type for a given period.
76 + *
77 + * @param metricType metric type
78 + * @param duration duration
79 + * @param unit time unit
80 + * @return a collection of metric value
81 + */
82 + double[] recentMetrics(String metricType, int duration, TimeUnit unit);
83 +
84 + /**
85 + * Returns minimum metric value of a given metric type.
86 + *
87 + * @param metricType metric type
88 + * @return metric value
89 + */
90 + double minMetric(String metricType);
91 +
92 + /**
93 + * Returns maximum metric value of a given metric type.
94 + *
95 + * @param metricType metric type
96 + * @return metric value
97 + */
98 + double maxMetric(String metricType);
99 +
100 + /**
101 + * Returns a collection of metric values of a given metric type for a day.
102 + *
103 + * @param metricType metric type
104 + * @return a collection of metric value
105 + */
106 + double[] metrics(String metricType);
107 +
108 + /**
109 + * Returns a collection of metric values of a given metric type for
110 + * a given period.
111 + *
112 + * @param metricType metric type
113 + * @param startTime start time
114 + * @param endTime end time
115 + * @return a collection of metric value
116 + */
117 + double[] metrics(String metricType, long startTime, long endTime);
118 +
119 + /**
120 + * A builder of MetricsDatabase.
121 + */
122 + interface Builder {
123 +
124 + /**
125 + * Sets the metric name.
126 + *
127 + * @param metricName metric name
128 + * @return builder object
129 + */
130 + Builder withMetricName(String metricName);
131 +
132 + /**
133 + * Add a new metric to be monitored.
134 + *
135 + * @param metricType control metric type
136 + */
137 + Builder addMetricType(String metricType);
138 +
139 + /**
140 + * Builds a MetricDatabase instance.
141 + *
142 + * @return MetricDatabase instance
143 + */
144 + MetricsDatabase build();
145 + }
146 +}
...@@ -105,6 +105,11 @@ ...@@ -105,6 +105,11 @@
105 <version>1.1.1</version> 105 <version>1.1.1</version>
106 </dependency> 106 </dependency>
107 <dependency> 107 <dependency>
108 + <groupId>org.rrd4j</groupId>
109 + <artifactId>rrd4j</artifactId>
110 + <version>2.2</version>
111 + </dependency>
112 + <dependency>
108 <groupId>com.sun.jersey</groupId> 113 <groupId>com.sun.jersey</groupId>
109 <artifactId>jersey-servlet</artifactId> 114 <artifactId>jersey-servlet</artifactId>
110 </dependency> 115 </dependency>
......
...@@ -43,7 +43,6 @@ public class ControlPlaneMonitor implements ControlPlaneMonitorService { ...@@ -43,7 +43,6 @@ public class ControlPlaneMonitor implements ControlPlaneMonitorService {
43 43
44 @Activate 44 @Activate
45 public void activate() { 45 public void activate() {
46 -
47 } 46 }
48 47
49 @Deactivate 48 @Deactivate
...@@ -53,6 +52,7 @@ public class ControlPlaneMonitor implements ControlPlaneMonitorService { ...@@ -53,6 +52,7 @@ public class ControlPlaneMonitor implements ControlPlaneMonitorService {
53 @Override 52 @Override
54 public void updateMetric(ControlMetric cpm, Integer updateInterval, 53 public void updateMetric(ControlMetric cpm, Integer updateInterval,
55 Optional<DeviceId> deviceId) { 54 Optional<DeviceId> deviceId) {
55 +
56 } 56 }
57 57
58 @Override 58 @Override
......
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 org.junit.Before;
19 +import org.junit.Test;
20 +import org.onosproject.cpman.MetricsDatabase;
21 +
22 +import java.util.HashMap;
23 +import java.util.Map;
24 +import java.util.concurrent.TimeUnit;
25 +
26 +import static org.hamcrest.Matchers.is;
27 +import static org.junit.Assert.assertThat;
28 +
29 +/**
30 + * Unit test for control plane metrics back-end database.
31 + */
32 +public class MetricsDatabaseTest {
33 +
34 + private MetricsDatabase mdb;
35 + private static final String CPU_METRIC = "cpu";
36 + private static final String CPU_LOAD = "load";
37 + private static final String MEMORY_METRIC = "memory";
38 + private static final String MEMORY_FREE_PERC = "freePerc";
39 + private static final String MEMORY_USED_PERC = "usedPerc";
40 +
41 + /**
42 + * Initializes the MetricsDatabase instance.
43 + */
44 + @Before
45 + public void setUp() {
46 + mdb = new DefaultMetricsDatabase.Builder()
47 + .withMetricName(CPU_METRIC)
48 + .addMetricType(CPU_LOAD)
49 + .build();
50 + }
51 +
52 + /**
53 + * Tests the metric update function.
54 + */
55 + @Test
56 + public void testMetricUpdate() {
57 + long currentTime = System.currentTimeMillis() / 1000L;
58 +
59 + mdb.updateMetric(CPU_LOAD, 30, currentTime);
60 + assertThat(30D, is(mdb.recentMetric(CPU_LOAD)));
61 +
62 + mdb.updateMetric(CPU_LOAD, 40, currentTime + 60);
63 + assertThat(40D, is(mdb.recentMetric(CPU_LOAD)));
64 +
65 + mdb.updateMetric(CPU_LOAD, 50, currentTime + 120);
66 + assertThat(50D, is(mdb.recentMetric(CPU_LOAD)));
67 + }
68 +
69 + /**
70 + * Tests the metric range fetch function.
71 + */
72 + @Test
73 + public void testMetricRangeFetch() {
74 + // full range fetch
75 + assertThat(mdb.metrics(CPU_LOAD).length, is(60 * 24));
76 +
77 + // query one minute time range
78 + assertThat(mdb.recentMetrics(CPU_LOAD, 1, TimeUnit.MINUTES).length, is(1));
79 +
80 + // query one hour time range
81 + assertThat(mdb.recentMetrics(CPU_LOAD, 1, TimeUnit.HOURS).length, is(60));
82 +
83 + // query one day time range
84 + assertThat(mdb.recentMetrics(CPU_LOAD, 1, TimeUnit.DAYS).length, is(60 * 24));
85 +
86 + // query a specific time range
87 + long endTime = System.currentTimeMillis() / 1000L;
88 + long startTime = endTime - 60 * 5;
89 + assertThat(mdb.metrics(CPU_LOAD, startTime, endTime).length, is(5));
90 + }
91 +
92 + /**
93 + * Test the projected time range.
94 + */
95 + @Test(expected = IllegalArgumentException.class)
96 + public void testExceededTimeRange() {
97 + // query 25 hours time range
98 + assertThat(mdb.recentMetrics(CPU_LOAD, 25, TimeUnit.HOURS).length, is(60 * 24));
99 + }
100 +
101 + /**
102 + * Test the projected time range.
103 + */
104 + @Test(expected = IllegalArgumentException.class)
105 + public void testInsufficientTimeRange() {
106 + // query 50 seconds time range
107 + assertThat(mdb.recentMetrics(CPU_LOAD, 50, TimeUnit.SECONDS).length, is(1));
108 + }
109 +
110 + /**
111 + * Test multiple metrics update and query.
112 + */
113 + @Test
114 + public void testMultipleMetrics() {
115 + MetricsDatabase multiMdb = new DefaultMetricsDatabase.Builder()
116 + .withMetricName(MEMORY_METRIC)
117 + .addMetricType(MEMORY_FREE_PERC)
118 + .addMetricType(MEMORY_USED_PERC)
119 + .build();
120 +
121 + Map<String, Double> metrics = new HashMap<>();
122 + metrics.putIfAbsent(MEMORY_FREE_PERC, 30D);
123 + metrics.putIfAbsent(MEMORY_USED_PERC, 70D);
124 + multiMdb.updateMetrics(metrics);
125 +
126 + assertThat(30D, is(multiMdb.recentMetric(MEMORY_FREE_PERC)));
127 + assertThat(70D, is(multiMdb.recentMetric(MEMORY_USED_PERC)));
128 + }
129 +}