ONOS-2186 - GUI Topo Overlay - (WIP)
- added isActive() predicate to UiTopoOverlay. - auto-select single intent in an intent selection group. - clean up mouse over/out handling. Change-Id: I0f951bd26fcfc791d73bb8121ebbe002086294ea
Showing
8 changed files
with
69 additions
and
28 deletions
| ... | @@ -33,6 +33,8 @@ public class UiTopoOverlay { | ... | @@ -33,6 +33,8 @@ public class UiTopoOverlay { |
| 33 | 33 | ||
| 34 | private final String id; | 34 | private final String id; |
| 35 | 35 | ||
| 36 | + private boolean isActive = false; | ||
| 37 | + | ||
| 36 | /** | 38 | /** |
| 37 | * Creates a new user interface topology view overlay descriptor. | 39 | * Creates a new user interface topology view overlay descriptor. |
| 38 | * | 40 | * |
| ... | @@ -62,14 +64,23 @@ public class UiTopoOverlay { | ... | @@ -62,14 +64,23 @@ public class UiTopoOverlay { |
| 62 | * Callback invoked when this overlay is activated. | 64 | * Callback invoked when this overlay is activated. |
| 63 | */ | 65 | */ |
| 64 | public void activate() { | 66 | public void activate() { |
| 65 | - log.debug("Overlay '{}' Activated", id); | 67 | + isActive = true; |
| 66 | } | 68 | } |
| 67 | 69 | ||
| 68 | /** | 70 | /** |
| 69 | * Callback invoked when this overlay is deactivated. | 71 | * Callback invoked when this overlay is deactivated. |
| 70 | */ | 72 | */ |
| 71 | public void deactivate() { | 73 | public void deactivate() { |
| 72 | - log.debug("Overlay '{}' Deactivated", id); | 74 | + isActive = false; |
| 75 | + } | ||
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * Returns true if this overlay is currently active. | ||
| 79 | + * | ||
| 80 | + * @return true if overlay active | ||
| 81 | + */ | ||
| 82 | + public boolean isActive() { | ||
| 83 | + return isActive; | ||
| 73 | } | 84 | } |
| 74 | 85 | ||
| 75 | /** | 86 | /** | ... | ... |
| ... | @@ -30,6 +30,7 @@ import static com.google.common.base.Strings.isNullOrEmpty; | ... | @@ -30,6 +30,7 @@ import static com.google.common.base.Strings.isNullOrEmpty; |
| 30 | */ | 30 | */ |
| 31 | public class TopoOverlayCache { | 31 | public class TopoOverlayCache { |
| 32 | 32 | ||
| 33 | + private static final String EMPTY = ""; | ||
| 33 | private static final UiTopoOverlay NONE = new NullOverlay(); | 34 | private static final UiTopoOverlay NONE = new NullOverlay(); |
| 34 | 35 | ||
| 35 | private final Map<String, UiTopoOverlay> overlays = new HashMap<>(); | 36 | private final Map<String, UiTopoOverlay> overlays = new HashMap<>(); |
| ... | @@ -95,20 +96,21 @@ public class TopoOverlayCache { | ... | @@ -95,20 +96,21 @@ public class TopoOverlayCache { |
| 95 | return overlays.size(); | 96 | return overlays.size(); |
| 96 | } | 97 | } |
| 97 | 98 | ||
| 99 | + /** | ||
| 100 | + * Returns true if the identifier of the currently active overlay | ||
| 101 | + * matches the given parameter. | ||
| 102 | + * | ||
| 103 | + * @param overlayId overlay identifier | ||
| 104 | + * @return true if this matches the ID of currently active overlay | ||
| 105 | + */ | ||
| 106 | + public boolean isActive(String overlayId) { | ||
| 107 | + return currentOverlay().id().equals(overlayId); | ||
| 108 | + } | ||
| 98 | 109 | ||
| 99 | // overlay instance representing "no overlay selected" | 110 | // overlay instance representing "no overlay selected" |
| 100 | private static class NullOverlay extends UiTopoOverlay { | 111 | private static class NullOverlay extends UiTopoOverlay { |
| 101 | public NullOverlay() { | 112 | public NullOverlay() { |
| 102 | - super(null); | 113 | + super(EMPTY); |
| 103 | - } | ||
| 104 | - | ||
| 105 | - // override activate and deactivate, so no log messages are written | ||
| 106 | - @Override | ||
| 107 | - public void activate() { | ||
| 108 | - } | ||
| 109 | - | ||
| 110 | - @Override | ||
| 111 | - public void deactivate() { | ||
| 112 | } | 114 | } |
| 113 | } | 115 | } |
| 114 | } | 116 | } | ... | ... |
| ... | @@ -399,9 +399,11 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -399,9 +399,11 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 399 | .build(); | 399 | .build(); |
| 400 | 400 | ||
| 401 | intentService.submit(intent); | 401 | intentService.submit(intent); |
| 402 | + if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) { | ||
| 402 | traffic.monitor(intent); | 403 | traffic.monitor(intent); |
| 403 | } | 404 | } |
| 404 | } | 405 | } |
| 406 | + } | ||
| 405 | 407 | ||
| 406 | private final class AddMultiSourceIntent extends RequestHandler { | 408 | private final class AddMultiSourceIntent extends RequestHandler { |
| 407 | private AddMultiSourceIntent() { | 409 | private AddMultiSourceIntent() { |
| ... | @@ -432,9 +434,11 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -432,9 +434,11 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
| 432 | .build(); | 434 | .build(); |
| 433 | 435 | ||
| 434 | intentService.submit(intent); | 436 | intentService.submit(intent); |
| 437 | + if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) { | ||
| 435 | traffic.monitor(intent); | 438 | traffic.monitor(intent); |
| 436 | } | 439 | } |
| 437 | } | 440 | } |
| 441 | + } | ||
| 438 | 442 | ||
| 439 | // ========= ----------------------------------------------------------------- | 443 | // ========= ----------------------------------------------------------------- |
| 440 | 444 | ... | ... |
| ... | @@ -25,7 +25,10 @@ import org.onosproject.ui.topo.PropertyPanel; | ... | @@ -25,7 +25,10 @@ import org.onosproject.ui.topo.PropertyPanel; |
| 25 | * Topology Overlay for network traffic. | 25 | * Topology Overlay for network traffic. |
| 26 | */ | 26 | */ |
| 27 | public class TrafficOverlay extends UiTopoOverlay { | 27 | public class TrafficOverlay extends UiTopoOverlay { |
| 28 | - private static final String TRAFFIC_ID = "traffic"; | 28 | + /** |
| 29 | + * Traffic Overlay identifier. | ||
| 30 | + */ | ||
| 31 | + public static final String TRAFFIC_ID = "traffic"; | ||
| 29 | 32 | ||
| 30 | private static final String SDF_ID = "showDeviceFlows"; | 33 | private static final String SDF_ID = "showDeviceFlows"; |
| 31 | private static final String SRT_ID = "showRelatedTraffic"; | 34 | private static final String SRT_ID = "showRelatedTraffic"; |
| ... | @@ -38,10 +41,22 @@ public class TrafficOverlay extends UiTopoOverlay { | ... | @@ -38,10 +41,22 @@ public class TrafficOverlay extends UiTopoOverlay { |
| 38 | super(TRAFFIC_ID); | 41 | super(TRAFFIC_ID); |
| 39 | } | 42 | } |
| 40 | 43 | ||
| 44 | + // override activate and deactivate, to write log messages | ||
| 45 | + @Override | ||
| 46 | + public void activate() { | ||
| 47 | + super.activate(); | ||
| 48 | + log.debug("TrafficOverlay Activated"); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + @Override | ||
| 52 | + public void deactivate() { | ||
| 53 | + super.deactivate(); | ||
| 54 | + log.debug("TrafficOverlay Deactivated"); | ||
| 55 | + } | ||
| 56 | + | ||
| 41 | @Override | 57 | @Override |
| 42 | public void modifyDeviceDetails(PropertyPanel pp) { | 58 | public void modifyDeviceDetails(PropertyPanel pp) { |
| 43 | pp.addButton(SHOW_DEVICE_FLOWS) | 59 | pp.addButton(SHOW_DEVICE_FLOWS) |
| 44 | .addButton(SHOW_RELATED_TRAFFIC); | 60 | .addButton(SHOW_RELATED_TRAFFIC); |
| 45 | } | 61 | } |
| 46 | - | ||
| 47 | } | 62 | } | ... | ... |
| ... | @@ -51,6 +51,9 @@ public class IntentSelection { | ... | @@ -51,6 +51,9 @@ public class IntentSelection { |
| 51 | public IntentSelection(NodeSelection nodes, TopoIntentFilter filter) { | 51 | public IntentSelection(NodeSelection nodes, TopoIntentFilter filter) { |
| 52 | this.nodes = nodes; | 52 | this.nodes = nodes; |
| 53 | intents = filter.findPathIntents(nodes.hosts(), nodes.devices()); | 53 | intents = filter.findPathIntents(nodes.hosts(), nodes.devices()); |
| 54 | + if (intents.size() == 1) { | ||
| 55 | + index = 0; // pre-select a single intent | ||
| 56 | + } | ||
| 54 | } | 57 | } |
| 55 | 58 | ||
| 56 | /** | 59 | /** | ... | ... |
| ... | @@ -229,9 +229,9 @@ | ... | @@ -229,9 +229,9 @@ |
| 229 | tps.displaySomething(); | 229 | tps.displaySomething(); |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | - // returns true if we are hovering over a node, or any nodes are selected | 232 | + // returns true if one or more nodes are selected. |
| 233 | function somethingSelected() { | 233 | function somethingSelected() { |
| 234 | - return hovered || nSel(); | 234 | + return nSel(); |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | function clickConsumed(x) { | 237 | function clickConsumed(x) { | ... | ... |
| ... | @@ -41,13 +41,15 @@ | ... | @@ -41,13 +41,15 @@ |
| 41 | // Helper functions | 41 | // Helper functions |
| 42 | 42 | ||
| 43 | // invoked in response to change in selection and/or mouseover/out: | 43 | // invoked in response to change in selection and/or mouseover/out: |
| 44 | - function requestTrafficForMode() { | 44 | + function requestTrafficForMode(mouse) { |
| 45 | if (trafficMode === 'flows') { | 45 | if (trafficMode === 'flows') { |
| 46 | requestDeviceLinkFlows(); | 46 | requestDeviceLinkFlows(); |
| 47 | } else if (trafficMode === 'intents') { | 47 | } else if (trafficMode === 'intents') { |
| 48 | + if (!mouse || hoverMode === 'intents') { | ||
| 48 | requestRelatedIntents(); | 49 | requestRelatedIntents(); |
| 50 | + } | ||
| 49 | } else { | 51 | } else { |
| 50 | - cancelTraffic(); | 52 | + // do nothing |
| 51 | } | 53 | } |
| 52 | } | 54 | } |
| 53 | 55 | ||
| ... | @@ -89,8 +91,8 @@ | ... | @@ -89,8 +91,8 @@ |
| 89 | // === ------------------------------------------------------------- | 91 | // === ------------------------------------------------------------- |
| 90 | // Traffic requests invoked from keystrokes or toolbar buttons... | 92 | // Traffic requests invoked from keystrokes or toolbar buttons... |
| 91 | 93 | ||
| 92 | - function cancelTraffic() { | 94 | + function cancelTraffic(forced) { |
| 93 | - if (!trafficMode) { | 95 | + if (!trafficMode || (!forced && trafficMode === 'allFlowPort')) { |
| 94 | return false; | 96 | return false; |
| 95 | } | 97 | } |
| 96 | 98 | ||
| ... | @@ -101,15 +103,15 @@ | ... | @@ -101,15 +103,15 @@ |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 103 | function showAllFlowTraffic() { | 105 | function showAllFlowTraffic() { |
| 104 | - trafficMode = 'allFlow'; | 106 | + trafficMode = 'allFlowPort'; |
| 105 | - hoverMode = 'all'; | 107 | + hoverMode = null; |
| 106 | wss.sendEvent('requestAllFlowTraffic'); | 108 | wss.sendEvent('requestAllFlowTraffic'); |
| 107 | flash.flash('All Flow Traffic'); | 109 | flash.flash('All Flow Traffic'); |
| 108 | } | 110 | } |
| 109 | 111 | ||
| 110 | function showAllPortTraffic() { | 112 | function showAllPortTraffic() { |
| 111 | - trafficMode = 'allPort'; | 113 | + trafficMode = 'allFlowPort'; |
| 112 | - hoverMode = 'all'; | 114 | + hoverMode = null; |
| 113 | wss.sendEvent('requestAllPortTraffic'); | 115 | wss.sendEvent('requestAllPortTraffic'); |
| 114 | flash.flash('All Port Traffic'); | 116 | flash.flash('All Port Traffic'); |
| 115 | } | 117 | } |
| ... | @@ -161,6 +163,8 @@ | ... | @@ -161,6 +163,8 @@ |
| 161 | two: so[1], | 163 | two: so[1], |
| 162 | ids: so | 164 | ids: so |
| 163 | }); | 165 | }); |
| 166 | + trafficMode = 'intents'; | ||
| 167 | + hoverMode = null; | ||
| 164 | flash.flash('Host-to-Host flow added'); | 168 | flash.flash('Host-to-Host flow added'); |
| 165 | } | 169 | } |
| 166 | 170 | ||
| ... | @@ -171,6 +175,8 @@ | ... | @@ -171,6 +175,8 @@ |
| 171 | dst: so[so.length - 1], | 175 | dst: so[so.length - 1], |
| 172 | ids: so | 176 | ids: so |
| 173 | }); | 177 | }); |
| 178 | + trafficMode = 'intents'; | ||
| 179 | + hoverMode = null; | ||
| 174 | flash.flash('Multi-Source flow added'); | 180 | flash.flash('Multi-Source flow added'); |
| 175 | } | 181 | } |
| 176 | 182 | ... | ... |
| ... | @@ -45,7 +45,7 @@ | ... | @@ -45,7 +45,7 @@ |
| 45 | }, | 45 | }, |
| 46 | 46 | ||
| 47 | deactivate: function () { | 47 | deactivate: function () { |
| 48 | - tts.cancelTraffic(); | 48 | + tts.cancelTraffic(true); |
| 49 | $log.debug("Traffic overlay DEACTIVATED"); | 49 | $log.debug("Traffic overlay DEACTIVATED"); |
| 50 | }, | 50 | }, |
| 51 | 51 | ||
| ... | @@ -69,7 +69,7 @@ | ... | @@ -69,7 +69,7 @@ |
| 69 | // NOTE: fully qual. button ID is derived from overlay-id and key-name | 69 | // NOTE: fully qual. button ID is derived from overlay-id and key-name |
| 70 | keyBindings: { | 70 | keyBindings: { |
| 71 | 0: { | 71 | 0: { |
| 72 | - cb: function () { tts.cancelTraffic(); }, | 72 | + cb: function () { tts.cancelTraffic(true); }, |
| 73 | tt: 'Cancel traffic monitoring', | 73 | tt: 'Cancel traffic monitoring', |
| 74 | gid: 'xMark' | 74 | gid: 'xMark' |
| 75 | }, | 75 | }, |
| ... | @@ -137,10 +137,10 @@ | ... | @@ -137,10 +137,10 @@ |
| 137 | // mouse hooks | 137 | // mouse hooks |
| 138 | mouseover: function (m) { | 138 | mouseover: function (m) { |
| 139 | // m has id, class, and type properties | 139 | // m has id, class, and type properties |
| 140 | - tts.requestTrafficForMode(); | 140 | + tts.requestTrafficForMode(true); |
| 141 | }, | 141 | }, |
| 142 | mouseout: function () { | 142 | mouseout: function () { |
| 143 | - tts.requestTrafficForMode(); | 143 | + tts.requestTrafficForMode(true); |
| 144 | } | 144 | } |
| 145 | } | 145 | } |
| 146 | }; | 146 | }; | ... | ... |
-
Please register or login to post a comment