Fixing port stats rate calculation.
Change-Id: Ic4c803f58a53c293ae05bc0c207d7e23546f7158
diff --git a/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java b/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java
index 91af1f3..45e8537 100644
--- a/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java
+++ b/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java
@@ -28,12 +28,12 @@
private final long current;
private final long previous;
private final long time;
- private final int interval;
+ private final long interval;
/**
* Indicates the flow statistics poll interval in seconds.
*/
- private static int pollInterval = 10;
+ private static long pollInterval = 10;
/**
* Creates an invalid load.
@@ -63,7 +63,7 @@
* @param previous the previous value
* @param interval poll interval for this load
*/
- public DefaultLoad(long current, long previous, int interval) {
+ public DefaultLoad(long current, long previous, long interval) {
checkArgument(interval > 0, "Interval must be greater than 0");
this.current = current;
this.previous = previous;
@@ -78,7 +78,7 @@
*
* @param newPollInterval poll interval duration in seconds
*/
- public static void setPollInterval(int newPollInterval) {
+ public static void setPollInterval(long newPollInterval) {
pollInterval = newPollInterval;
}
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java
index ea2d2e3..be4915d 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/impl/PortStatisticsManager.java
@@ -49,8 +49,8 @@
private final Logger log = getLogger(getClass());
- private static final int SECOND = 1_000; // milliseconds
- private static final long STALE_LIMIT = 15_000; // milliseconds
+ private static final long POLL_FREQUENCY = 10_000; // milliseconds
+ private static final long STALE_LIMIT = (long) (1.5 * POLL_FREQUENCY);
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
@@ -77,11 +77,15 @@
DataPoint c = current.get(connectPoint);
DataPoint p = previous.get(connectPoint);
long now = System.currentTimeMillis();
- if (c != null && p != null && (now - c.time < STALE_LIMIT) &&
- (c.time > p.time + SECOND) &&
- (c.stats.bytesSent() - p.stats.bytesSent() >= 0)) {
- return new DefaultLoad(c.stats.bytesSent(), p.stats.bytesSent(),
- (int) (c.time - p.time) / SECOND);
+
+ if (c != null && p != null && (now - c.time < STALE_LIMIT)) {
+ if (c.stats.durationSec() > p.stats.durationSec() &&
+ c.stats.bytesSent() >= p.stats.bytesSent() &&
+ c.stats.durationSec() >= POLL_FREQUENCY / 1_000) {
+ return new DefaultLoad(c.stats.bytesSent(), p.stats.bytesSent(),
+ c.stats.durationSec() - p.stats.durationSec());
+ }
+ return new DefaultLoad(c.stats.bytesSent(), 0, c.stats.durationSec());
}
return null;
}
@@ -114,15 +118,15 @@
// Updates the port stats for the specified port
private void updatePortData(DeviceId deviceId, PortStatistics stats) {
ConnectPoint cp = new ConnectPoint(deviceId, portNumber(stats.port()));
-
- // If we have a current data point, demote it to previous
DataPoint c = current.get(cp);
- if (c != null) {
- previous.put(cp, c);
- }
// Create a new data point and make it the current one
current.put(cp, new DataPoint(stats));
+
+ // If we have a current data point, demote it to previous
+ if (c != null) {
+ previous.put(cp, c);
+ }
}
// Cleans all port loads for the specified device
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
index b006b1e..3ab7161 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
@@ -16,7 +16,6 @@
package org.onosproject.ui.impl;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableList;
@@ -90,6 +89,7 @@
import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED;
import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_REMOVED;
import static org.onosproject.cluster.ControllerNode.State.ACTIVE;
+import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.HostId.hostId;
import static org.onosproject.net.LinkKey.linkKey;
@@ -101,7 +101,8 @@
import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED;
-import static org.onosproject.ui.impl.TopologyViewMessageHandlerBase.StatsType.*;
+import static org.onosproject.ui.impl.TopologyViewMessageHandlerBase.StatsType.FLOW;
+import static org.onosproject.ui.impl.TopologyViewMessageHandlerBase.StatsType.PORT;
/**
* Facility for creating messages bound for the topology viewer.
@@ -126,7 +127,7 @@
private static final String KB_UNIT = "KB";
private static final String B_UNIT = "B";
- private static final long BPS_THRESHOLD = 1024;
+ private static final double BPS_THRESHOLD = 4 * KB;
protected ServiceDirectory directory;
protected ClusterService clusterService;
@@ -567,37 +568,49 @@
pathNodeT.set("labels", labelsT);
paths.add(pathNodeT);
- for (BiLink link : consolidateLinks(linkService.getLinks())) {
+ Map<LinkKey, BiLink> biLinks = consolidateLinks(linkService.getLinks());
+ addEdgeLinks(biLinks);
+ for (BiLink link : biLinks.values()) {
boolean bi = link.two != null;
- if (isInfrastructureEgress(link.one) ||
- (bi && isInfrastructureEgress(link.two))) {
- if (type == FLOW) {
- link.addLoad(flowStatsService.load(link.one));
- link.addLoad(bi ? flowStatsService.load(link.two) : null);
- } else if (type == PORT) {
- link.addLoad(portStatsService.load(link.one.src()), BPS_THRESHOLD);
- link.addLoad(bi ? portStatsService.load(link.two.src()) : null, BPS_THRESHOLD);
- }
- if (link.hasTraffic) {
- linksNodeT.add(compactLinkString(link.one));
- labelsT.add(type == PORT ?
- formatBytes(link.rate) + "ps" :
- formatBytes(link.bytes));
- } else {
- linksNodeN.add(compactLinkString(link.one));
- labelsN.add("");
- }
+ if (type == FLOW) {
+ link.addLoad(getLinkLoad(link.one));
+ link.addLoad(bi ? getLinkLoad(link.two) : null);
+ } else if (type == PORT) {
+ link.addLoad(portStatsService.load(link.one.src()), BPS_THRESHOLD);
+ link.addLoad(portStatsService.load(link.one.dst()), BPS_THRESHOLD);
+ }
+ if (link.hasTraffic) {
+ linksNodeT.add(compactLinkString(link.one));
+ labelsT.add(type == PORT ?
+ formatBytes(link.rate) + "ps" :
+ formatBytes(link.bytes));
+ } else {
+ linksNodeN.add(compactLinkString(link.one));
+ labelsN.add("");
}
}
return JsonUtils.envelope("showTraffic", 0, payload);
}
- private Collection<BiLink> consolidateLinks(Iterable<Link> links) {
+ private Load getLinkLoad(Link link) {
+ if (link.src().elementId() instanceof DeviceId) {
+ return flowStatsService.load(link);
+ }
+ return null;
+ }
+
+ private void addEdgeLinks(Map<LinkKey, BiLink> biLinks) {
+ hostService.getHosts().forEach(host -> {
+ addLink(biLinks, createEdgeLink(host.location(), false));
+ });
+ }
+
+ private Map<LinkKey, BiLink> consolidateLinks(Iterable<Link> links) {
Map<LinkKey, BiLink> biLinks = new HashMap<>();
for (Link link : links) {
addLink(biLinks, link);
}
- return biLinks.values();
+ return biLinks;
}
// Produces JSON message to trigger flow overview visualization
@@ -680,7 +693,7 @@
((LinkCollectionIntent) installable).links());
} else if (installable instanceof OpticalPathIntent) {
classifyLinks(type, biLinks, trafficClass.showTraffic,
- ((OpticalPathIntent) installable).path().links());
+ ((OpticalPathIntent) installable).path().links());
}
}
}
@@ -708,12 +721,10 @@
if (links != null) {
for (Link link : links) {
BiLink biLink = addLink(biLinks, link);
- if (isInfrastructureEgress(link)) {
- if (showTraffic) {
- biLink.addLoad(flowStatsService.load(link));
- }
- biLink.addClass(type);
+ if (showTraffic) {
+ biLink.addLoad(flowStatsService.load(link));
}
+ biLink.addClass(type);
}
}
}
@@ -731,37 +742,6 @@
return biLink;
}
-
- // Adds the link segments (path or tree) associated with the specified
- // connectivity intent
- protected void addPathTraffic(ArrayNode paths, String type, String trafficType,
- Iterable<Link> links) {
- ObjectNode pathNode = objectNode();
- ArrayNode linksNode = arrayNode();
-
- if (links != null) {
- ArrayNode labels = arrayNode();
- boolean hasTraffic = false;
- for (Link link : links) {
- if (isInfrastructureEgress(link)) {
- linksNode.add(compactLinkString(link));
- Load load = flowStatsService.load(link);
- String label = "";
- if (load.rate() > 0) {
- hasTraffic = true;
- label = formatBytes(load.latest());
- }
- labels.add(label);
- }
- }
- pathNode.put("class", hasTraffic ? type + " " + trafficType : type);
- pathNode.put("traffic", hasTraffic);
- pathNode.set("links", linksNode);
- pathNode.set("labels", labels);
- paths.add(pathNode);
- }
- }
-
// Poor-mans formatting to get the labels with byte counts looking nice.
private String formatBytes(long bytes) {
// TODO: multiply everything by 8 to compute bits/second
@@ -790,10 +770,6 @@
return format.format(number);
}
- private boolean isInfrastructureEgress(Link link) {
- return link.src().elementId() instanceof DeviceId;
- }
-
// Produces compact string representation of a link.
private static String compactLinkString(Link link) {
return String.format(COMPACT, link.src().elementId(), link.src().port(),
@@ -802,7 +778,6 @@
// Produces JSON property details.
private ObjectNode json(String id, String type, Prop... props) {
- ObjectMapper mapper = new ObjectMapper();
ObjectNode result = objectNode()
.put("id", id).put("type", type);
ObjectNode pnode = objectNode();
@@ -848,7 +823,7 @@
addLoad(load, 0);
}
- void addLoad(Load load, long threshold) {
+ void addLoad(Load load, double threshold) {
if (load != null) {
this.hasTraffic = hasTraffic || load.rate() > threshold;
this.bytes += load.latest();