Thomas Vachuska

Fixing port stats rate calculation.

Change-Id: Ic4c803f58a53c293ae05bc0c207d7e23546f7158
...@@ -28,12 +28,12 @@ public class DefaultLoad implements Load { ...@@ -28,12 +28,12 @@ public class DefaultLoad implements Load {
28 private final long current; 28 private final long current;
29 private final long previous; 29 private final long previous;
30 private final long time; 30 private final long time;
31 - private final int interval; 31 + private final long interval;
32 32
33 /** 33 /**
34 * Indicates the flow statistics poll interval in seconds. 34 * Indicates the flow statistics poll interval in seconds.
35 */ 35 */
36 - private static int pollInterval = 10; 36 + private static long pollInterval = 10;
37 37
38 /** 38 /**
39 * Creates an invalid load. 39 * Creates an invalid load.
...@@ -63,7 +63,7 @@ public class DefaultLoad implements Load { ...@@ -63,7 +63,7 @@ public class DefaultLoad implements Load {
63 * @param previous the previous value 63 * @param previous the previous value
64 * @param interval poll interval for this load 64 * @param interval poll interval for this load
65 */ 65 */
66 - public DefaultLoad(long current, long previous, int interval) { 66 + public DefaultLoad(long current, long previous, long interval) {
67 checkArgument(interval > 0, "Interval must be greater than 0"); 67 checkArgument(interval > 0, "Interval must be greater than 0");
68 this.current = current; 68 this.current = current;
69 this.previous = previous; 69 this.previous = previous;
...@@ -78,7 +78,7 @@ public class DefaultLoad implements Load { ...@@ -78,7 +78,7 @@ public class DefaultLoad implements Load {
78 * 78 *
79 * @param newPollInterval poll interval duration in seconds 79 * @param newPollInterval poll interval duration in seconds
80 */ 80 */
81 - public static void setPollInterval(int newPollInterval) { 81 + public static void setPollInterval(long newPollInterval) {
82 pollInterval = newPollInterval; 82 pollInterval = newPollInterval;
83 } 83 }
84 84
......
...@@ -49,8 +49,8 @@ public class PortStatisticsManager implements PortStatisticsService { ...@@ -49,8 +49,8 @@ public class PortStatisticsManager implements PortStatisticsService {
49 49
50 private final Logger log = getLogger(getClass()); 50 private final Logger log = getLogger(getClass());
51 51
52 - private static final int SECOND = 1_000; // milliseconds 52 + private static final long POLL_FREQUENCY = 10_000; // milliseconds
53 - private static final long STALE_LIMIT = 15_000; // milliseconds 53 + private static final long STALE_LIMIT = (long) (1.5 * POLL_FREQUENCY);
54 54
55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 protected DeviceService deviceService; 56 protected DeviceService deviceService;
...@@ -77,11 +77,15 @@ public class PortStatisticsManager implements PortStatisticsService { ...@@ -77,11 +77,15 @@ public class PortStatisticsManager implements PortStatisticsService {
77 DataPoint c = current.get(connectPoint); 77 DataPoint c = current.get(connectPoint);
78 DataPoint p = previous.get(connectPoint); 78 DataPoint p = previous.get(connectPoint);
79 long now = System.currentTimeMillis(); 79 long now = System.currentTimeMillis();
80 - if (c != null && p != null && (now - c.time < STALE_LIMIT) && 80 +
81 - (c.time > p.time + SECOND) && 81 + if (c != null && p != null && (now - c.time < STALE_LIMIT)) {
82 - (c.stats.bytesSent() - p.stats.bytesSent() >= 0)) { 82 + if (c.stats.durationSec() > p.stats.durationSec() &&
83 - return new DefaultLoad(c.stats.bytesSent(), p.stats.bytesSent(), 83 + c.stats.bytesSent() >= p.stats.bytesSent() &&
84 - (int) (c.time - p.time) / SECOND); 84 + c.stats.durationSec() >= POLL_FREQUENCY / 1_000) {
85 + return new DefaultLoad(c.stats.bytesSent(), p.stats.bytesSent(),
86 + c.stats.durationSec() - p.stats.durationSec());
87 + }
88 + return new DefaultLoad(c.stats.bytesSent(), 0, c.stats.durationSec());
85 } 89 }
86 return null; 90 return null;
87 } 91 }
...@@ -114,15 +118,15 @@ public class PortStatisticsManager implements PortStatisticsService { ...@@ -114,15 +118,15 @@ public class PortStatisticsManager implements PortStatisticsService {
114 // Updates the port stats for the specified port 118 // Updates the port stats for the specified port
115 private void updatePortData(DeviceId deviceId, PortStatistics stats) { 119 private void updatePortData(DeviceId deviceId, PortStatistics stats) {
116 ConnectPoint cp = new ConnectPoint(deviceId, portNumber(stats.port())); 120 ConnectPoint cp = new ConnectPoint(deviceId, portNumber(stats.port()));
121 + DataPoint c = current.get(cp);
122 +
123 + // Create a new data point and make it the current one
124 + current.put(cp, new DataPoint(stats));
117 125
118 // If we have a current data point, demote it to previous 126 // If we have a current data point, demote it to previous
119 - DataPoint c = current.get(cp);
120 if (c != null) { 127 if (c != null) {
121 previous.put(cp, c); 128 previous.put(cp, c);
122 } 129 }
123 -
124 - // Create a new data point and make it the current one
125 - current.put(cp, new DataPoint(stats));
126 } 130 }
127 131
128 // Cleans all port loads for the specified device 132 // Cleans all port loads for the specified device
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
16 package org.onosproject.ui.impl; 16 package org.onosproject.ui.impl;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 -import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.fasterxml.jackson.databind.node.ArrayNode; 19 import com.fasterxml.jackson.databind.node.ArrayNode;
21 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
22 import com.google.common.collect.ImmutableList; 21 import com.google.common.collect.ImmutableList;
...@@ -90,6 +89,7 @@ import static com.google.common.base.Strings.isNullOrEmpty; ...@@ -90,6 +89,7 @@ import static com.google.common.base.Strings.isNullOrEmpty;
90 import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED; 89 import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED;
91 import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_REMOVED; 90 import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_REMOVED;
92 import static org.onosproject.cluster.ControllerNode.State.ACTIVE; 91 import static org.onosproject.cluster.ControllerNode.State.ACTIVE;
92 +import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
93 import static org.onosproject.net.DeviceId.deviceId; 93 import static org.onosproject.net.DeviceId.deviceId;
94 import static org.onosproject.net.HostId.hostId; 94 import static org.onosproject.net.HostId.hostId;
95 import static org.onosproject.net.LinkKey.linkKey; 95 import static org.onosproject.net.LinkKey.linkKey;
...@@ -101,7 +101,8 @@ import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED; ...@@ -101,7 +101,8 @@ import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
101 import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED; 101 import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
102 import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED; 102 import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
103 import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED; 103 import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED;
104 -import static org.onosproject.ui.impl.TopologyViewMessageHandlerBase.StatsType.*; 104 +import static org.onosproject.ui.impl.TopologyViewMessageHandlerBase.StatsType.FLOW;
105 +import static org.onosproject.ui.impl.TopologyViewMessageHandlerBase.StatsType.PORT;
105 106
106 /** 107 /**
107 * Facility for creating messages bound for the topology viewer. 108 * Facility for creating messages bound for the topology viewer.
...@@ -126,7 +127,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -126,7 +127,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
126 private static final String KB_UNIT = "KB"; 127 private static final String KB_UNIT = "KB";
127 private static final String B_UNIT = "B"; 128 private static final String B_UNIT = "B";
128 129
129 - private static final long BPS_THRESHOLD = 1024; 130 + private static final double BPS_THRESHOLD = 4 * KB;
130 131
131 protected ServiceDirectory directory; 132 protected ServiceDirectory directory;
132 protected ClusterService clusterService; 133 protected ClusterService clusterService;
...@@ -567,37 +568,49 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -567,37 +568,49 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
567 pathNodeT.set("labels", labelsT); 568 pathNodeT.set("labels", labelsT);
568 paths.add(pathNodeT); 569 paths.add(pathNodeT);
569 570
570 - for (BiLink link : consolidateLinks(linkService.getLinks())) { 571 + Map<LinkKey, BiLink> biLinks = consolidateLinks(linkService.getLinks());
572 + addEdgeLinks(biLinks);
573 + for (BiLink link : biLinks.values()) {
571 boolean bi = link.two != null; 574 boolean bi = link.two != null;
572 - if (isInfrastructureEgress(link.one) || 575 + if (type == FLOW) {
573 - (bi && isInfrastructureEgress(link.two))) { 576 + link.addLoad(getLinkLoad(link.one));
574 - if (type == FLOW) { 577 + link.addLoad(bi ? getLinkLoad(link.two) : null);
575 - link.addLoad(flowStatsService.load(link.one)); 578 + } else if (type == PORT) {
576 - link.addLoad(bi ? flowStatsService.load(link.two) : null); 579 + link.addLoad(portStatsService.load(link.one.src()), BPS_THRESHOLD);
577 - } else if (type == PORT) { 580 + link.addLoad(portStatsService.load(link.one.dst()), BPS_THRESHOLD);
578 - link.addLoad(portStatsService.load(link.one.src()), BPS_THRESHOLD); 581 + }
579 - link.addLoad(bi ? portStatsService.load(link.two.src()) : null, BPS_THRESHOLD); 582 + if (link.hasTraffic) {
580 - } 583 + linksNodeT.add(compactLinkString(link.one));
581 - if (link.hasTraffic) { 584 + labelsT.add(type == PORT ?
582 - linksNodeT.add(compactLinkString(link.one)); 585 + formatBytes(link.rate) + "ps" :
583 - labelsT.add(type == PORT ? 586 + formatBytes(link.bytes));
584 - formatBytes(link.rate) + "ps" : 587 + } else {
585 - formatBytes(link.bytes)); 588 + linksNodeN.add(compactLinkString(link.one));
586 - } else { 589 + labelsN.add("");
587 - linksNodeN.add(compactLinkString(link.one));
588 - labelsN.add("");
589 - }
590 } 590 }
591 } 591 }
592 return JsonUtils.envelope("showTraffic", 0, payload); 592 return JsonUtils.envelope("showTraffic", 0, payload);
593 } 593 }
594 594
595 - private Collection<BiLink> consolidateLinks(Iterable<Link> links) { 595 + private Load getLinkLoad(Link link) {
596 + if (link.src().elementId() instanceof DeviceId) {
597 + return flowStatsService.load(link);
598 + }
599 + return null;
600 + }
601 +
602 + private void addEdgeLinks(Map<LinkKey, BiLink> biLinks) {
603 + hostService.getHosts().forEach(host -> {
604 + addLink(biLinks, createEdgeLink(host.location(), false));
605 + });
606 + }
607 +
608 + private Map<LinkKey, BiLink> consolidateLinks(Iterable<Link> links) {
596 Map<LinkKey, BiLink> biLinks = new HashMap<>(); 609 Map<LinkKey, BiLink> biLinks = new HashMap<>();
597 for (Link link : links) { 610 for (Link link : links) {
598 addLink(biLinks, link); 611 addLink(biLinks, link);
599 } 612 }
600 - return biLinks.values(); 613 + return biLinks;
601 } 614 }
602 615
603 // Produces JSON message to trigger flow overview visualization 616 // Produces JSON message to trigger flow overview visualization
...@@ -680,7 +693,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -680,7 +693,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
680 ((LinkCollectionIntent) installable).links()); 693 ((LinkCollectionIntent) installable).links());
681 } else if (installable instanceof OpticalPathIntent) { 694 } else if (installable instanceof OpticalPathIntent) {
682 classifyLinks(type, biLinks, trafficClass.showTraffic, 695 classifyLinks(type, biLinks, trafficClass.showTraffic,
683 - ((OpticalPathIntent) installable).path().links()); 696 + ((OpticalPathIntent) installable).path().links());
684 } 697 }
685 } 698 }
686 } 699 }
...@@ -708,12 +721,10 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -708,12 +721,10 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
708 if (links != null) { 721 if (links != null) {
709 for (Link link : links) { 722 for (Link link : links) {
710 BiLink biLink = addLink(biLinks, link); 723 BiLink biLink = addLink(biLinks, link);
711 - if (isInfrastructureEgress(link)) { 724 + if (showTraffic) {
712 - if (showTraffic) { 725 + biLink.addLoad(flowStatsService.load(link));
713 - biLink.addLoad(flowStatsService.load(link));
714 - }
715 - biLink.addClass(type);
716 } 726 }
727 + biLink.addClass(type);
717 } 728 }
718 } 729 }
719 } 730 }
...@@ -731,37 +742,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -731,37 +742,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
731 return biLink; 742 return biLink;
732 } 743 }
733 744
734 -
735 - // Adds the link segments (path or tree) associated with the specified
736 - // connectivity intent
737 - protected void addPathTraffic(ArrayNode paths, String type, String trafficType,
738 - Iterable<Link> links) {
739 - ObjectNode pathNode = objectNode();
740 - ArrayNode linksNode = arrayNode();
741 -
742 - if (links != null) {
743 - ArrayNode labels = arrayNode();
744 - boolean hasTraffic = false;
745 - for (Link link : links) {
746 - if (isInfrastructureEgress(link)) {
747 - linksNode.add(compactLinkString(link));
748 - Load load = flowStatsService.load(link);
749 - String label = "";
750 - if (load.rate() > 0) {
751 - hasTraffic = true;
752 - label = formatBytes(load.latest());
753 - }
754 - labels.add(label);
755 - }
756 - }
757 - pathNode.put("class", hasTraffic ? type + " " + trafficType : type);
758 - pathNode.put("traffic", hasTraffic);
759 - pathNode.set("links", linksNode);
760 - pathNode.set("labels", labels);
761 - paths.add(pathNode);
762 - }
763 - }
764 -
765 // Poor-mans formatting to get the labels with byte counts looking nice. 745 // Poor-mans formatting to get the labels with byte counts looking nice.
766 private String formatBytes(long bytes) { 746 private String formatBytes(long bytes) {
767 // TODO: multiply everything by 8 to compute bits/second 747 // TODO: multiply everything by 8 to compute bits/second
...@@ -790,10 +770,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -790,10 +770,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
790 return format.format(number); 770 return format.format(number);
791 } 771 }
792 772
793 - private boolean isInfrastructureEgress(Link link) {
794 - return link.src().elementId() instanceof DeviceId;
795 - }
796 -
797 // Produces compact string representation of a link. 773 // Produces compact string representation of a link.
798 private static String compactLinkString(Link link) { 774 private static String compactLinkString(Link link) {
799 return String.format(COMPACT, link.src().elementId(), link.src().port(), 775 return String.format(COMPACT, link.src().elementId(), link.src().port(),
...@@ -802,7 +778,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -802,7 +778,6 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
802 778
803 // Produces JSON property details. 779 // Produces JSON property details.
804 private ObjectNode json(String id, String type, Prop... props) { 780 private ObjectNode json(String id, String type, Prop... props) {
805 - ObjectMapper mapper = new ObjectMapper();
806 ObjectNode result = objectNode() 781 ObjectNode result = objectNode()
807 .put("id", id).put("type", type); 782 .put("id", id).put("type", type);
808 ObjectNode pnode = objectNode(); 783 ObjectNode pnode = objectNode();
...@@ -848,7 +823,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -848,7 +823,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
848 addLoad(load, 0); 823 addLoad(load, 0);
849 } 824 }
850 825
851 - void addLoad(Load load, long threshold) { 826 + void addLoad(Load load, double threshold) {
852 if (load != null) { 827 if (load != null) {
853 this.hasTraffic = hasTraffic || load.rate() > threshold; 828 this.hasTraffic = hasTraffic || load.rate() > threshold;
854 this.bytes += load.latest(); 829 this.bytes += load.latest();
......