[onos-6879] Adding configuration property to node metrics app
Change-Id: I64f7a42c44be7b61ec2db291ed90a02434844041
diff --git a/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeCpu.java b/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeCpuUsage.java
similarity index 91%
rename from apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeCpu.java
rename to apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeCpuUsage.java
index 87a79c0..7a88a2a 100644
--- a/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeCpu.java
+++ b/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeCpuUsage.java
@@ -25,11 +25,11 @@
/**
* Represents CPU usage info of Cluster controllers.
*/
-public final class NodeCpu {
+public final class NodeCpuUsage {
private final NodeId node;
private final double usage;
- private NodeCpu(final NodeId node, final Double usage) {
+ private NodeCpuUsage(final NodeId node, final Double usage) {
this.node = node;
this.usage = usage;
}
@@ -65,7 +65,7 @@
if (getClass() != obj.getClass()) {
return false;
}
- final NodeCpu other = (NodeCpu) obj;
+ final NodeCpuUsage other = (NodeCpuUsage) obj;
return Objects.equals(this.node, other.node)
&& Objects.equals(this.usage, other.usage);
}
@@ -102,10 +102,10 @@
return this;
}
- public NodeCpu build() {
+ public NodeCpuUsage build() {
checkNotNull(node, "Must specify an node id");
checkNotNull(usage, "Must specify a usage");
- return new NodeCpu(node, usage);
+ return new NodeCpuUsage(node, usage);
}
}
diff --git a/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeMemory.java b/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeMemoryUsage.java
similarity index 94%
rename from apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeMemory.java
rename to apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeMemoryUsage.java
index 399bc90..4531fe1 100644
--- a/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeMemory.java
+++ b/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeMemoryUsage.java
@@ -26,7 +26,7 @@
/**
* Represents Memory usage of Cluster controllers.
*/
-public final class NodeMemory {
+public final class NodeMemoryUsage {
private final NodeId node;
@@ -42,7 +42,7 @@
private static final double PERCENTAGE_MULTIPLIER = 100.0;
- private NodeMemory(final NodeId node, final Units units,
+ private NodeMemoryUsage(final NodeId node, final Units units,
final Long free, final Long used, final Long total,
final Double usage) {
this.node = node;
@@ -114,7 +114,7 @@
if (getClass() != obj.getClass()) {
return false;
}
- NodeMemory other = (NodeMemory) obj;
+ NodeMemoryUsage other = (NodeMemoryUsage) obj;
return Objects.equals(this.node, other.node)
&& Objects.equals(this.free, other.free)
&& Objects.equals(this.used, other.used)
@@ -191,14 +191,14 @@
return this;
}
- public NodeMemory build() {
+ public NodeMemoryUsage build() {
checkNotNull(node, "Must specify an node id");
checkNotNull(unit, "Must specify a unit");
checkNotNull(used, "Must specify a used Diskspace");
checkNotNull(free, "Must specify a free Diskspace");
checkNotNull(total, "Must specify a total Diskspace");
double usage = used * PERCENTAGE_MULTIPLIER / total;
- return new NodeMemory(node, unit, free, used, total, usage);
+ return new NodeMemoryUsage(node, unit, free, used, total, usage);
}
}
diff --git a/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeMetricsService.java b/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeMetricsService.java
index 1228fb0..4ad0985 100644
--- a/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeMetricsService.java
+++ b/apps/nodemetrics/api/src/main/java/org/onosproject/nodemetrics/NodeMetricsService.java
@@ -30,7 +30,7 @@
* Returns may memory information of all Cluster nodes.
* @return map
*/
- Map<NodeId, NodeMemory> memory();
+ Map<NodeId, NodeMemoryUsage> memory();
/**
* Returns may disk information of all Cluster nodes.
@@ -42,14 +42,14 @@
* Returns may CPU information of all Cluster nodes.
* @return map object, NodeId as key and NodeCpu information as value.
*/
- Map<NodeId, NodeCpu> cpu();
+ Map<NodeId, NodeCpuUsage> cpu();
/**
* Get the memory information of Specific Cluster node.
* @param nodeid to get Memory information of that respective cluster node.
- * @return Nodememory object.
+ * @return NodememoryUsage object.
*/
- NodeMemory memory(NodeId nodeid);
+ NodeMemoryUsage memory(NodeId nodeid);
/**
* Get the disk information of Specific Cluster node.
@@ -61,7 +61,7 @@
/**
* Get the CPU information of Specific Cluster node.
* @param nodeid to get CPU information of that respective cluster node.
- * @return NodeCpu object.
+ * @return NodeCpuUsage object.
*/
- NodeCpu cpu(NodeId nodeid);
+ NodeCpuUsage cpu(NodeId nodeid);
}
diff --git a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeCpuUsageCommand.java b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeCpuUsageCommand.java
index a122791..12dd649 100644
--- a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeCpuUsageCommand.java
+++ b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeCpuUsageCommand.java
@@ -20,7 +20,7 @@
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cluster.NodeId;
-import org.onosproject.nodemetrics.NodeCpu;
+import org.onosproject.nodemetrics.NodeCpuUsage;
import org.onosproject.nodemetrics.NodeMetricsService;
import java.util.Collection;
@@ -42,19 +42,19 @@
@Override
protected void execute() {
if (nodeId != null) {
- NodeCpu cpu = nodeService.cpu(NodeId.nodeId(nodeId));
+ NodeCpuUsage cpu = nodeService.cpu(NodeId.nodeId(nodeId));
if (Objects.nonNull(cpu)) {
print("CPU usage : %s ", cpu);
} else {
print("Node %s doesn't exists", nodeId);
}
} else {
- Collection<NodeCpu> cpu = nodeService.cpu().values();
+ Collection<NodeCpuUsage> cpu = nodeService.cpu().values();
printCpuUsage(cpu);
}
}
- private void printCpuUsage(Collection<NodeCpu> cpuList) {
+ private void printCpuUsage(Collection<NodeCpuUsage> cpuList) {
cpuList.forEach(cpu -> print("%s", cpu));
}
}
diff --git a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryCommand.java b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryUsageCommand.java
similarity index 81%
rename from apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryCommand.java
rename to apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryUsageCommand.java
index 3c6ec5b..2f18c43 100644
--- a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryCommand.java
+++ b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/cli/ShowNodeMemoryUsageCommand.java
@@ -20,7 +20,7 @@
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cluster.NodeId;
-import org.onosproject.nodemetrics.NodeMemory;
+import org.onosproject.nodemetrics.NodeMemoryUsage;
import org.onosproject.nodemetrics.NodeMetricsService;
import java.util.Collection;
@@ -31,7 +31,7 @@
*/
@Command(scope = "onos", name = "node-memory",
description = "Lists all node memory utilization")
-public class ShowNodeMemoryCommand extends AbstractShellCommand {
+public class ShowNodeMemoryUsageCommand extends AbstractShellCommand {
@Argument(index = 0, name = "nodeId", description = "Node identity",
required = false, multiValued = false)
@@ -42,19 +42,19 @@
@Override
protected void execute() {
if (nodeId != null) {
- NodeMemory memory = nodeService.memory(NodeId.nodeId(nodeId));
+ NodeMemoryUsage memory = nodeService.memory(NodeId.nodeId(nodeId));
if (Objects.nonNull(memory)) {
print("Memory usage : %s", memory.toString());
} else {
print("Node %s doesn't exists");
}
} else {
- Collection<NodeMemory> memory = nodeService.memory().values();
- printMemory(memory);
+ Collection<NodeMemoryUsage> memory = nodeService.memory().values();
+ printMemoryUsage(memory);
}
}
- private void printMemory(Collection<NodeMemory> memoryList) {
+ private void printMemoryUsage(Collection<NodeMemoryUsage> memoryList) {
memoryList.forEach(memory -> print("%s", memory));
}
}
diff --git a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/impl/NodeMetricsManager.java b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/impl/NodeMetricsManager.java
index c91f9d8..812ebb7 100644
--- a/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/impl/NodeMetricsManager.java
+++ b/apps/nodemetrics/mgr/src/main/java/org/onosproject/nodemetrics/impl/NodeMetricsManager.java
@@ -18,9 +18,13 @@
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.osgi.service.component.ComponentContext;
+import org.onosproject.cfg.ComponentConfigService;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.FileSystemUsage;
import org.hyperic.sigar.Mem;
@@ -32,9 +36,9 @@
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
-import org.onosproject.nodemetrics.NodeCpu;
+import org.onosproject.nodemetrics.NodeCpuUsage;
import org.onosproject.nodemetrics.NodeDiskUsage;
-import org.onosproject.nodemetrics.NodeMemory;
+import org.onosproject.nodemetrics.NodeMemoryUsage;
import org.onosproject.nodemetrics.NodeMetricsService;
import org.onosproject.nodemetrics.Units;
import org.onosproject.store.serializers.KryoNamespaces;
@@ -45,11 +49,15 @@
import org.slf4j.LoggerFactory;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
+import java.util.Dictionary;
+import static org.onlab.util.Tools.getIntegerProperty;
+
@Service
@Component(immediate = true)
@@ -72,22 +80,30 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LogicalClockService clockService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ComponentConfigService cfgService;
+
private ScheduledExecutorService metricsExecutor;
private ScheduledFuture<?> scheduledTask;
private ApplicationId appId;
private NodeId localNodeId;
- private EventuallyConsistentMap<NodeId, NodeMemory> memoryStore;
+ private EventuallyConsistentMap<NodeId, NodeMemoryUsage> memoryStore;
private EventuallyConsistentMap<NodeId, NodeDiskUsage> diskStore;
- private EventuallyConsistentMap<NodeId, NodeCpu> cpuStore;
+ private EventuallyConsistentMap<NodeId, NodeCpuUsage> cpuStore;
private Sigar sigar;
+ @Property(name = "metricPollFrequencySeconds", intValue = DEFAULT_POLL_FREQUENCY_SECONDS,
+ label = "Frequency (in seconds) for polling controller metrics")
+ protected int metricPollFrequencySeconds = DEFAULT_POLL_FREQUENCY_SECONDS;
+
@Activate
- public void activate() {
+ public void activate(ComponentContext context) {
appId = coreService
.registerApplication("org.onosproject.nodemetrics");
+ cfgService.registerProperties(getClass());
metricsExecutor = Executors.newSingleThreadScheduledExecutor(
Tools.groupedThreads("nodemetrics/pollingStatics",
"statistics-executor-%d", log));
@@ -95,11 +111,11 @@
localNodeId = clusterService.getLocalNode().id();
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
.register(KryoNamespaces.API)
- .register(NodeMemory.class)
+ .register(NodeMemoryUsage.class)
.register(NodeDiskUsage.class)
- .register(NodeCpu.class)
+ .register(NodeCpuUsage.class)
.register(Units.class);
- memoryStore = storageService.<NodeId, NodeMemory>eventuallyConsistentMapBuilder()
+ memoryStore = storageService.<NodeId, NodeMemoryUsage>eventuallyConsistentMapBuilder()
.withSerializer(serializer)
.withTimestampProvider((nodeId, memory) -> clockService.getTimestamp())
.withName("nodemetrics-memory")
@@ -111,26 +127,50 @@
.withName("nodemetrics-disk")
.build();
- cpuStore = storageService.<NodeId, NodeCpu>eventuallyConsistentMapBuilder()
+ cpuStore = storageService.<NodeId, NodeCpuUsage>eventuallyConsistentMapBuilder()
.withSerializer(serializer)
.withTimestampProvider((nodeId, cpu) -> clockService.getTimestamp())
.withName("nodemetrics-cpu")
.build();
-
- scheduledTask = schedulePolling();
+ modified(context);
sigar = new Sigar();
pollMetrics();
}
@Deactivate
public void deactivate() {
+ cfgService.unregisterProperties(getClass(), false);
scheduledTask.cancel(true);
metricsExecutor.shutdown();
sigar.close();
}
+ @Modified
+ public void modified(ComponentContext context) {
+ if (context == null) {
+ log.info("No component configuration");
+ return;
+ }
+
+ Dictionary<?, ?> properties = context.getProperties();
+ int newPollFrequency = getNewPollFrequency(properties);
+ //First time call to this modified method is when app activates
+ if (Objects.isNull(scheduledTask)) {
+ metricPollFrequencySeconds = newPollFrequency;
+ scheduledTask = schedulePolling();
+ } else {
+ if (newPollFrequency != metricPollFrequencySeconds) {
+ metricPollFrequencySeconds = newPollFrequency;
+ //stops the old scheduled task
+ scheduledTask.cancel(true);
+ //schedules new task at the new polling rate
+ scheduledTask = schedulePolling();
+ }
+ }
+ }
+
@Override
- public Map<NodeId, NodeMemory> memory() {
+ public Map<NodeId, NodeMemoryUsage> memory() {
return this.ecToMap(memoryStore);
}
@@ -140,12 +180,12 @@
}
@Override
- public Map<NodeId, NodeCpu> cpu() {
+ public Map<NodeId, NodeCpuUsage> cpu() {
return this.ecToMap(cpuStore);
}
@Override
- public NodeMemory memory(NodeId nodeid) {
+ public NodeMemoryUsage memory(NodeId nodeid) {
return memoryStore.get(nodeid);
}
@@ -155,14 +195,26 @@
}
@Override
- public NodeCpu cpu(NodeId nodeid) {
+ public NodeCpuUsage cpu(NodeId nodeid) {
return cpuStore.get(nodeid);
}
private ScheduledFuture schedulePolling() {
return metricsExecutor.scheduleAtFixedRate(this::pollMetrics,
- DEFAULT_POLL_FREQUENCY_SECONDS / 4,
- DEFAULT_POLL_FREQUENCY_SECONDS, TimeUnit.SECONDS);
+ metricPollFrequencySeconds / 4,
+ metricPollFrequencySeconds, TimeUnit.SECONDS);
+ }
+
+ private int getNewPollFrequency(Dictionary<?, ?> properties) {
+ int newPollFrequency;
+ try {
+ newPollFrequency = getIntegerProperty(properties, "metricPollFrequencySeconds");
+ //String s = getIntegerProperty(properties, "metricPollFrequencySeconds");
+ //newPollFrequency = isNullOrEmpty(s) ? pollFrequency : Integer.parseInt(s.trim());
+ } catch (NumberFormatException | ClassCastException e) {
+ newPollFrequency = DEFAULT_POLL_FREQUENCY_SECONDS;
+ }
+ return newPollFrequency;
}
private <K, V> Map<K, V> ecToMap(EventuallyConsistentMap<K, V> ecMap) {
@@ -170,16 +222,17 @@
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
+
private void pollMetrics() {
try {
CpuPerc cpu = sigar.getCpuPerc();
Mem mem = sigar.getMem();
FileSystemUsage disk = sigar.getFileSystemUsage(SLASH);
- NodeMemory memoryNode = new NodeMemory.Builder().free(mem.getFree())
+ NodeMemoryUsage memoryNode = new NodeMemoryUsage.Builder().free(mem.getFree())
.used(mem.getUsed()).total(mem.getTotal()).withUnit(Units.BYTES)
.withNode(localNodeId).build();
- NodeCpu cpuNode = new NodeCpu.Builder().withNode(localNodeId)
+ NodeCpuUsage cpuNode = new NodeCpuUsage.Builder().withNode(localNodeId)
.usage(cpu.getCombined() * PERCENTAGE_MULTIPLIER).build();
NodeDiskUsage diskNode = new NodeDiskUsage.Builder().withNode(localNodeId)
.free(disk.getFree()).used(disk.getUsed()).withUnit(Units.KBYTES)