Refactored Traffic Monitor code to display packets / second.
- cleaned up "rate thresholds" for coloring links.
- added unit tests for TopoUtils.
- "Monitor All Traffic" button on toolbar now cycles between 3 modes.
Change-Id: If33cfb3e6d6190e1321752b6d058274d3004f309
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
index 85d5eec..e20216d 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
@@ -53,10 +53,10 @@
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentEvent;
import org.onosproject.net.intent.IntentListener;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MultiPointToSinglePointIntent;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.link.LinkListener;
import org.onosproject.ui.JsonUtils;
@@ -111,8 +111,7 @@
private static final String REQ_PREV_INTENT = "requestPrevRelatedIntent";
private static final String REQ_SEL_INTENT_TRAFFIC = "requestSelectedIntentTraffic";
private static final String SEL_INTENT = "selectIntent";
- private static final String REQ_ALL_FLOW_TRAFFIC = "requestAllFlowTraffic";
- private static final String REQ_ALL_PORT_TRAFFIC = "requestAllPortTraffic";
+ private static final String REQ_ALL_TRAFFIC = "requestAllTraffic";
private static final String REQ_DEV_LINK_FLOWS = "requestDeviceLinkFlows";
private static final String CANCEL_TRAFFIC = "cancelTraffic";
private static final String REQ_SUMMARY = "requestSummary";
@@ -123,8 +122,6 @@
private static final String TOPO_START = "topoStart";
private static final String TOPO_SELECT_OVERLAY = "topoSelectOverlay";
private static final String TOPO_STOP = "topoStop";
-
- //Protected Intents events
private static final String SEL_PROTECTED_INTENT = "selectProtectedIntent";
private static final String CANCEL_PROTECTED_INTENT_HIGHLIGHT = "cancelProtectedIntentHighlight";
@@ -157,7 +154,12 @@
private static final String ACTIVATE = "activate";
private static final String DEACTIVATE = "deactivate";
private static final String PURGE = "purge";
+ private static final String TRAFFIC_TYPE = "trafficType";
+ // field values
+ private static final String FLOW_STATS_BYTES = "flowStatsBytes";
+ private static final String PORT_STATS_BIT_SEC = "portStatsBitSec";
+ private static final String PORT_STATS_PKT_SEC = "portStatsPktSec";
private static final String MY_APP_ID = "org.onosproject.gui";
@@ -234,8 +236,7 @@
new ResubmitIntent(),
new RemoveIntents(),
- new ReqAllFlowTraffic(),
- new ReqAllPortTraffic(),
+ new ReqAllTraffic(),
new ReqDevLinkFlows(),
new ReqRelatedIntents(),
new ReqNextIntent(),
@@ -560,25 +561,28 @@
// ========= -----------------------------------------------------------------
- private final class ReqAllFlowTraffic extends RequestHandler {
- private ReqAllFlowTraffic() {
- super(REQ_ALL_FLOW_TRAFFIC);
+ private final class ReqAllTraffic extends RequestHandler {
+ private ReqAllTraffic() {
+ super(REQ_ALL_TRAFFIC);
}
@Override
public void process(ObjectNode payload) {
- traffic.monitor(Mode.ALL_FLOW_TRAFFIC);
- }
- }
+ String trafficType = string(payload, TRAFFIC_TYPE, FLOW_STATS_BYTES);
- private final class ReqAllPortTraffic extends RequestHandler {
- private ReqAllPortTraffic() {
- super(REQ_ALL_PORT_TRAFFIC);
- }
-
- @Override
- public void process(ObjectNode payload) {
- traffic.monitor(Mode.ALL_PORT_TRAFFIC);
+ switch (trafficType) {
+ case FLOW_STATS_BYTES:
+ traffic.monitor(Mode.ALL_FLOW_TRAFFIC_BYTES);
+ break;
+ case PORT_STATS_BIT_SEC:
+ traffic.monitor(Mode.ALL_PORT_TRAFFIC_BIT_PS);
+ break;
+ case PORT_STATS_PKT_SEC:
+ traffic.monitor(Mode.ALL_PORT_TRAFFIC_PKT_PS);
+ break;
+ default:
+ break;
+ }
}
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java b/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java
index d324cc8..5cf5765 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TrafficMonitor.java
@@ -79,7 +79,7 @@
public class TrafficMonitor extends AbstractTopoMonitor {
// 4 Kilo Bytes as threshold
- private static final double BPS_THRESHOLD = 4 * TopoUtils.KILO;
+ private static final double BPS_THRESHOLD = 4 * TopoUtils.N_KILO;
private static final Logger log =
LoggerFactory.getLogger(TrafficMonitor.class);
@@ -89,8 +89,9 @@
*/
public enum Mode {
IDLE,
- ALL_FLOW_TRAFFIC,
- ALL_PORT_TRAFFIC,
+ ALL_FLOW_TRAFFIC_BYTES,
+ ALL_PORT_TRAFFIC_BIT_PS,
+ ALL_PORT_TRAFFIC_PKT_PS,
DEV_LINK_FLOWS,
RELATED_INTENTS,
SELECTED_INTENT
@@ -136,8 +137,9 @@
* <p>
* The monitoring mode is expected to be one of:
* <ul>
- * <li>ALL_FLOW_TRAFFIC</li>
- * <li>ALL_PORT_TRAFFIC</li>
+ * <li>ALL_FLOW_TRAFFIC_BYTES</li>
+ * <li>ALL_PORT_TRAFFIC_BIT_PS</li>
+ * <li>ALL_PORT_TRAFFIC_PKT_PS</li>
* <li>SELECTED_INTENT</li>
* </ul>
*
@@ -148,16 +150,22 @@
this.mode = mode;
switch (mode) {
- case ALL_FLOW_TRAFFIC:
+ case ALL_FLOW_TRAFFIC_BYTES:
clearSelection();
scheduleTask();
sendAllFlowTraffic();
break;
- case ALL_PORT_TRAFFIC:
+ case ALL_PORT_TRAFFIC_BIT_PS:
clearSelection();
scheduleTask();
- sendAllPortTraffic();
+ sendAllPortTraffic(StatsType.PORT_STATS);
+ break;
+
+ case ALL_PORT_TRAFFIC_PKT_PS:
+ clearSelection();
+ scheduleTask();
+ sendAllPortTraffic(StatsType.PORT_PACKET_STATS);
break;
case SELECTED_INTENT:
@@ -334,9 +342,9 @@
msgHandler.sendHighlights(trafficSummary(StatsType.FLOW_STATS));
}
- private void sendAllPortTraffic() {
- log.debug("sendAllPortTraffic");
- msgHandler.sendHighlights(trafficSummary(StatsType.PORT_STATS));
+ private void sendAllPortTraffic(StatsType t) {
+ log.debug("sendAllPortTraffic: {}", t);
+ msgHandler.sendHighlights(trafficSummary(t));
}
private void sendDeviceLinkFlows() {
@@ -494,7 +502,6 @@
Load egressSrc = servicesBundle.portStatsService().load(one.src(), metricType);
Load egressDst = servicesBundle.portStatsService().load(one.dst(), metricType);
link.addLoad(maxLoad(egressSrc, egressDst), metricType == BYTES ? BPS_THRESHOLD : 0);
-// link.addLoad(maxLoad(egressSrc, egressDst), 10); // DEBUG ONLY!!
}
private Load maxLoad(Load a, Load b) {
@@ -669,11 +676,14 @@
public void run() {
try {
switch (mode) {
- case ALL_FLOW_TRAFFIC:
+ case ALL_FLOW_TRAFFIC_BYTES:
sendAllFlowTraffic();
break;
- case ALL_PORT_TRAFFIC:
- sendAllPortTraffic();
+ case ALL_PORT_TRAFFIC_BIT_PS:
+ sendAllPortTraffic(StatsType.PORT_STATS);
+ break;
+ case ALL_PORT_TRAFFIC_PKT_PS:
+ sendAllPortTraffic(StatsType.PORT_PACKET_STATS);
break;
case DEV_LINK_FLOWS:
sendDeviceLinkFlows();
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TrafficLink.java b/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TrafficLink.java
index 570fed4..3075acd 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TrafficLink.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/topo/util/TrafficLink.java
@@ -23,12 +23,19 @@
import org.onosproject.ui.topo.LinkHighlight;
import org.onosproject.ui.topo.LinkHighlight.Flavor;
import org.onosproject.ui.topo.Mod;
-import org.onosproject.ui.topo.TopoUtils;
+import org.onosproject.ui.topo.TopoUtils.Magnitude;
+import org.onosproject.ui.topo.TopoUtils.ValueLabel;
import java.util.HashSet;
import java.util.Set;
-import static org.onosproject.ui.topo.LinkHighlight.Flavor.*;
+import static org.onosproject.ui.topo.LinkHighlight.Flavor.NO_HIGHLIGHT;
+import static org.onosproject.ui.topo.LinkHighlight.Flavor.PRIMARY_HIGHLIGHT;
+import static org.onosproject.ui.topo.LinkHighlight.Flavor.SECONDARY_HIGHLIGHT;
+import static org.onosproject.ui.topo.TopoUtils.formatBytes;
+import static org.onosproject.ui.topo.TopoUtils.formatClippedBitRate;
+import static org.onosproject.ui.topo.TopoUtils.formatFlows;
+import static org.onosproject.ui.topo.TopoUtils.formatPacketRate;
/**
* Representation of a link and its inverse, and associated traffic data.
@@ -36,9 +43,12 @@
* {@link LinkHighlight}s for showing traffic data on the topology view.
*/
public class TrafficLink extends BiLink {
+ private static final Mod PORT_TRAFFIC_GREEN = new Mod("port-traffic-green");
+ private static final Mod PORT_TRAFFIC_YELLOW = new Mod("port-traffic-yellow");
+ private static final Mod PORT_TRAFFIC_ORANGE = new Mod("port-traffic-orange");
+ private static final Mod PORT_TRAFFIC_RED = new Mod("port-traffic-red");
private static final String EMPTY = "";
- private static final String QUE = "?";
private long bytes = 0;
private long rate = 0;
@@ -88,7 +98,7 @@
* @return self, for chaining
*/
public TrafficLink tagFlavor(Flavor flavor) {
- this.taggedFlavor = flavor;
+ taggedFlavor = flavor;
return this;
}
@@ -144,14 +154,15 @@
StatsType statsType = (StatsType) type;
switch (statsType) {
case FLOW_COUNT:
- return highlightForFlowCount(statsType);
+ return highlightForFlowCount();
case FLOW_STATS:
case PORT_STATS:
+ case PORT_PACKET_STATS:
return highlightForStats(statsType);
case TAGGED:
- return highlightForTagging(statsType);
+ return highlightForTagging();
default:
throw new IllegalStateException("unexpected case: " + statsType);
@@ -159,60 +170,83 @@
}
private LinkHighlight highlightForStats(StatsType type) {
- LinkHighlight hlite = new LinkHighlight(linkId(), SECONDARY_HIGHLIGHT)
- .setLabel(generateLabel(type));
- if (!mods.isEmpty()) {
- mods.forEach(hlite::addMod);
+ ValueLabel vl = null;
+ Mod m = null;
+
+ // based on the type of stats, need to determine the label and "color"...
+ switch (type) {
+ case FLOW_STATS:
+ vl = formatBytes(bytes);
+ // default to "secondary highlighting" of link
+ break;
+
+ case PORT_STATS:
+ vl = formatClippedBitRate(rate);
+
+ // set color based on bits per second...
+ if (vl.magnitude() == Magnitude.ONE ||
+ vl.magnitude() == Magnitude.KILO) {
+ m = PORT_TRAFFIC_GREEN;
+
+ } else if (vl.magnitude() == Magnitude.MEGA) {
+ m = PORT_TRAFFIC_YELLOW;
+
+ } else if (vl.magnitude() == Magnitude.GIGA) {
+ m = vl.clipped() ? PORT_TRAFFIC_RED : PORT_TRAFFIC_ORANGE;
+ }
+ break;
+
+ case PORT_PACKET_STATS:
+ vl = formatPacketRate(rate);
+
+ // TODO: need to decide color threshold parameters for packets
+ // for now, we'll just default to "green"
+ m = PORT_TRAFFIC_GREEN;
+ break;
+
+ default:
+ break;
}
- return hlite;
+
+ LinkHighlight hlite = new LinkHighlight(linkId(), SECONDARY_HIGHLIGHT);
+ if (vl != null) {
+ hlite.setLabel(vl.toString());
+ }
+ if (m != null) {
+ hlite.addMod(m);
+ }
+
+ return addCustomMods(hlite);
}
- private LinkHighlight highlightForFlowCount(StatsType type) {
+ private LinkHighlight highlightForFlowCount() {
Flavor flavor = flows > 0 ? PRIMARY_HIGHLIGHT : SECONDARY_HIGHLIGHT;
LinkHighlight hlite = new LinkHighlight(linkId(), flavor)
- .setLabel(generateLabel(type));
- if (!mods.isEmpty()) {
- mods.forEach(hlite::addMod);
- }
- return hlite;
+ .setLabel(formatFlows(flows));
+ return addCustomMods(hlite);
}
- private LinkHighlight highlightForTagging(StatsType type) {
+ private LinkHighlight highlightForTagging() {
LinkHighlight hlite = new LinkHighlight(linkId(), taggedFlavor)
- .setLabel(generateLabel(type));
+ .setLabel(hasTraffic ? formatBytes(bytes).toString() : EMPTY);
+
if (isOptical) {
hlite.addMod(LinkHighlight.MOD_OPTICAL);
}
if (antMarch) {
hlite.addMod(LinkHighlight.MOD_ANIMATED);
}
+ return addCustomMods(hlite);
+ }
+
+ private LinkHighlight addCustomMods(LinkHighlight hlite) {
if (!mods.isEmpty()) {
mods.forEach(hlite::addMod);
}
return hlite;
}
- // Generates a string representation of the load, to be used as a label
- private String generateLabel(StatsType type) {
- switch (type) {
- case FLOW_COUNT:
- return TopoUtils.formatFlows(flows);
-
- case FLOW_STATS:
- return TopoUtils.formatBytes(bytes);
-
- case PORT_STATS:
- return TopoUtils.formatBitRate(rate);
-
- case TAGGED:
- return hasTraffic ? TopoUtils.formatBytes(bytes) : EMPTY;
-
- default:
- return QUE;
- }
- }
-
/**
* Returns true if this link has been deemed to have enough traffic
* to register on the topology view in the web UI.
diff --git a/web/gui/src/main/webapp/app/view/topo/topo-theme.css b/web/gui/src/main/webapp/app/view/topo/topo-theme.css
index 768c506..8f48766 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo-theme.css
+++ b/web/gui/src/main/webapp/app/view/topo/topo-theme.css
@@ -267,24 +267,37 @@
stroke: rgba(0,153,51,0.5);
}
-/* Port traffic color visualization for Kbps, Mbps, and Gbps */
+/* Port traffic color visualization:
-#ov-topo svg .link.secondary.port-traffic-Kbps {
+ For bits per second we will use:
+ - green for Kbps,
+ - yellow for Mbps,
+ - orange for Gbps, and
+ - red for > 10 Gbps
+
+ For packets per second we will use:
+ - green for > 0
+ - yellow for > ?
+ - orange for > ??
+ - red for > ???
+*/
+
+#ov-topo svg .link.secondary.port-traffic-green {
stroke: rgb(0,153,51);
stroke-width: 5.0;
}
-#ov-topo svg .link.secondary.port-traffic-Mbps {
+#ov-topo svg .link.secondary.port-traffic-yellow {
stroke: rgb(128,145,27);
stroke-width: 6.5;
}
-#ov-topo svg .link.secondary.port-traffic-Gbps {
+#ov-topo svg .link.secondary.port-traffic-orange {
stroke: rgb(255, 137, 3);
stroke-width: 8.0;
}
-#ov-topo svg .link.secondary.port-traffic-Gbps-choked {
+#ov-topo svg .link.secondary.port-traffic-red {
stroke: rgb(183, 30, 21);
stroke-width: 8.0;
}
diff --git a/web/gui/src/main/webapp/app/view/topo/topoForce.js b/web/gui/src/main/webapp/app/view/topo/topoForce.js
index 03d8477..0808271 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoForce.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoForce.js
@@ -898,8 +898,8 @@
// TODO: find an automatic way of tracking via the "showHighlights" events
var allTrafficClasses = 'primary secondary optical animated ' +
- 'port-traffic-Kbps port-traffic-Mbps port-traffic-Gbps ' +
- 'port-traffic-Gbps-choked';
+ 'port-traffic-green port-traffic-yellow port-traffic-orange ' +
+ 'port-traffic-red';
function clearLinkTrafficStyle() {
link.style('stroke-width', null)
diff --git a/web/gui/src/main/webapp/app/view/topo/topoTraffic.js b/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
index 2db9275..11a4dba 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
@@ -32,9 +32,22 @@
selectOrder()
*/
+ var allTrafficTypes = [
+ 'flowStatsBytes',
+ 'portStatsBitSec',
+ 'portStatsPktSec'
+ ],
+ allTrafficMsgs = [
+ 'Flow Stats (bytes)',
+ 'Port Stats (bits / second)',
+ 'Port Stats (packets / second)'
+ ];
+
// internal state
var trafficMode = null,
- hoverMode = null;
+ hoverMode = null,
+ allTrafficIndex = 0;
+
// === -----------------------------------------------------
@@ -104,18 +117,14 @@
return true;
}
- function showAllFlowTraffic() {
+ function showAllTraffic() {
trafficMode = 'allFlowPort';
hoverMode = null;
- wss.sendEvent('requestAllFlowTraffic');
- flash.flash('All Flow Traffic');
- }
-
- function showAllPortTraffic() {
- trafficMode = 'allFlowPort';
- hoverMode = null;
- wss.sendEvent('requestAllPortTraffic');
- flash.flash('All Port Traffic');
+ wss.sendEvent('requestAllTraffic', {
+ trafficType: allTrafficTypes[allTrafficIndex]
+ });
+ flash.flash(allTrafficMsgs[allTrafficIndex]);
+ allTrafficIndex = (allTrafficIndex + 1) % 3;
}
function showDeviceLinkFlows () {
@@ -245,8 +254,7 @@
// invoked from toolbar overlay buttons or keystrokes
cancelTraffic: cancelTraffic,
- showAllFlowTraffic: showAllFlowTraffic,
- showAllPortTraffic: showAllPortTraffic,
+ showAllTraffic: showAllTraffic,
showDeviceLinkFlows: showDeviceLinkFlows,
showRelatedIntents: showRelatedIntents,
showPrevIntent: showPrevIntent,
diff --git a/web/gui/src/main/webapp/app/view/topo/topoTrafficNew.js b/web/gui/src/main/webapp/app/view/topo/topoTrafficNew.js
index ac8f4a2..7877e93 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoTrafficNew.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoTrafficNew.js
@@ -75,13 +75,8 @@
},
A: {
- cb: function () { tts.showAllFlowTraffic(); },
- tt: 'Monitor all traffic using flow stats',
- gid: 'm_allTraffic'
- },
- Q: {
- cb: function () { tts.showAllPortTraffic(); },
- tt: 'Monitor all traffic using port stats',
+ cb: function () { tts.showAllTraffic(); },
+ tt: 'Monitor all traffic',
gid: 'm_allTraffic'
},
F: {
@@ -111,7 +106,7 @@
},
_keyOrder: [
- '0', 'A', 'Q', 'F', 'V', 'leftArrow', 'rightArrow', 'W'
+ '0', 'A', 'F', 'V', 'leftArrow', 'rightArrow', 'W'
]
},
diff --git a/web/gui/src/main/webapp/tests/app/view/topo/topoTraffic-spec.js b/web/gui/src/main/webapp/tests/app/view/topo/topoTraffic-spec.js
index 0a04f34..2f51848 100644
--- a/web/gui/src/main/webapp/tests/app/view/topo/topoTraffic-spec.js
+++ b/web/gui/src/main/webapp/tests/app/view/topo/topoTraffic-spec.js
@@ -38,8 +38,7 @@
'initTraffic',
'destroyTraffic',
'cancelTraffic',
- 'showAllFlowTraffic',
- 'showAllPortTraffic',
+ 'showAllTraffic',
'showDeviceLinkFlows',
'showRelatedIntents',
'showPrevIntent',