mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-14 17:01:02 +02:00
GUI fixes/breaks.
Change-Id: Ic5c8b087cc32506162153b2756a677c7d9e3bdd7
This commit is contained in:
parent
20bc6ae5de
commit
164fa5c9ad
@ -66,7 +66,7 @@ import static org.slf4j.LoggerFactory.getLogger;
|
||||
public class DefaultTopologyProvider extends AbstractProvider
|
||||
implements TopologyProvider {
|
||||
|
||||
private static final int MAX_THREADS = 8;
|
||||
private static final int MAX_THREADS = 32;
|
||||
private static final int DEFAULT_MAX_EVENTS = 1000;
|
||||
private static final int DEFAULT_MAX_IDLE_MS = 10;
|
||||
private static final int DEFAULT_MAX_BATCH_MS = 50;
|
||||
|
20
tools/test/topos/topo-200sw-linkalarm.py
Normal file
20
tools/test/topos/topo-200sw-linkalarm.py
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
from mininet.topo import Topo
|
||||
|
||||
class MyTopo( Topo ):
|
||||
"10 'floating' switch topology"
|
||||
|
||||
def __init__( self ):
|
||||
# Initialize topology
|
||||
Topo.__init__( self )
|
||||
|
||||
sw_list = []
|
||||
swC = self.addSwitch('sc', dpid = 'ffffffff00000001')
|
||||
|
||||
for i in range(1, 201):
|
||||
switch=self.addSwitch('s'+str(i), dpid = str(i).zfill(16))
|
||||
self.addLink(switch,swC)
|
||||
|
||||
sw_list.append(switch)
|
||||
|
||||
topos = { 'mytopo': ( lambda: MyTopo() ) }
|
@ -33,6 +33,7 @@ import org.onlab.onos.net.intent.PathIntent;
|
||||
import org.onlab.onos.net.intent.PointToPointIntent;
|
||||
import org.onlab.onos.net.link.LinkService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -71,17 +72,19 @@ public class TopologyViewIntentFilter {
|
||||
* Finds all path (host-to-host or point-to-point) intents that pertains
|
||||
* to the given hosts.
|
||||
*
|
||||
* @param hosts set of hosts to query by
|
||||
* @param devices set of devices to query by
|
||||
* @param hosts set of hosts to query by
|
||||
* @param devices set of devices to query by
|
||||
* @param sourceIntents collection of intents to search
|
||||
* @return set of intents that 'match' all hosts and devices given
|
||||
*/
|
||||
Set<Intent> findPathIntents(Set<Host> hosts, Set<Device> devices) {
|
||||
List<Intent> findPathIntents(Set<Host> hosts, Set<Device> devices,
|
||||
Iterable<Intent> sourceIntents) {
|
||||
// Derive from this the set of edge connect points.
|
||||
Set<ConnectPoint> edgePoints = getEdgePoints(hosts);
|
||||
|
||||
// Iterate over all intents and produce a set that contains only those
|
||||
// intents that target all selected hosts or derived edge connect points.
|
||||
return getIntents(hosts, devices, edgePoints);
|
||||
return getIntents(hosts, devices, edgePoints, sourceIntents);
|
||||
}
|
||||
|
||||
|
||||
@ -94,10 +97,11 @@ public class TopologyViewIntentFilter {
|
||||
return edgePoints;
|
||||
}
|
||||
|
||||
// Produces a set of intents that target all selected hosts, devices or connect points.
|
||||
private Set<Intent> getIntents(Set<Host> hosts, Set<Device> devices,
|
||||
Set<ConnectPoint> edgePoints) {
|
||||
Set<Intent> intents = new HashSet<>();
|
||||
// Produces a list of intents that target all selected hosts, devices or connect points.
|
||||
private List<Intent> getIntents(Set<Host> hosts, Set<Device> devices,
|
||||
Set<ConnectPoint> edgePoints,
|
||||
Iterable<Intent> sourceIntents) {
|
||||
List<Intent> intents = new ArrayList<>();
|
||||
if (hosts.isEmpty() && devices.isEmpty()) {
|
||||
return intents;
|
||||
}
|
||||
@ -105,7 +109,7 @@ public class TopologyViewIntentFilter {
|
||||
Set<OpticalConnectivityIntent> opticalIntents = new HashSet<>();
|
||||
|
||||
// Search through all intents and see if they are relevant to our search.
|
||||
for (Intent intent : intentService.getIntents()) {
|
||||
for (Intent intent : sourceIntents) {
|
||||
if (intentService.getIntentState(intent.id()) == INSTALLED) {
|
||||
boolean isRelevant = false;
|
||||
if (intent instanceof HostToHostIntent) {
|
||||
@ -140,7 +144,7 @@ public class TopologyViewIntentFilter {
|
||||
}
|
||||
|
||||
// Indicates whether the specified intent involves all of the given hosts.
|
||||
private boolean isIntentRelevantToHosts(HostToHostIntent intent, Set<Host> hosts) {
|
||||
private boolean isIntentRelevantToHosts(HostToHostIntent intent, Iterable<Host> hosts) {
|
||||
for (Host host : hosts) {
|
||||
HostId id = host.id();
|
||||
// Bail if intent does not involve this host.
|
||||
@ -152,7 +156,7 @@ public class TopologyViewIntentFilter {
|
||||
}
|
||||
|
||||
// Indicates whether the specified intent involves all of the given devices.
|
||||
private boolean isIntentRelevantToDevices(Intent intent, Set<Device> devices) {
|
||||
private boolean isIntentRelevantToDevices(Intent intent, Iterable<Device> devices) {
|
||||
List<Intent> installables = intentService.getInstallableIntents(intent.id());
|
||||
for (Device device : devices) {
|
||||
if (!isIntentRelevantToDevice(installables, device)) {
|
||||
@ -192,7 +196,8 @@ public class TopologyViewIntentFilter {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isIntentRelevant(PointToPointIntent intent, Set<ConnectPoint> edgePoints) {
|
||||
private boolean isIntentRelevant(PointToPointIntent intent,
|
||||
Iterable<ConnectPoint> edgePoints) {
|
||||
for (ConnectPoint point : edgePoints) {
|
||||
// Bail if intent does not involve this edge point.
|
||||
if (!point.equals(intent.egressPoint()) &&
|
||||
@ -205,7 +210,7 @@ public class TopologyViewIntentFilter {
|
||||
|
||||
// Indicates whether the specified intent involves all of the given edge points.
|
||||
private boolean isIntentRelevant(MultiPointToSinglePointIntent intent,
|
||||
Set<ConnectPoint> edgePoints) {
|
||||
Iterable<ConnectPoint> edgePoints) {
|
||||
for (ConnectPoint point : edgePoints) {
|
||||
// Bail if intent does not involve this edge point.
|
||||
if (!point.equals(intent.egressPoint()) &&
|
||||
@ -218,7 +223,7 @@ public class TopologyViewIntentFilter {
|
||||
|
||||
// Indicates whether the specified intent involves all of the given edge points.
|
||||
private boolean isIntentRelevant(OpticalConnectivityIntent opticalIntent,
|
||||
Set<Intent> intents) {
|
||||
Iterable<Intent> intents) {
|
||||
Link ccSrc = getFirstLink(opticalIntent.getSrc(), false);
|
||||
Link ccDst = getFirstLink(opticalIntent.getDst(), true);
|
||||
|
||||
|
@ -676,13 +676,16 @@ public abstract class TopologyViewMessages {
|
||||
List<Intent> installables = intentService.getInstallableIntents(intent.id());
|
||||
if (installables != null) {
|
||||
for (Intent installable : installables) {
|
||||
String cls = isOptical ? trafficClass.type + " optical" : trafficClass.type;
|
||||
String type = isOptical ? trafficClass.type + " optical" : trafficClass.type;
|
||||
if (installable instanceof PathIntent) {
|
||||
classifyLinks(cls, biLinks, ((PathIntent) installable).path().links());
|
||||
classifyLinks(type, biLinks, trafficClass.showTraffic,
|
||||
((PathIntent) installable).path().links());
|
||||
} else if (installable instanceof LinkCollectionIntent) {
|
||||
classifyLinks(cls, biLinks, ((LinkCollectionIntent) installable).links());
|
||||
classifyLinks(type, biLinks, trafficClass.showTraffic,
|
||||
((LinkCollectionIntent) installable).links());
|
||||
} else if (installable instanceof OpticalPathIntent) {
|
||||
classifyLinks(cls, biLinks, ((OpticalPathIntent) installable).path().links());
|
||||
classifyLinks(type, biLinks, trafficClass.showTraffic,
|
||||
((OpticalPathIntent) installable).path().links());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -695,12 +698,14 @@ public abstract class TopologyViewMessages {
|
||||
// Adds the link segments (path or tree) associated with the specified
|
||||
// connectivity intent
|
||||
private void classifyLinks(String type, Map<LinkKey, BiLink> biLinks,
|
||||
Iterable<Link> links) {
|
||||
boolean showTraffic, Iterable<Link> links) {
|
||||
if (links != null) {
|
||||
for (Link link : links) {
|
||||
BiLink biLink = addLink(biLinks, link);
|
||||
if (isInfrastructureEgress(link)) {
|
||||
biLink.addLoad(statService.load(link));
|
||||
if (showTraffic) {
|
||||
biLink.addLoad(statService.load(link));
|
||||
}
|
||||
biLink.addClass(type);
|
||||
}
|
||||
}
|
||||
@ -862,12 +867,18 @@ public abstract class TopologyViewMessages {
|
||||
|
||||
// Auxiliary carrier of data for requesting traffic message.
|
||||
protected class TrafficClass {
|
||||
public final boolean showTraffic;
|
||||
public final String type;
|
||||
public final Set<Intent> intents;
|
||||
public final Iterable<Intent> intents;
|
||||
|
||||
TrafficClass(String type, Set<Intent> intents) {
|
||||
TrafficClass(String type, Iterable<Intent> intents) {
|
||||
this(type, intents, false);
|
||||
}
|
||||
|
||||
TrafficClass(String type, Iterable<Intent> intents, boolean showTraffic) {
|
||||
this.type = type;
|
||||
this.intents = intents;
|
||||
this.showTraffic = showTraffic;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,8 @@ public class TopologyViewWebSocket
|
||||
|
||||
private static final String APP_ID = "org.onlab.onos.gui";
|
||||
|
||||
private static final long TRAFFIC_FREQUENCY_SEC = 2000;
|
||||
private static final long TRAFFIC_FREQUENCY = 2000;
|
||||
private static final long SUMMARY_FREQUENCY = 30000;
|
||||
|
||||
private static final Comparator<? super ControllerNode> NODE_COMPARATOR =
|
||||
new Comparator<ControllerNode>() {
|
||||
@ -103,9 +104,9 @@ public class TopologyViewWebSocket
|
||||
|
||||
private final Timer timer = new Timer("topology-view");
|
||||
|
||||
private static final int MAX_EVENTS = 500;
|
||||
private static final int MAX_BATCH_MS = 1000;
|
||||
private static final int MAX_IDLE_MS = 500;
|
||||
private static final int MAX_EVENTS = 1000;
|
||||
private static final int MAX_BATCH_MS = 5000;
|
||||
private static final int MAX_IDLE_MS = 1000;
|
||||
|
||||
private final ApplicationId appId;
|
||||
|
||||
@ -122,15 +123,23 @@ public class TopologyViewWebSocket
|
||||
|
||||
private final EventAccumulator eventAccummulator = new InternalEventAccummulator();
|
||||
|
||||
private boolean summaryEnabled = true;
|
||||
private TimerTask trafficTask;
|
||||
private ObjectNode trafficEvent;
|
||||
|
||||
private TimerTask summaryTask;
|
||||
private ObjectNode summaryEvent;
|
||||
|
||||
private long lastActive = System.currentTimeMillis();
|
||||
private boolean listenersRemoved = false;
|
||||
|
||||
private TopologyViewIntentFilter intentFilter;
|
||||
|
||||
// Current selection context
|
||||
private Set<Host> selectedHosts;
|
||||
private Set<Device> selectedDevices;
|
||||
private List<Intent> selectedIntents;
|
||||
private int currentIntentIndex = -1;
|
||||
|
||||
/**
|
||||
* Creates a new web-socket for serving data to GUI topology view.
|
||||
*
|
||||
@ -204,7 +213,6 @@ public class TopologyViewWebSocket
|
||||
processMessage((ObjectNode) mapper.reader().readTree(data));
|
||||
} catch (Exception e) {
|
||||
log.warn("Unable to parse GUI request {} due to {}", data, e);
|
||||
log.warn("Boom!!!!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,19 +229,29 @@ public class TopologyViewWebSocket
|
||||
} else if (type.equals("addMultiSourceIntent")) {
|
||||
createMultiSourceIntent(event);
|
||||
|
||||
} else if (type.equals("requestTraffic")) {
|
||||
requestTraffic(event);
|
||||
} else if (type.equals("requestRelatedIntents")) {
|
||||
requestRelatedIntents(event);
|
||||
} else if (type.equals("requestNextRelatedIntent")) {
|
||||
requestNextRelatedIntent(event);
|
||||
} else if (type.equals("requestSelectedIntentTraffic")) {
|
||||
requestSelectedIntentTraffic(event);
|
||||
|
||||
} else if (type.equals("requestAllTraffic")) {
|
||||
requestAllTraffic(event);
|
||||
startTrafficMonitoring(event);
|
||||
|
||||
} else if (type.equals("requestDeviceLinkFlows")) {
|
||||
requestDeviceLinkFlows(event);
|
||||
startTrafficMonitoring(event);
|
||||
|
||||
} else if (type.equals("cancelTraffic")) {
|
||||
cancelTraffic(event);
|
||||
|
||||
} else if (type.equals("requestSummary")) {
|
||||
requestSummary(event);
|
||||
startSummaryMonitoring(event);
|
||||
} else if (type.equals("cancelSummary")) {
|
||||
cancelSummary(event);
|
||||
stopSummaryMonitoring();
|
||||
|
||||
} else if (type.equals("equalizeMasters")) {
|
||||
equalizeMasters(event);
|
||||
@ -324,8 +342,9 @@ public class TopologyViewWebSocket
|
||||
new HostToHostIntent(appId, one, two,
|
||||
DefaultTrafficSelector.builder().build(),
|
||||
DefaultTrafficTreatment.builder().build());
|
||||
startMonitoring(event);
|
||||
|
||||
intentService.submit(intent);
|
||||
startMonitoringIntent(event, intent);
|
||||
}
|
||||
|
||||
// Creates multi-source-to-single-dest intent.
|
||||
@ -348,10 +367,24 @@ public class TopologyViewWebSocket
|
||||
MultiPointToSinglePointIntent intent =
|
||||
new MultiPointToSinglePointIntent(appId, selector, treatment,
|
||||
ingressPoints, dstHost.location());
|
||||
startMonitoring(event);
|
||||
|
||||
intentService.submit(intent);
|
||||
startMonitoringIntent(event, intent);
|
||||
}
|
||||
|
||||
|
||||
private synchronized void startMonitoringIntent(ObjectNode event, Intent intent) {
|
||||
selectedHosts = new HashSet<>();
|
||||
selectedDevices = new HashSet<>();
|
||||
selectedIntents = new ArrayList<>();
|
||||
selectedIntents.add(intent);
|
||||
currentIntentIndex = -1;
|
||||
requestNextRelatedIntent(event);
|
||||
requestSelectedIntentTraffic(event);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Set<ConnectPoint> getHostLocations(Set<HostId> hostIds) {
|
||||
Set<ConnectPoint> points = new HashSet<>();
|
||||
for (HostId hostId : hostIds) {
|
||||
@ -374,17 +407,15 @@ public class TopologyViewWebSocket
|
||||
}
|
||||
|
||||
|
||||
private synchronized long startMonitoring(ObjectNode event) {
|
||||
if (trafficTask != null) {
|
||||
stopMonitoring();
|
||||
}
|
||||
private synchronized long startTrafficMonitoring(ObjectNode event) {
|
||||
stopTrafficMonitoring();
|
||||
trafficEvent = event;
|
||||
trafficTask = new TrafficMonitor();
|
||||
timer.schedule(trafficTask, TRAFFIC_FREQUENCY_SEC, TRAFFIC_FREQUENCY_SEC);
|
||||
timer.schedule(trafficTask, TRAFFIC_FREQUENCY, TRAFFIC_FREQUENCY);
|
||||
return number(event, "sid");
|
||||
}
|
||||
|
||||
private synchronized void stopMonitoring() {
|
||||
private synchronized void stopTrafficMonitoring() {
|
||||
if (trafficTask != null) {
|
||||
trafficTask.cancel();
|
||||
trafficTask = null;
|
||||
@ -394,13 +425,13 @@ public class TopologyViewWebSocket
|
||||
|
||||
// Subscribes for host traffic messages.
|
||||
private synchronized void requestAllTraffic(ObjectNode event) {
|
||||
long sid = startMonitoring(event);
|
||||
long sid = startTrafficMonitoring(event);
|
||||
sendMessage(trafficSummaryMessage(sid));
|
||||
}
|
||||
|
||||
private void requestDeviceLinkFlows(ObjectNode event) {
|
||||
ObjectNode payload = payload(event);
|
||||
long sid = startMonitoring(event);
|
||||
long sid = startTrafficMonitoring(event);
|
||||
|
||||
// Get the set of selected hosts and their intents.
|
||||
ArrayNode ids = (ArrayNode) payload.path("ids");
|
||||
@ -416,58 +447,122 @@ public class TopologyViewWebSocket
|
||||
}
|
||||
|
||||
|
||||
// Subscribes for host traffic messages.
|
||||
private synchronized void requestTraffic(ObjectNode event) {
|
||||
// Requests related intents message.
|
||||
private synchronized void requestRelatedIntents(ObjectNode event) {
|
||||
ObjectNode payload = payload(event);
|
||||
if (!payload.has("ids")) {
|
||||
return;
|
||||
}
|
||||
|
||||
long sid = startMonitoring(event);
|
||||
long sid = number(event, "sid");
|
||||
|
||||
// Get the set of selected hosts and their intents.
|
||||
ArrayNode ids = (ArrayNode) payload.path("ids");
|
||||
Set<Host> hosts = getHosts(ids);
|
||||
Set<Device> devices = getDevices(ids);
|
||||
Set<Intent> intents = intentFilter.findPathIntents(hosts, devices);
|
||||
// Cancel any other traffic monitoring mode.
|
||||
stopTrafficMonitoring();
|
||||
|
||||
// If there is a hover node, include it in the hosts and find intents.
|
||||
String hover = string(payload, "hover");
|
||||
Set<Intent> hoverIntents;
|
||||
if (haveSelectedIntents()) {
|
||||
// Get the set of selected hosts and their intents.
|
||||
ArrayNode ids = (ArrayNode) payload.path("ids");
|
||||
selectedHosts = getHosts(ids);
|
||||
selectedDevices = getDevices(ids);
|
||||
selectedIntents = intentFilter.findPathIntents(selectedHosts, selectedDevices,
|
||||
intentService.getIntents());
|
||||
currentIntentIndex = -1;
|
||||
|
||||
// Send a message to highlight all links of all monitored intents.
|
||||
sendMessage(trafficMessage(sid, new TrafficClass("primary", selectedIntents)));
|
||||
}
|
||||
|
||||
if (!isNullOrEmpty(hover)) {
|
||||
addHover(hosts, devices, hover);
|
||||
hoverIntents = intentFilter.findPathIntents(hosts, devices);
|
||||
intents.removeAll(hoverIntents);
|
||||
// If there is a hover node, include it in the selection and find intents.
|
||||
processExtendedSelection(sid, hover);
|
||||
}
|
||||
}
|
||||
|
||||
// Send an initial message to highlight all links of all monitored intents.
|
||||
sendMessage(trafficMessage(sid,
|
||||
new TrafficClass("primary", hoverIntents),
|
||||
new TrafficClass("secondary", intents)));
|
||||
private boolean haveSelectedIntents() {
|
||||
return selectedIntents != null && !selectedIntents.isEmpty();
|
||||
}
|
||||
|
||||
} else {
|
||||
// Send an initial message to highlight all links of all monitored intents.
|
||||
sendMessage(trafficMessage(sid, new TrafficClass("primary", intents)));
|
||||
private void processExtendedSelection(long sid, String hover) {
|
||||
Set<Host> hoverSelHosts = new HashSet<>(selectedHosts);
|
||||
Set<Device> hoverSelDevices = new HashSet<>(selectedDevices);
|
||||
addHover(hoverSelHosts, hoverSelDevices, hover);
|
||||
|
||||
List<Intent> primary =
|
||||
intentFilter.findPathIntents(hoverSelHosts, hoverSelDevices,
|
||||
selectedIntents);
|
||||
Set<Intent> secondary = new HashSet<>(selectedIntents);
|
||||
secondary.removeAll(primary);
|
||||
|
||||
// Send a message to highlight all links of all monitored intents.
|
||||
sendMessage(trafficMessage(sid, new TrafficClass("primary", primary),
|
||||
new TrafficClass("secondary", secondary)));
|
||||
}
|
||||
|
||||
// Requests next of the related intents.
|
||||
private void requestNextRelatedIntent(ObjectNode event) {
|
||||
if (haveSelectedIntents()) {
|
||||
currentIntentIndex = (currentIntentIndex + 1) % selectedIntents.size();
|
||||
Intent selectedIntent = selectedIntents.get(currentIntentIndex);
|
||||
log.info("Requested next intent {}", selectedIntent.id());
|
||||
|
||||
Set<Intent> primary = new HashSet<>();
|
||||
primary.add(selectedIntent);
|
||||
|
||||
Set<Intent> secondary = new HashSet<>(selectedIntents);
|
||||
secondary.remove(selectedIntent);
|
||||
|
||||
// Send a message to highlight all links of the selected intent.
|
||||
sendMessage(trafficMessage(number(event, "sid"),
|
||||
new TrafficClass("primary", primary),
|
||||
new TrafficClass("secondary", secondary)));
|
||||
}
|
||||
}
|
||||
|
||||
// Requests monitoring of traffic for the selected intent.
|
||||
private void requestSelectedIntentTraffic(ObjectNode event) {
|
||||
if (haveSelectedIntents()) {
|
||||
Intent selectedIntent = selectedIntents.get(currentIntentIndex);
|
||||
log.info("Requested traffic for selected {}", selectedIntent.id());
|
||||
|
||||
Set<Intent> primary = new HashSet<>();
|
||||
primary.add(selectedIntent);
|
||||
|
||||
// Send a message to highlight all links of the selected intent.
|
||||
sendMessage(trafficMessage(number(event, "sid"),
|
||||
new TrafficClass("primary", primary, true)));
|
||||
}
|
||||
}
|
||||
|
||||
// Cancels sending traffic messages.
|
||||
private void cancelTraffic(ObjectNode event) {
|
||||
selectedIntents = null;
|
||||
sendMessage(trafficMessage(number(event, "sid")));
|
||||
stopMonitoring();
|
||||
stopTrafficMonitoring();
|
||||
}
|
||||
|
||||
|
||||
private synchronized long startSummaryMonitoring(ObjectNode event) {
|
||||
stopSummaryMonitoring();
|
||||
summaryEvent = event;
|
||||
summaryTask = new SummaryMonitor();
|
||||
timer.schedule(summaryTask, SUMMARY_FREQUENCY, SUMMARY_FREQUENCY);
|
||||
return number(event, "sid");
|
||||
}
|
||||
|
||||
private synchronized void stopSummaryMonitoring() {
|
||||
if (summaryEvent != null) {
|
||||
summaryTask.cancel();
|
||||
summaryTask = null;
|
||||
summaryEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribes for summary messages.
|
||||
private synchronized void requestSummary(ObjectNode event) {
|
||||
summaryEnabled = true;
|
||||
sendMessage(summmaryMessage(number(event, "sid")));
|
||||
}
|
||||
|
||||
// Cancels sending summary messages.
|
||||
private synchronized void cancelSummary(ObjectNode event) {
|
||||
summaryEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
// Forces mastership role rebalancing.
|
||||
private void equalizeMasters(ObjectNode event) {
|
||||
@ -550,7 +645,7 @@ public class TopologyViewWebSocket
|
||||
@Override
|
||||
public void event(IntentEvent event) {
|
||||
if (trafficEvent != null) {
|
||||
requestTraffic(trafficEvent);
|
||||
requestSelectedIntentTraffic(trafficEvent);
|
||||
}
|
||||
eventAccummulator.add(event);
|
||||
}
|
||||
@ -564,6 +659,7 @@ public class TopologyViewWebSocket
|
||||
}
|
||||
}
|
||||
|
||||
// Periodic update of the traffic information
|
||||
private class TrafficMonitor extends TimerTask {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -574,8 +670,8 @@ public class TopologyViewWebSocket
|
||||
requestAllTraffic(trafficEvent);
|
||||
} else if (type.equals("requestDeviceLinkFlows")) {
|
||||
requestDeviceLinkFlows(trafficEvent);
|
||||
} else {
|
||||
requestTraffic(trafficEvent);
|
||||
} else if (type.equals("requestSelectedIntentTraffic")) {
|
||||
requestSelectedIntentTraffic(trafficEvent);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -585,6 +681,20 @@ public class TopologyViewWebSocket
|
||||
}
|
||||
}
|
||||
|
||||
// Periodic update of the summary information
|
||||
private class SummaryMonitor extends TimerTask {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (summaryEvent != null) {
|
||||
requestSummary(summaryEvent);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Unable to handle summary request due to {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulates events to drive methodic update of the summary pane.
|
||||
private class InternalEventAccummulator extends AbstractEventAccumulator {
|
||||
protected InternalEventAccummulator() {
|
||||
@ -594,7 +704,7 @@ public class TopologyViewWebSocket
|
||||
@Override
|
||||
public void processEvents(List<Event> events) {
|
||||
try {
|
||||
if (summaryEnabled) {
|
||||
if (summaryEvent != null) {
|
||||
sendMessage(summmaryMessage(0));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -145,8 +145,10 @@
|
||||
P: togglePorts,
|
||||
U: [unpin, 'Unpin node (hover mouse over)'],
|
||||
R: [resetPanZoom, 'Reset pan / zoom'],
|
||||
V: [showTrafficAction, 'Show related traffic'],
|
||||
A: [showAllTrafficAction, 'Show all traffic'],
|
||||
V: [showRelatedIntentsAction, 'Show all related intents'],
|
||||
N: [showNextIntentAction, 'Show next related intent'],
|
||||
W: [showSelectedIntentTrafficAction, 'Monitor traffic of selected intent'],
|
||||
A: [showAllTrafficAction, 'Monitor all traffic'],
|
||||
F: [showDeviceLinkFlowsAction, 'Show device link flows'],
|
||||
X: [toggleNodeLock, 'Lock / unlock node positions'],
|
||||
Z: [toggleOblique, 'Toggle oblique view (Experimental)'],
|
||||
@ -209,10 +211,11 @@
|
||||
oblique = false;
|
||||
|
||||
// constants
|
||||
var hoverModeAll = 1,
|
||||
var hoverModeNone = 0,
|
||||
hoverModeAll = 1,
|
||||
hoverModeFlows = 2,
|
||||
hoverModeIntents = 3,
|
||||
hoverMode = hoverModeFlows;
|
||||
hoverMode = hoverModeNone;
|
||||
|
||||
// D3 selections
|
||||
var svg,
|
||||
@ -394,7 +397,7 @@
|
||||
cancelSummary();
|
||||
stopAntTimer();
|
||||
} else {
|
||||
hoverMode = hoverModeFlows;
|
||||
hoverMode = hoverModeNone;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1219,22 +1222,20 @@
|
||||
}
|
||||
|
||||
function requestTrafficForMode() {
|
||||
if (hoverMode === hoverModeAll) {
|
||||
requestAllTraffic();
|
||||
} else if (hoverMode === hoverModeFlows) {
|
||||
if (hoverMode === hoverModeFlows) {
|
||||
requestDeviceLinkFlows();
|
||||
} else if (hoverMode === hoverModeIntents) {
|
||||
requestSelectTraffic();
|
||||
requestRelatedIntents();
|
||||
}
|
||||
}
|
||||
|
||||
function showTrafficAction() {
|
||||
function showRelatedIntentsAction() {
|
||||
hoverMode = hoverModeIntents;
|
||||
requestSelectTraffic();
|
||||
flash('Related Traffic');
|
||||
requestRelatedIntents();
|
||||
flash('Related intents');
|
||||
}
|
||||
|
||||
function requestSelectTraffic() {
|
||||
function requestRelatedIntents() {
|
||||
function hoverValid() {
|
||||
return hoverMode === hoverModeIntents &&
|
||||
hovered &&
|
||||
@ -1242,13 +1243,24 @@
|
||||
}
|
||||
|
||||
if (validateSelectionContext()) {
|
||||
sendMessage('requestTraffic', {
|
||||
sendMessage('requestRelatedIntents', {
|
||||
ids: selectOrder,
|
||||
hover: hoverValid() ? hovered.id : ''
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function showNextIntentAction() {
|
||||
hoverMode = hoverModeNone;
|
||||
sendMessage('requestNextRelatedIntent', {});
|
||||
flash('Next related intent');
|
||||
}
|
||||
|
||||
function showSelectedIntentTrafficAction() {
|
||||
hoverMode = hoverModeNone;
|
||||
sendMessage('requestSelectedIntentTraffic', {});
|
||||
flash('Monitoring selected intent');
|
||||
}
|
||||
|
||||
function showDeviceLinkFlowsAction() {
|
||||
hoverMode = hoverModeFlows;
|
||||
@ -2010,13 +2022,17 @@
|
||||
}
|
||||
|
||||
function nodeMouseOver(d) {
|
||||
hovered = d;
|
||||
requestTrafficForMode();
|
||||
if (hovered != d) {
|
||||
hovered = d;
|
||||
requestTrafficForMode();
|
||||
}
|
||||
}
|
||||
|
||||
function nodeMouseOut(d) {
|
||||
hovered = null;
|
||||
requestTrafficForMode();
|
||||
if (hovered != null) {
|
||||
hovered = null;
|
||||
requestTrafficForMode();
|
||||
}
|
||||
}
|
||||
|
||||
function addHostIcon(node, radius, iid) {
|
||||
@ -2498,7 +2514,7 @@
|
||||
wsTrace('rx', msg);
|
||||
}
|
||||
function wsTrace(rxtx, msg) {
|
||||
console.log('[' + rxtx + '] ' + msg);
|
||||
// console.log('[' + rxtx + '] ' + msg);
|
||||
}
|
||||
|
||||
// NOTE: Temporary hardcoded example for showing detail pane
|
||||
@ -2620,7 +2636,6 @@
|
||||
emptySelect();
|
||||
} else if (nSel === 1) {
|
||||
singleSelect();
|
||||
requestTrafficForMode();
|
||||
} else {
|
||||
multiSelect();
|
||||
}
|
||||
@ -2635,12 +2650,14 @@
|
||||
function singleSelect() {
|
||||
// NOTE: detail is shown from showDetails event callback
|
||||
requestDetails();
|
||||
cancelTraffic();
|
||||
requestTrafficForMode();
|
||||
}
|
||||
|
||||
function multiSelect() {
|
||||
haveDetails = true;
|
||||
populateMultiSelect();
|
||||
cancelTraffic();
|
||||
requestTrafficForMode();
|
||||
}
|
||||
|
||||
@ -2738,7 +2755,7 @@
|
||||
function addSingleSelectActions(data) {
|
||||
detailPane.append('hr');
|
||||
// always want to allow 'show traffic'
|
||||
addAction(detailPane, 'Show Related Traffic', showTrafficAction);
|
||||
addAction(detailPane, 'Show Related Traffic', showRelatedIntentsAction);
|
||||
|
||||
if (data.type === 'switch') {
|
||||
addAction(detailPane, 'Show Device Flows', showDeviceLinkFlowsAction);
|
||||
@ -2748,7 +2765,7 @@
|
||||
function addMultiSelectActions() {
|
||||
detailPane.append('hr');
|
||||
// always want to allow 'show traffic'
|
||||
addAction(detailPane, 'Show Related Traffic', showTrafficAction);
|
||||
addAction(detailPane, 'Show Related Traffic', showRelatedIntentsAction);
|
||||
// if exactly two hosts are selected, also want 'add host intent'
|
||||
if (nSel() === 2 && allSelectionsClass('host')) {
|
||||
addAction(detailPane, 'Create Host-to-Host Flow', addHostIntentAction);
|
||||
|
Loading…
x
Reference in New Issue
Block a user