From e7591e56bdd03fb15b7f690f992bb71c0eee3d1c Mon Sep 17 00:00:00 2001 From: Thomas Vachuska Date: Thu, 13 Nov 2014 21:31:15 -0800 Subject: [PATCH] GUI traffic visualization work on server-side. Change-Id: I15564fc8484464858adf57fe22462f4951d09d09 --- .../org/onlab/onos/gui/TopologyMessages.java | 30 +++++--- .../org/onlab/onos/gui/TopologyWebSocket.java | 76 +++++++++++-------- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/web/gui/src/main/java/org/onlab/onos/gui/TopologyMessages.java b/web/gui/src/main/java/org/onlab/onos/gui/TopologyMessages.java index e7bc37eaa1..c87a7f6bdb 100644 --- a/web/gui/src/main/java/org/onlab/onos/gui/TopologyMessages.java +++ b/web/gui/src/main/java/org/onlab/onos/gui/TopologyMessages.java @@ -43,7 +43,6 @@ import org.onlab.onos.net.host.HostService; import org.onlab.onos.net.intent.ConnectivityIntent; import org.onlab.onos.net.intent.Intent; import org.onlab.onos.net.intent.IntentService; -import org.onlab.onos.net.intent.IntentState; import org.onlab.onos.net.intent.LinkCollectionIntent; import org.onlab.onos.net.intent.PathIntent; import org.onlab.onos.net.link.LinkEvent; @@ -232,7 +231,7 @@ public abstract class TopologyMessages { ObjectNode payload = mapper.createObjectNode() .put("id", compactLinkString(link)) .put("type", link.type().toString().toLowerCase()) - .put("online", true) // TODO: add link state field + .put("online", true) // link.state()) TODO: add link state field .put("linkWidth", 2) .put("src", link.src().deviceId().toString()) .put("srcPort", link.src().port().toString()) @@ -370,18 +369,18 @@ public abstract class TopologyMessages { // Produces JSON message to trigger traffic visualization - protected ObjectNode trafficMessage(Set intents, long sid) { + protected ObjectNode trafficMessage(long sid, TrafficClass... trafficClasses) { ObjectNode payload = mapper.createObjectNode(); ArrayNode paths = mapper.createArrayNode(); payload.set("paths", paths); - for (Intent intent : intents) { - List installables = intentService.getInstallableIntents(intent.id()); - IntentState state = intentService.getIntentState(intent.id()); - String type = state == IntentState.FAILED ? "inactive" : "active"; - for (Intent installable : installables) { - if (installable instanceof ConnectivityIntent) { - addPathTraffic(paths, type, (ConnectivityIntent) installable); + for (TrafficClass trafficClass : trafficClasses) { + for (Intent intent : trafficClass.intents) { + List installables = intentService.getInstallableIntents(intent.id()); + for (Intent installable : installables) { + if (installable instanceof ConnectivityIntent) { + addPathTraffic(paths, trafficClass.type, (ConnectivityIntent) installable); + } } } } @@ -452,4 +451,15 @@ public abstract class TopologyMessages { } } + // Auxiliary carrier of data for requesting traffic message. + protected class TrafficClass { + public final String type; + public final Set intents; + + TrafficClass(String type, Set intents) { + this.type = type; + this.intents = intents; + } + } + } diff --git a/web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java b/web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java index 9e2623fce5..cf8144b548 100644 --- a/web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java +++ b/web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java @@ -56,6 +56,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import static com.google.common.base.Strings.isNullOrEmpty; import static org.onlab.onos.cluster.ClusterEvent.Type.INSTANCE_ADDED; import static org.onlab.onos.net.DeviceId.deviceId; import static org.onlab.onos.net.HostId.hostId; @@ -252,38 +253,44 @@ public class TopologyWebSocket private void requestTraffic(ObjectNode event) { ObjectNode payload = payload(event); long sid = number(event, "sid"); - Set intents = findPathIntents(payload); - // Add all those intents to the list of monitored intents & flows. - intentsToMonitor.clear(); - for (Intent intent : intents) { - intentsToMonitor.put(intent, sid); + // Get the set of selected hosts and their intents. + Set hosts = getHosts((ArrayNode) payload.path("ids")); + Set intents = findPathIntents(hosts); + + // If there is a hover node, include it in the hosts and find intents. + String hover = string(payload, "hover"); + Set hoverIntents; + if (!isNullOrEmpty(hover)) { + addHost(hosts, hostId(hover)); + hoverIntents = findPathIntents(hosts); + intents.removeAll(hoverIntents); + + // Send an initial message to highlight all links of all monitored intents. + sendMessage(trafficMessage(sid, + new TrafficClass("primary", hoverIntents), + new TrafficClass("secondary", intents))); + + } else { + // Send an initial message to highlight all links of all monitored intents. + sendMessage(trafficMessage(sid, new TrafficClass("primary", intents))); + + // Add all those intents to the list of monitored intents & flows. + intentsToMonitor.clear(); + for (Intent intent : intents) { + intentsToMonitor.put(intent, sid); + } } - - // Send an initial message to highlight all links of all monitored intents. - sendMessage(trafficMessage(intents, sid)); } // Cancels sending traffic messages. private void cancelTraffic(ObjectNode event) { - ObjectNode payload = payload(event); - long sid = number(event, "sid"); - Set intents = findPathIntents(payload); - - // Remove all those intents from the list of monitored intents & flows. - intentsToMonitor.clear(); // TODO: remove when ready - for (Intent intent : intents) { - intentsToMonitor.remove(intent.id()); - } - sendMessage(trafficMessage(intents, sid)); + sendMessage(trafficMessage(number(event, "sid"))); } // Finds all path (host-to-host or point-to-point) intents that pertains - // to the hosts indicated in the given event payload. - private Set findPathIntents(ObjectNode payload) { - // Get the list of selected hosts. - Set hosts = getHosts((ArrayNode) payload.path("ids")); - + // to the given hosts. + private Set findPathIntents(Set hosts) { // Derive from this the set of edge connect points. Set edgePoints = getEdgePoints(hosts); @@ -359,19 +366,25 @@ public class TopologyWebSocket // Produces a set of all host ids listed in the specified JSON array. private Set getHosts(ArrayNode array) { Set hosts = new HashSet<>(); - for (JsonNode node : array) { - try { - Host host = hostService.getHost(hostId(node.asText())); - if (host != null) { - hosts.add(host); + if (array != null) { + for (JsonNode node : array) { + try { + addHost(hosts, hostId(node.asText())); + } catch (IllegalArgumentException e) { + log.debug("Skipping ID {}", node.asText()); } - } catch (IllegalArgumentException e) { - log.debug("Skipping ID {}", node.asText()); } } return hosts; } + private void addHost(Set hosts, HostId hostId) { + Host host = hostService.getHost(hostId); + if (host != null) { + hosts.add(host); + } + } + // Produces a set of edge points from the specified set of hosts. private Set getEdgePoints(Set hosts) { Set edgePoints = new HashSet<>(); @@ -460,7 +473,8 @@ public class TopologyWebSocket ObjectNode payload = pathMessage(path, "host") .put("intentId", intent.id().toString()); sendMessage(envelope("showPath", sid, payload)); - sendMessage(trafficMessage(intentsToMonitor.keySet(), sid)); + TrafficClass tc = new TrafficClass("animated", intentsToMonitor.keySet()); + sendMessage(trafficMessage(sid, tc)); } } }