Simon Hunt
Committed by Gerrit Code Review

ONOS-2186 - GUI Topo Overlay - (WIP)

- added devicesWithHover(), hostsWithHover(), hovered() to NodeSelection.
- wrote unit tests for NodeSelection.

Change-Id: I6dca0f4f0a4ce2412438c8411102034969ef4343
...@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode; ...@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode;
21 import com.fasterxml.jackson.databind.node.ArrayNode; 21 import com.fasterxml.jackson.databind.node.ArrayNode;
22 import com.fasterxml.jackson.databind.node.ObjectNode; 22 import com.fasterxml.jackson.databind.node.ObjectNode;
23 import org.onosproject.net.Device; 23 import org.onosproject.net.Device;
24 +import org.onosproject.net.Element;
24 import org.onosproject.net.Host; 25 import org.onosproject.net.Host;
25 import org.onosproject.net.device.DeviceService; 26 import org.onosproject.net.device.DeviceService;
26 import org.onosproject.net.host.HostService; 27 import org.onosproject.net.host.HostService;
...@@ -55,10 +56,12 @@ public class NodeSelection { ...@@ -55,10 +56,12 @@ public class NodeSelection {
55 56
56 private final Set<Device> devices = new HashSet<>(); 57 private final Set<Device> devices = new HashSet<>();
57 private final Set<Host> hosts = new HashSet<>(); 58 private final Set<Host> hosts = new HashSet<>();
59 + private Element hovered;
58 60
59 /** 61 /**
60 * Creates a node selection entity, from the given payload, using the 62 * Creates a node selection entity, from the given payload, using the
61 - * supplied device and host services. 63 + * supplied device and host services. Note that if a device or host was
64 + * hovered over by the mouse, it is available via {@link #hovered()}.
62 * 65 *
63 * @param payload message payload 66 * @param payload message payload
64 * @param deviceService device service 67 * @param deviceService device service
...@@ -73,25 +76,24 @@ public class NodeSelection { ...@@ -73,25 +76,24 @@ public class NodeSelection {
73 ids = extractIds(payload); 76 ids = extractIds(payload);
74 hover = extractHover(payload); 77 hover = extractHover(payload);
75 78
79 + // start by extracting the hovered element if any
80 + if (isNullOrEmpty(hover)) {
81 + hovered = null;
82 + } else {
83 + setHoveredElement();
84 + }
85 +
86 + // now go find the devices and hosts that are in the selection list
76 Set<String> unmatched = findDevices(ids); 87 Set<String> unmatched = findDevices(ids);
77 unmatched = findHosts(unmatched); 88 unmatched = findHosts(unmatched);
78 if (unmatched.size() > 0) { 89 if (unmatched.size() > 0) {
79 log.debug("Skipping unmatched IDs {}", unmatched); 90 log.debug("Skipping unmatched IDs {}", unmatched);
80 } 91 }
81 92
82 - if (!isNullOrEmpty(hover)) {
83 - unmatched = new HashSet<>();
84 - unmatched.add(hover);
85 - unmatched = findDevices(unmatched);
86 - unmatched = findHosts(unmatched);
87 - if (unmatched.size() > 0) {
88 - log.debug("Skipping unmatched HOVER {}", unmatched);
89 - }
90 - }
91 } 93 }
92 94
93 /** 95 /**
94 - * Returns a view of the selected devices. 96 + * Returns a view of the selected devices (hover not included).
95 * 97 *
96 * @return selected devices 98 * @return selected devices
97 */ 99 */
...@@ -100,7 +102,24 @@ public class NodeSelection { ...@@ -100,7 +102,24 @@ public class NodeSelection {
100 } 102 }
101 103
102 /** 104 /**
103 - * Returns a view of the selected hosts. 105 + * Returns a view of the selected devices, including the hovered device
106 + * if there was one.
107 + *
108 + * @return selected (plus hovered) devices
109 + */
110 + public Set<Device> devicesWithHover() {
111 + Set<Device> withHover;
112 + if (hovered != null && hovered instanceof Device) {
113 + withHover = new HashSet<>(devices);
114 + withHover.add((Device) hovered);
115 + } else {
116 + withHover = devices;
117 + }
118 + return Collections.unmodifiableSet(withHover);
119 + }
120 +
121 + /**
122 + * Returns a view of the selected hosts (hover not included).
104 * 123 *
105 * @return selected hosts 124 * @return selected hosts
106 */ 125 */
...@@ -109,6 +128,33 @@ public class NodeSelection { ...@@ -109,6 +128,33 @@ public class NodeSelection {
109 } 128 }
110 129
111 /** 130 /**
131 + * Returns a view of the selected hosts, including the hovered host
132 + * if thee was one.
133 + *
134 + * @return selected (plus hovered) hosts
135 + */
136 + public Set<Host> hostsWithHover() {
137 + Set<Host> withHover;
138 + if (hovered != null && hovered instanceof Host) {
139 + withHover = new HashSet<>(hosts);
140 + withHover.add((Host) hovered);
141 + } else {
142 + withHover = hosts;
143 + }
144 + return Collections.unmodifiableSet(withHover);
145 + }
146 +
147 + /**
148 + * Returns the element (host or device) over which the mouse was hovering,
149 + * or null.
150 + *
151 + * @return element hovered over
152 + */
153 + public Element hovered() {
154 + return hovered;
155 + }
156 +
157 + /**
112 * Returns true if nothing is selected. 158 * Returns true if nothing is selected.
113 * 159 *
114 * @return true if nothing selected 160 * @return true if nothing selected
...@@ -146,6 +192,26 @@ public class NodeSelection { ...@@ -146,6 +192,26 @@ public class NodeSelection {
146 return JsonUtils.string(payload, HOVER); 192 return JsonUtils.string(payload, HOVER);
147 } 193 }
148 194
195 + private void setHoveredElement() {
196 + Set<String> unmatched;
197 + unmatched = new HashSet<>();
198 + unmatched.add(hover);
199 + unmatched = findDevices(unmatched);
200 + if (devices.size() == 1) {
201 + hovered = devices.iterator().next();
202 + devices.clear();
203 + } else {
204 + unmatched = findHosts(unmatched);
205 + if (hosts.size() == 1) {
206 + hovered = hosts.iterator().next();
207 + hosts.clear();
208 + } else {
209 + hovered = null;
210 + log.debug("Skipping unmatched HOVER {}", unmatched);
211 + }
212 + }
213 + }
214 +
149 private Set<String> findDevices(Set<String> ids) { 215 private Set<String> findDevices(Set<String> ids) {
150 Set<String> unmatched = new HashSet<>(); 216 Set<String> unmatched = new HashSet<>();
151 Device device; 217 Device device;
...@@ -156,9 +222,9 @@ public class NodeSelection { ...@@ -156,9 +222,9 @@ public class NodeSelection {
156 if (device != null) { 222 if (device != null) {
157 devices.add(device); 223 devices.add(device);
158 } else { 224 } else {
159 - log.debug("Device with ID {} not found", id); 225 + unmatched.add(id);
160 } 226 }
161 - } catch (IllegalArgumentException e) { 227 + } catch (Exception e) {
162 unmatched.add(id); 228 unmatched.add(id);
163 } 229 }
164 } 230 }
...@@ -175,9 +241,9 @@ public class NodeSelection { ...@@ -175,9 +241,9 @@ public class NodeSelection {
175 if (host != null) { 241 if (host != null) {
176 hosts.add(host); 242 hosts.add(host);
177 } else { 243 } else {
178 - log.debug("Host with ID {} not found", id); 244 + unmatched.add(id);
179 } 245 }
180 - } catch (IllegalArgumentException e) { 246 + } catch (Exception e) {
181 unmatched.add(id); 247 unmatched.add(id);
182 } 248 }
183 } 249 }
......
...@@ -186,7 +186,7 @@ public class TrafficMonitor { ...@@ -186,7 +186,7 @@ public class TrafficMonitor {
186 switch (mode) { 186 switch (mode) {
187 case DEV_LINK_FLOWS: 187 case DEV_LINK_FLOWS:
188 // only care about devices (not hosts) 188 // only care about devices (not hosts)
189 - if (selectedNodes.devices().isEmpty()) { 189 + if (selectedNodes.devicesWithHover().isEmpty()) {
190 sendClearAll(); 190 sendClearAll();
191 } else { 191 } else {
192 scheduleTask(); 192 scheduleTask();
...@@ -371,11 +371,11 @@ public class TrafficMonitor { ...@@ -371,11 +371,11 @@ public class TrafficMonitor {
371 private Highlights deviceLinkFlows() { 371 private Highlights deviceLinkFlows() {
372 Highlights highlights = new Highlights(); 372 Highlights highlights = new Highlights();
373 373
374 - if (selectedNodes != null && !selectedNodes.devices().isEmpty()) { 374 + if (selectedNodes != null && !selectedNodes.devicesWithHover().isEmpty()) {
375 // capture flow counts on bilinks 375 // capture flow counts on bilinks
376 TrafficLinkMap linkMap = new TrafficLinkMap(); 376 TrafficLinkMap linkMap = new TrafficLinkMap();
377 377
378 - for (Device device : selectedNodes.devices()) { 378 + for (Device device : selectedNodes.devicesWithHover()) {
379 Map<Link, Integer> counts = getLinkFlowCounts(device.id()); 379 Map<Link, Integer> counts = getLinkFlowCounts(device.id());
380 for (Link link : counts.keySet()) { 380 for (Link link : counts.keySet()) {
381 TrafficLink tlink = linkMap.add(link); 381 TrafficLink tlink = linkMap.add(link);
......
...@@ -50,7 +50,7 @@ public class IntentSelection { ...@@ -50,7 +50,7 @@ public class IntentSelection {
50 */ 50 */
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.hostsWithHover(), nodes.devicesWithHover());
54 if (intents.size() == 1) { 54 if (intents.size() == 1) {
55 index = 0; // pre-select a single intent 55 index = 0; // pre-select a single intent
56 } 56 }
......