ONOS-1479 -- GUI - augmenting topology view for extensibility: WIP.
- Major refactoring of TopologyViewMessageHandler and related classes.
Change-Id: I920f7f9f7317f3987a9a8da35ac086e9f8cab8d3
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 b88ee4f..c2f54e4 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
@@ -48,7 +48,6 @@
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.intent.HostToHostIntent;
-import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentEvent;
import org.onosproject.net.intent.IntentListener;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
@@ -57,6 +56,9 @@
import org.onosproject.ui.JsonUtils;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
+import org.onosproject.ui.impl.TrafficMonitorObject.Mode;
+import org.onosproject.ui.impl.topo.NodeSelection;
+import org.onosproject.ui.topo.Highlights;
import org.onosproject.ui.topo.PropertyPanel;
import java.util.ArrayList;
@@ -70,7 +72,6 @@
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
-import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED;
@@ -117,8 +118,6 @@
// fields
private static final String ID = "id";
- private static final String IDS = "ids";
- private static final String HOVER = "hover";
private static final String DEVICE = "device";
private static final String HOST = "host";
private static final String CLASS = "class";
@@ -132,14 +131,12 @@
private static final String NAMES = "names";
private static final String ACTIVATE = "activate";
private static final String DEACTIVATE = "deactivate";
- private static final String PRIMARY = "primary";
- private static final String SECONDARY = "secondary";
private static final String APP_ID = "org.onosproject.gui";
- private static final long TRAFFIC_FREQUENCY = 5000;
- private static final long SUMMARY_FREQUENCY = 30000;
+ private static final long TRAFFIC_PERIOD = 5000;
+ private static final long SUMMARY_PERIOD = 30000;
private static final Comparator<? super ControllerNode> NODE_COMPARATOR =
(o1, o2) -> o1.id().toString().compareTo(o2.id().toString());
@@ -165,31 +162,21 @@
private final ExecutorService msgSender =
newSingleThreadExecutor(groupedThreads("onos/gui", "msg-sender"));
- private TopoOverlayCache overlayCache;
+ private TrafficMonitorObject tmo;
- private TimerTask trafficTask = null;
- private TrafficEvent trafficEvent = null;
+ private TopoOverlayCache overlayCache;
private TimerTask summaryTask = null;
private boolean summaryRunning = false;
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;
-
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
- intentFilter = new TopologyViewIntentFilter(intentService, deviceService,
- hostService, linkService);
appId = directory.get(CoreService.class).registerApplication(APP_ID);
+ tmo = new TrafficMonitorObject(TRAFFIC_PERIOD, servicesBundle, this);
}
@Override
@@ -214,18 +201,18 @@
new UpdateMeta(),
new EqMasters(),
- // TODO: implement "showHighlights" event (replaces "showTraffic")
-
// TODO: migrate traffic related to separate app
new AddHostIntent(),
new AddMultiSourceIntent(),
+
+ new ReqAllFlowTraffic(),
+ new ReqAllPortTraffic(),
+ new ReqDevLinkFlows(),
new ReqRelatedIntents(),
new ReqNextIntent(),
new ReqPrevIntent(),
new ReqSelectedIntentTraffic(),
- new ReqAllFlowTraffic(),
- new ReqAllPortTraffic(),
- new ReqDevLinkFlows(),
+
new CancelTraffic()
);
}
@@ -288,7 +275,7 @@
@Override
public void process(long sid, ObjectNode payload) {
stopSummaryMonitoring();
- stopTrafficMonitoring();
+ tmo.stop();
}
}
@@ -390,6 +377,9 @@
}
}
+
+ // ========= -----------------------------------------------------------------
+
// === TODO: move traffic related classes to traffic app
private final class AddHostIntent extends RequestHandler {
@@ -410,7 +400,7 @@
.build();
intentService.submit(intent);
- startMonitoringIntent(intent);
+ tmo.monitor(intent);
}
}
@@ -443,82 +433,11 @@
.build();
intentService.submit(intent);
- startMonitoringIntent(intent);
+ tmo.monitor(intent);
}
}
- private final class ReqRelatedIntents extends RequestHandler {
- private ReqRelatedIntents() {
- super(REQ_RELATED_INTENTS);
- }
-
- @Override
- public void process(long sid, ObjectNode payload) {
- // Cancel any other traffic monitoring mode.
- stopTrafficMonitoring();
-
- if (!payload.has(IDS)) {
- return;
- }
-
- // 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;
-
- if (haveSelectedIntents()) {
- // Send a message to highlight all links of all monitored intents.
- sendMessage(trafficMessage(new TrafficClass(PRIMARY, selectedIntents)));
- }
-
- // TODO: Re-introduce once the client click vs hover gesture stuff is sorted out.
-// String hover = string(payload, "hover");
-// if (!isNullOrEmpty(hover)) {
-// // If there is a hover node, include it in the selection and find intents.
-// processHoverExtendedSelection(sid, hover);
-// }
- }
- }
-
- private final class ReqNextIntent extends RequestHandler {
- private ReqNextIntent() {
- super(REQ_NEXT_INTENT);
- }
-
- @Override
- public void process(long sid, ObjectNode payload) {
- stopTrafficMonitoring();
- requestAnotherRelatedIntent(+1);
- }
- }
-
- private final class ReqPrevIntent extends RequestHandler {
- private ReqPrevIntent() {
- super(REQ_PREV_INTENT);
- }
-
- @Override
- public void process(long sid, ObjectNode payload) {
- stopTrafficMonitoring();
- requestAnotherRelatedIntent(-1);
- }
- }
-
- private final class ReqSelectedIntentTraffic extends RequestHandler {
- private ReqSelectedIntentTraffic() {
- super(REQ_SEL_INTENT_TRAFFIC);
- }
-
- @Override
- public void process(long sid, ObjectNode payload) {
- trafficEvent = new TrafficEvent(TrafficEvent.Type.SEL_INTENT, payload);
- requestSelectedIntentTraffic();
- startTrafficMonitoring();
- }
- }
+ // ========= -----------------------------------------------------------------
private final class ReqAllFlowTraffic extends RequestHandler {
private ReqAllFlowTraffic() {
@@ -527,8 +446,7 @@
@Override
public void process(long sid, ObjectNode payload) {
- trafficEvent = new TrafficEvent(TrafficEvent.Type.ALL_FLOW_TRAFFIC, payload);
- requestAllFlowTraffic();
+ tmo.monitor(Mode.ALL_FLOW_TRAFFIC);
}
}
@@ -539,8 +457,7 @@
@Override
public void process(long sid, ObjectNode payload) {
- trafficEvent = new TrafficEvent(TrafficEvent.Type.ALL_PORT_TRAFFIC, payload);
- requestAllPortTraffic();
+ tmo.monitor(Mode.ALL_PORT_TRAFFIC);
}
}
@@ -551,8 +468,55 @@
@Override
public void process(long sid, ObjectNode payload) {
- trafficEvent = new TrafficEvent(TrafficEvent.Type.DEV_LINK_FLOWS, payload);
- requestDeviceLinkFlows(payload);
+ NodeSelection nodeSelection =
+ new NodeSelection(payload, deviceService, hostService);
+ tmo.monitor(Mode.DEV_LINK_FLOWS, nodeSelection);
+ }
+ }
+
+ private final class ReqRelatedIntents extends RequestHandler {
+ private ReqRelatedIntents() {
+ super(REQ_RELATED_INTENTS);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ NodeSelection nodeSelection =
+ new NodeSelection(payload, deviceService, hostService);
+ tmo.monitor(Mode.RELATED_INTENTS, nodeSelection);
+ }
+ }
+
+ private final class ReqNextIntent extends RequestHandler {
+ private ReqNextIntent() {
+ super(REQ_NEXT_INTENT);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ tmo.selectNextIntent();
+ }
+ }
+
+ private final class ReqPrevIntent extends RequestHandler {
+ private ReqPrevIntent() {
+ super(REQ_PREV_INTENT);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ tmo.selectPreviousIntent();
+ }
+ }
+
+ private final class ReqSelectedIntentTraffic extends RequestHandler {
+ private ReqSelectedIntentTraffic() {
+ super(REQ_SEL_INTENT_TRAFFIC);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ tmo.monitor(Mode.SEL_INTENT);
}
}
@@ -563,14 +527,16 @@
@Override
public void process(long sid, ObjectNode payload) {
- selectedIntents = null;
- sendMessage(trafficMessage());
- stopTrafficMonitoring();
+ tmo.stop();
}
}
//=======================================================================
+ // Converts highlights to JSON format and sends the message to the client
+ protected void sendHighlights(Highlights highlights) {
+ sendMessage(JsonUtils.envelope(SHOW_HIGHLIGHTS, json(highlights)));
+ }
// Sends the specified data to the client.
protected synchronized void sendMessage(ObjectNode data) {
@@ -591,7 +557,7 @@
private void cancelAllRequests() {
stopSummaryMonitoring();
- stopTrafficMonitoring();
+ tmo.stop();
}
// Sends all controller nodes to the client as node-added messages.
@@ -641,18 +607,6 @@
}
}
-
- private synchronized void startMonitoringIntent(Intent intent) {
- selectedHosts = new HashSet<>();
- selectedDevices = new HashSet<>();
- selectedIntents = new ArrayList<>();
- selectedIntents.add(intent);
- currentIntentIndex = -1;
- requestAnotherRelatedIntent(+1);
- requestSelectedIntentTraffic();
- }
-
-
private Set<ConnectPoint> getHostLocations(Set<HostId> hostIds) {
Set<ConnectPoint> points = new HashSet<>();
for (HostId hostId : hostIds) {
@@ -675,121 +629,10 @@
}
- private synchronized void startTrafficMonitoring() {
- stopTrafficMonitoring();
- trafficTask = new TrafficMonitor();
- timer.schedule(trafficTask, TRAFFIC_FREQUENCY, TRAFFIC_FREQUENCY);
- }
-
- private synchronized void stopTrafficMonitoring() {
- if (trafficTask != null) {
- trafficTask.cancel();
- trafficTask = null;
- }
- }
-
- // Subscribes for flow traffic messages.
- private synchronized void requestAllFlowTraffic() {
- startTrafficMonitoring();
- sendMessage(trafficSummaryMessage(StatsType.FLOW));
- }
-
- // Subscribes for port traffic messages.
- private synchronized void requestAllPortTraffic() {
- startTrafficMonitoring();
- sendMessage(trafficSummaryMessage(StatsType.PORT));
- }
-
- private void requestDeviceLinkFlows(ObjectNode payload) {
- startTrafficMonitoring();
-
- // Get the set of selected hosts and their intents.
- ArrayNode ids = (ArrayNode) payload.path(IDS);
- Set<Host> hosts = new HashSet<>();
- Set<Device> devices = getDevices(ids);
-
- // If there is a hover node, include it in the hosts and find intents.
- String hover = JsonUtils.string(payload, HOVER);
- if (!isNullOrEmpty(hover)) {
- addHover(hosts, devices, hover);
- }
- sendMessage(flowSummaryMessage(devices));
- }
-
-
- private boolean haveSelectedIntents() {
- return selectedIntents != null && !selectedIntents.isEmpty();
- }
-
- // Processes the selection extended with hovered item to segregate items
- // into primary (those including the hover) vs secondary highlights.
- private void processHoverExtendedSelection(long sid, String hover) {
- Set<Host> hoverSelHosts = new HashSet<>(selectedHosts);
- Set<Device> hoverSelDevices = new HashSet<>(selectedDevices);
- addHover(hoverSelHosts, hoverSelDevices, hover);
-
- List<Intent> primary = selectedIntents == null ? new ArrayList<>() :
- 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(new TrafficClass(PRIMARY, primary),
- new TrafficClass(SECONDARY, secondary)));
- }
-
- // Requests next or previous related intent.
- private void requestAnotherRelatedIntent(int offset) {
- if (haveSelectedIntents()) {
- currentIntentIndex = currentIntentIndex + offset;
- if (currentIntentIndex < 0) {
- currentIntentIndex = selectedIntents.size() - 1;
- } else if (currentIntentIndex >= selectedIntents.size()) {
- currentIntentIndex = 0;
- }
- sendSelectedIntent();
- }
- }
-
- // Sends traffic information on the related intents with the currently
- // selected intent highlighted.
- private void sendSelectedIntent() {
- Intent selectedIntent = selectedIntents.get(currentIntentIndex);
- log.debug("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(new TrafficClass(PRIMARY, primary),
- new TrafficClass(SECONDARY, secondary)));
- }
-
- // Requests monitoring of traffic for the selected intent.
- private void requestSelectedIntentTraffic() {
- if (haveSelectedIntents()) {
- if (currentIntentIndex < 0) {
- currentIntentIndex = 0;
- }
- Intent selectedIntent = selectedIntents.get(currentIntentIndex);
- log.debug("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(new TrafficClass(PRIMARY, primary, true)));
- }
- }
-
private synchronized void startSummaryMonitoring() {
stopSummaryMonitoring();
summaryTask = new SummaryMonitor();
- timer.schedule(summaryTask, SUMMARY_FREQUENCY, SUMMARY_FREQUENCY);
+ timer.schedule(summaryTask, SUMMARY_PERIOD, SUMMARY_PERIOD);
summaryRunning = true;
}
@@ -883,9 +726,7 @@
private class InternalIntentListener implements IntentListener {
@Override
public void event(IntentEvent event) {
- if (trafficTask != null) {
- msgSender.execute(TopologyViewMessageHandler.this::requestSelectedIntentTraffic);
- }
+ msgSender.execute(tmo::pokeIntent);
eventAccummulator.add(event);
}
}
@@ -898,51 +739,8 @@
}
}
- // encapsulate
- private static class TrafficEvent {
- enum Type {
- ALL_FLOW_TRAFFIC, ALL_PORT_TRAFFIC, DEV_LINK_FLOWS, SEL_INTENT
- }
- private final Type type;
- private final ObjectNode payload;
-
- TrafficEvent(Type type, ObjectNode payload) {
- this.type = type;
- this.payload = payload;
- }
- }
-
- // Periodic update of the traffic information
- private class TrafficMonitor extends TimerTask {
- @Override
- public void run() {
- try {
- if (trafficEvent != null) {
- switch (trafficEvent.type) {
- case ALL_FLOW_TRAFFIC:
- requestAllFlowTraffic();
- break;
- case ALL_PORT_TRAFFIC:
- requestAllPortTraffic();
- break;
- case DEV_LINK_FLOWS:
- requestDeviceLinkFlows(trafficEvent.payload);
- break;
- case SEL_INTENT:
- requestSelectedIntentTraffic();
- break;
- default:
- // nothing to do
- break;
- }
- }
- } catch (Exception e) {
- log.warn("Unable to handle traffic request due to {}", e.getMessage());
- log.warn("Boom!", e);
- }
- }
- }
+ // === SUMMARY MONITORING
// Periodic update of the summary information
private class SummaryMonitor extends TimerTask {
@@ -967,7 +765,7 @@
@Override
public void processItems(List<Event> items) {
- // Start-of-Debugging
+ // Start-of-Debugging -- Keep in until ONOS-2572 is fixed for reals
long now = System.currentTimeMillis();
String me = this.toString();
String miniMe = me.replaceAll("^.*@", "me@");