Add resource name into MetricsDatabase, handle exception gracefully
Change-Id: Icf19965a0fcbfd9696c42b12c32441fd3b161734
diff --git a/apps/cpman/api/src/main/java/org/onosproject/cpman/MetricsDatabase.java b/apps/cpman/api/src/main/java/org/onosproject/cpman/MetricsDatabase.java
index 54167b8..ccdc6b8 100644
--- a/apps/cpman/api/src/main/java/org/onosproject/cpman/MetricsDatabase.java
+++ b/apps/cpman/api/src/main/java/org/onosproject/cpman/MetricsDatabase.java
@@ -30,6 +30,13 @@
String metricName();
/**
+ * Returns the resource name of this database.
+ *
+ * @return resource name
+ */
+ String resourceName();
+
+ /**
* Update metric value by specifying metric type.
*
* @param metricType metric type (e.g., load, usage, etc.)
@@ -138,6 +145,14 @@
Builder withMetricName(String metricName);
/**
+ * Sets the resource name.
+ *
+ * @param resourceName resource name
+ * @return builder object
+ */
+ Builder withResourceName(String resourceName);
+
+ /**
* Add a new metric to be monitored.
*
* @param metricType control metric type
diff --git a/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/ControlPlaneMonitor.java b/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/ControlPlaneMonitor.java
index 3452255..fa971b6 100644
--- a/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/ControlPlaneMonitor.java
+++ b/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/ControlPlaneMonitor.java
@@ -77,6 +77,8 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterCommunicationService communicationService;
+ private static final String DEFAULT_RESOURCE = "default";
+
private static final Set RESOURCE_TYPE_SET =
ImmutableSet.of(Type.CONTROL_MESSAGE, Type.DISK, Type.NETWORK);
@@ -96,6 +98,8 @@
private static final String METRIC_TYPE_NULL = "Control metric type cannot be null";
+ Set<Map<ControlMetricType, Double>> debugSets = Sets.newHashSet();
+
private static final Serializer SERIALIZER = Serializer
.using(new KryoNamespace.Builder()
.register(KryoNamespaces.API)
@@ -107,8 +111,8 @@
@Activate
public void activate() {
- cpuMetrics = genMDbBuilder(Type.CPU, CPU_METRICS);
- memoryMetrics = genMDbBuilder(Type.MEMORY, MEMORY_METRICS);
+ cpuMetrics = genMDbBuilder(DEFAULT_RESOURCE, Type.CPU, CPU_METRICS);
+ memoryMetrics = genMDbBuilder(DEFAULT_RESOURCE, Type.MEMORY, MEMORY_METRICS);
controlMessageMap = Maps.newConcurrentMap();
diskMetricsMap = Maps.newConcurrentMap();
networkMetricsMap = Maps.newConcurrentMap();
@@ -170,7 +174,7 @@
if (ctrlMsgBuf.get(deviceId.get()).keySet()
.containsAll(CONTROL_MESSAGE_METRICS)) {
updateControlMessages(ctrlMsgBuf.get(deviceId.get()), deviceId.get());
- ctrlMsgBuf.get(deviceId.get()).clear();
+ ctrlMsgBuf.get(deviceId.get());
}
}
} else {
@@ -304,31 +308,34 @@
return ImmutableSet.of();
}
- private MetricsDatabase genMDbBuilder(Type resourceType,
+ private MetricsDatabase genMDbBuilder(String resourceName,
+ Type resourceType,
Set<ControlMetricType> metricTypes) {
MetricsDatabase.Builder builder = new DefaultMetricsDatabase.Builder();
builder.withMetricName(resourceType.toString());
+ builder.withResourceName(resourceName);
metricTypes.forEach(type -> builder.addMetricType(type.toString()));
return builder.build();
}
private void updateNetworkMetrics(Map<ControlMetricType, Double> metricMap,
String resName) {
- networkMetricsMap.putIfAbsent(resName,
- genMDbBuilder(Type.NETWORK, NETWORK_METRICS));
+ networkMetricsMap.putIfAbsent(resName, genMDbBuilder(resName,
+ Type.NETWORK, NETWORK_METRICS));
networkMetricsMap.get(resName).updateMetrics(convertMap(metricMap));
}
private void updateDiskMetrics(Map<ControlMetricType, Double> metricMap,
String resName) {
- diskMetricsMap.putIfAbsent(resName, genMDbBuilder(Type.DISK, DISK_METRICS));
+ diskMetricsMap.putIfAbsent(resName, genMDbBuilder(resName,
+ Type.DISK, DISK_METRICS));
diskMetricsMap.get(resName).updateMetrics(convertMap(metricMap));
}
private void updateControlMessages(Map<ControlMetricType, Double> metricMap,
DeviceId devId) {
- controlMessageMap.putIfAbsent(devId,
- genMDbBuilder(Type.CONTROL_MESSAGE, CONTROL_MESSAGE_METRICS));
+ controlMessageMap.putIfAbsent(devId, genMDbBuilder(devId.toString(),
+ Type.CONTROL_MESSAGE, CONTROL_MESSAGE_METRICS));
controlMessageMap.get(devId).updateMetrics(convertMap(metricMap));
}
diff --git a/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultMetricsDatabase.java b/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultMetricsDatabase.java
index 31a19da..fd88072 100644
--- a/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultMetricsDatabase.java
+++ b/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultMetricsDatabase.java
@@ -26,6 +26,8 @@
import org.rrd4j.core.RrdDb;
import org.rrd4j.core.RrdDef;
import org.rrd4j.core.Sample;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
@@ -43,7 +45,10 @@
* An implementation of control plane metrics back-end database.
*/
public final class DefaultMetricsDatabase implements MetricsDatabase {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
private String metricName;
+ private String resourceName;
private RrdDb rrdDb;
private Sample sample;
private static final long SECONDS_OF_DAY = 60L * 60L * 24L;
@@ -60,8 +65,9 @@
* @param metricName metric name
* @param rrdDb round robin database
*/
- private DefaultMetricsDatabase(String metricName, RrdDb rrdDb) {
+ private DefaultMetricsDatabase(String metricName, String resourceName, RrdDb rrdDb) {
this.metricName = metricName;
+ this.resourceName = resourceName;
this.rrdDb = rrdDb;
}
@@ -71,6 +77,11 @@
}
@Override
+ public String resourceName() {
+ return this.resourceName;
+ }
+
+ @Override
public void updateMetric(String metricType, double value) {
updateMetric(metricType, value, System.currentTimeMillis() / 1000L);
}
@@ -83,7 +94,7 @@
sample.setValue(metricType, value);
sample.update();
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Failed to update metric value due to {}", e.getMessage());
}
}
@@ -106,7 +117,7 @@
});
sample.update();
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Failed to update metric values due to {}", e.getMessage());
}
}
@@ -116,9 +127,9 @@
checkArgument(rrdDb.containsDs(metricType), NON_EXIST_METRIC);
return rrdDb.getDatasource(metricType).getLastValue();
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Failed to obtain metric value due to {}", e.getMessage());
+ return 0D;
}
- return 0D;
}
@Override
@@ -130,11 +141,14 @@
if (checkTimeRange(startTime, endTime)) {
FetchRequest fr = rrdDb.createFetchRequest(CONSOL_FUNCTION, startTime, endTime);
return arrangeDataPoints(fr.fetchData().getValues(metricType));
+ } else {
+ log.warn("Data projection is out-of-range");
+ return new double[0];
}
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Failed to obtain metric values due to {}", e.getMessage());
+ return new double[0];
}
- return new double[0];
}
@Override
@@ -145,9 +159,9 @@
long startTime = endTime - SECONDS_OF_DAY + 1;
return minMetric(metricType, startTime, endTime);
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Failed to obtain metric value due to {}", e.getMessage());
+ return 0D;
}
- return 0D;
}
@Override
@@ -158,9 +172,9 @@
long startTime = endTime - SECONDS_OF_DAY;
return maxMetric(metricType, startTime, endTime);
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Failed to obtain metric value due to {}", e.getMessage());
+ return 0D;
}
- return 0D;
}
@Override
@@ -171,9 +185,9 @@
long startTime = endTime - SECONDS_OF_DAY;
return metrics(metricType, startTime, endTime);
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Failed to obtain metric values due to {}", e.getMessage());
+ return new double[0];
}
- return new double[0];
}
@Override
@@ -183,22 +197,25 @@
if (checkTimeRange(startTime, endTime)) {
FetchRequest fr = rrdDb.createFetchRequest(CONSOL_FUNCTION, startTime, endTime);
return arrangeDataPoints(fr.fetchData().getValues(metricType));
+ } else {
+ log.warn("Data projection is out-of-range");
+ return new double[0];
}
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Failed to obtain metric values due to {}", e.getMessage());
+ return new double[0];
}
- return new double[0];
}
@Override
public long lastUpdate(String metricType) {
try {
checkArgument(rrdDb.containsDs(metricType), NON_EXIST_METRIC);
- rrdDb.getLastUpdateTime();
+ return rrdDb.getLastUpdateTime();
} catch (IOException e) {
- e.printStackTrace();
+ log.error("Failed to obtain last update time due to {}", e.getMessage());
+ return 0L;
}
- return 0L;
}
// try to check whether projected time range is within a day
@@ -242,12 +259,15 @@
private static final int STEP_VALUE = 1;
private static final int ROW_VALUE = 60 * 24;
private static final String METRIC_NAME_MSG = "Must specify a metric name.";
+ private static final String RESOURCE_NAME_MSG = "Must specify a resource name.";
private static final String METRIC_TYPE_MSG = "Must supply at least a metric type.";
+ private static final String SPLITTER = "_";
private RrdDb rrdDb;
private RrdDef rrdDef;
private List<DsDef> dsDefs;
private String metricName;
+ private String resourceName;
public Builder() {
// initialize data source definition list
@@ -255,11 +275,14 @@
}
@Override
- public Builder withMetricName(String metricName) {
- this.metricName = metricName;
+ public Builder withMetricName(String metric) {
+ this.metricName = metric;
+ return this;
+ }
- // define the resolution of monitored metrics
- rrdDef = new RrdDef(DB_PATH + "_" + metricName, RESOLUTION_IN_SECOND);
+ @Override
+ public MetricsDatabase.Builder withResourceName(String resource) {
+ this.resourceName = resource;
return this;
}
@@ -272,8 +295,13 @@
@Override
public MetricsDatabase build() {
checkNotNull(metricName, METRIC_NAME_MSG);
+ checkNotNull(resourceName, RESOURCE_NAME_MSG);
checkArgument(dsDefs.size() != 0, METRIC_TYPE_MSG);
+ // define the resolution of monitored metrics
+ rrdDef = new RrdDef(DB_PATH + SPLITTER + metricName +
+ SPLITTER + resourceName, RESOLUTION_IN_SECOND);
+
try {
DsDef[] dsDefArray = new DsDef[dsDefs.size()];
IntStream.range(0, dsDefs.size()).forEach(i -> dsDefArray[i] = dsDefs.get(i));
@@ -292,7 +320,7 @@
e.printStackTrace();
}
- return new DefaultMetricsDatabase(metricName, rrdDb);
+ return new DefaultMetricsDatabase(metricName, resourceName, rrdDb);
}
private DsDef defineSchema(String metricType) {
diff --git a/apps/cpman/app/src/test/java/org/onosproject/cpman/impl/MetricsDatabaseTest.java b/apps/cpman/app/src/test/java/org/onosproject/cpman/impl/MetricsDatabaseTest.java
index 713c7d8..75a2482 100644
--- a/apps/cpman/app/src/test/java/org/onosproject/cpman/impl/MetricsDatabaseTest.java
+++ b/apps/cpman/app/src/test/java/org/onosproject/cpman/impl/MetricsDatabaseTest.java
@@ -15,12 +15,18 @@
*/
package org.onosproject.cpman.impl;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
import org.junit.Before;
import org.junit.Test;
+import org.onosproject.cpman.ControlMetricType;
+import org.onosproject.cpman.ControlResource;
import org.onosproject.cpman.MetricsDatabase;
+import org.onosproject.net.DeviceId;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.Matchers.is;
@@ -34,9 +40,11 @@
private MetricsDatabase mdb;
private static final String CPU_METRIC = "cpu";
private static final String CPU_LOAD = "load";
+ private static final String DEFAULT_RES = "resource";
private static final String MEMORY_METRIC = "memory";
private static final String MEMORY_FREE_PERC = "freePerc";
private static final String MEMORY_USED_PERC = "usedPerc";
+ private Map<DeviceId, MetricsDatabase> devMetricsMap;
/**
* Initializes metrics database instance.
@@ -45,6 +53,7 @@
public void setUp() {
mdb = new DefaultMetricsDatabase.Builder()
.withMetricName(CPU_METRIC)
+ .withResourceName(DEFAULT_RES)
.addMetricType(CPU_LOAD)
.build();
}
@@ -114,6 +123,7 @@
public void testMultipleMetrics() {
MetricsDatabase multiMdb = new DefaultMetricsDatabase.Builder()
.withMetricName(MEMORY_METRIC)
+ .withResourceName(DEFAULT_RES)
.addMetricType(MEMORY_FREE_PERC)
.addMetricType(MEMORY_USED_PERC)
.build();
@@ -126,4 +136,51 @@
assertThat(30D, is(multiMdb.recentMetric(MEMORY_FREE_PERC)));
assertThat(70D, is(multiMdb.recentMetric(MEMORY_USED_PERC)));
}
+
+ /**
+ * Tests device metrics map update and query.
+ */
+ @Test
+ public void testDeviceMetricsMap() {
+ ControlResource.Type type = ControlResource.Type.CONTROL_MESSAGE;
+ DeviceId devId1 = DeviceId.deviceId("of:0000000000000101");
+ DeviceId devId2 = DeviceId.deviceId("of:0000000000000102");
+
+ devMetricsMap = Maps.newHashMap();
+
+ Set<DeviceId> devices = ImmutableSet.of(devId1, devId2);
+ devices.forEach(dev ->
+ devMetricsMap.putIfAbsent(dev,
+ genMDbBuilder(type, ControlResource.CONTROL_MESSAGE_METRICS)
+ .withResourceName(dev.toString())
+ .build()));
+
+ Map<String, Double> metrics1 = new HashMap<>();
+ ControlResource.CONTROL_MESSAGE_METRICS.forEach(msgType ->
+ metrics1.putIfAbsent(msgType.toString(), 10D));
+
+ Map<String, Double> metrics2 = new HashMap<>();
+ ControlResource.CONTROL_MESSAGE_METRICS.forEach(msgType ->
+ metrics2.putIfAbsent(msgType.toString(), 20D));
+
+
+ devMetricsMap.get(devId1).updateMetrics(metrics1);
+ devMetricsMap.get(devId2).updateMetrics(metrics2);
+
+ ControlResource.CONTROL_MESSAGE_METRICS.forEach(msgType ->
+ assertThat(10D, is(devMetricsMap.get(devId1).recentMetric(msgType.toString())))
+ );
+
+ ControlResource.CONTROL_MESSAGE_METRICS.forEach(msgType ->
+ assertThat(20D, is(devMetricsMap.get(devId2).recentMetric(msgType.toString())))
+ );
+ }
+
+ private MetricsDatabase.Builder genMDbBuilder(ControlResource.Type resourceType,
+ Set<ControlMetricType> metricTypes) {
+ MetricsDatabase.Builder builder = new DefaultMetricsDatabase.Builder();
+ builder.withMetricName(resourceType.toString());
+ metricTypes.forEach(type -> builder.addMetricType(type.toString()));
+ return builder;
+ }
}
diff --git a/providers/openflow/message/src/main/java/org/onosproject/provider/of/message/impl/OpenFlowControlMessageAggregator.java b/providers/openflow/message/src/main/java/org/onosproject/provider/of/message/impl/OpenFlowControlMessageAggregator.java
index cce9e0d..a0cacc8 100644
--- a/providers/openflow/message/src/main/java/org/onosproject/provider/of/message/impl/OpenFlowControlMessageAggregator.java
+++ b/providers/openflow/message/src/main/java/org/onosproject/provider/of/message/impl/OpenFlowControlMessageAggregator.java
@@ -141,7 +141,7 @@
* @return count value
*/
private long getCount(OFType type) {
- return (long) countMeterMap.get(type).getOneMinuteRate() *
- EXECUTE_PERIOD_IN_SECOND;
+ return (long) (countMeterMap.get(type).getOneMinuteRate()
+ * EXECUTE_PERIOD_IN_SECOND);
}
}