Committed by
Gerrit Code Review
ONOS-1479 -- GUI - augmenting topology view for extensibility:
- Added id field to property panel, as well as overloaded constructors. - Added modify*Details() methods to UiTopoOverlay. - Cleaned up use of string constants. - Reworked RequestDetails in Topo view msg handler (and base). - Fixed bug in topo UI where selected host title click caused exception on server. Change-Id: Ib2a3cf60fae8ad8cda77a3b6933ee758262e6f3c
Showing
7 changed files
with
224 additions
and
105 deletions
... | @@ -38,9 +38,7 @@ public final class JsonUtils { | ... | @@ -38,9 +38,7 @@ public final class JsonUtils { |
38 | * @param sid sequence ID | 38 | * @param sid sequence ID |
39 | * @param payload event payload | 39 | * @param payload event payload |
40 | * @return the object node representation | 40 | * @return the object node representation |
41 | - * @deprecated in Cardinal Release | ||
42 | */ | 41 | */ |
43 | - @Deprecated | ||
44 | public static ObjectNode envelope(String type, long sid, ObjectNode payload) { | 42 | public static ObjectNode envelope(String type, long sid, ObjectNode payload) { |
45 | ObjectNode event = MAPPER.createObjectNode(); | 43 | ObjectNode event = MAPPER.createObjectNode(); |
46 | event.put("event", type); | 44 | event.put("event", type); | ... | ... |
... | @@ -26,7 +26,10 @@ import org.slf4j.LoggerFactory; | ... | @@ -26,7 +26,10 @@ import org.slf4j.LoggerFactory; |
26 | */ | 26 | */ |
27 | public class UiTopoOverlay { | 27 | public class UiTopoOverlay { |
28 | 28 | ||
29 | - private final Logger log = LoggerFactory.getLogger(getClass()); | 29 | + /** |
30 | + * Logger for this overlay. | ||
31 | + */ | ||
32 | + protected final Logger log = LoggerFactory.getLogger(getClass()); | ||
30 | 33 | ||
31 | private final String id; | 34 | private final String id; |
32 | 35 | ||
... | @@ -72,7 +75,7 @@ public class UiTopoOverlay { | ... | @@ -72,7 +75,7 @@ public class UiTopoOverlay { |
72 | /** | 75 | /** |
73 | * Callback invoked to destroy this instance by cleaning up any | 76 | * Callback invoked to destroy this instance by cleaning up any |
74 | * internal state ready for garbage collection. | 77 | * internal state ready for garbage collection. |
75 | - * This default implementation does nothing. | 78 | + * This default implementation holds no state and does nothing. |
76 | */ | 79 | */ |
77 | public void destroy() { | 80 | public void destroy() { |
78 | } | 81 | } |
... | @@ -85,4 +88,24 @@ public class UiTopoOverlay { | ... | @@ -85,4 +88,24 @@ public class UiTopoOverlay { |
85 | */ | 88 | */ |
86 | public void modifySummary(PropertyPanel pp) { | 89 | public void modifySummary(PropertyPanel pp) { |
87 | } | 90 | } |
91 | + | ||
92 | + /** | ||
93 | + * Callback to modify the contents of the details panel for | ||
94 | + * a selected device. | ||
95 | + * This default implementation does nothing. | ||
96 | + * | ||
97 | + * @param pp property panel model of summary data | ||
98 | + */ | ||
99 | + public void modifyDeviceDetails(PropertyPanel pp) { | ||
100 | + } | ||
101 | + | ||
102 | + /** | ||
103 | + * Callback to modify the contents of the details panel for | ||
104 | + * a selected host. | ||
105 | + * This default implementation does nothing. | ||
106 | + * | ||
107 | + * @param pp property panel model of summary data | ||
108 | + */ | ||
109 | + public void modifyHostDetails(PropertyPanel pp) { | ||
110 | + } | ||
88 | } | 111 | } | ... | ... |
... | @@ -19,6 +19,7 @@ package org.onosproject.ui.topo; | ... | @@ -19,6 +19,7 @@ package org.onosproject.ui.topo; |
19 | 19 | ||
20 | import com.google.common.collect.Sets; | 20 | import com.google.common.collect.Sets; |
21 | 21 | ||
22 | +import java.text.DecimalFormat; | ||
22 | import java.util.ArrayList; | 23 | import java.util.ArrayList; |
23 | import java.util.List; | 24 | import java.util.List; |
24 | import java.util.Set; | 25 | import java.util.Set; |
... | @@ -30,6 +31,7 @@ public class PropertyPanel { | ... | @@ -30,6 +31,7 @@ public class PropertyPanel { |
30 | 31 | ||
31 | private String title; | 32 | private String title; |
32 | private String typeId; | 33 | private String typeId; |
34 | + private String id; | ||
33 | private List<Prop> properties = new ArrayList<>(); | 35 | private List<Prop> properties = new ArrayList<>(); |
34 | 36 | ||
35 | /** | 37 | /** |
... | @@ -56,6 +58,19 @@ public class PropertyPanel { | ... | @@ -56,6 +58,19 @@ public class PropertyPanel { |
56 | } | 58 | } |
57 | 59 | ||
58 | /** | 60 | /** |
61 | + * Adds an ID field to the panel data, to be included in | ||
62 | + * the returned JSON data to the client. | ||
63 | + * | ||
64 | + * @param id the identifier | ||
65 | + * @return self, for chaining | ||
66 | + */ | ||
67 | + public PropertyPanel id(String id) { | ||
68 | + this.id = id; | ||
69 | + return this; | ||
70 | + } | ||
71 | + | ||
72 | + | ||
73 | + /** | ||
59 | * Returns the title text. | 74 | * Returns the title text. |
60 | * | 75 | * |
61 | * @return title text | 76 | * @return title text |
... | @@ -74,6 +89,15 @@ public class PropertyPanel { | ... | @@ -74,6 +89,15 @@ public class PropertyPanel { |
74 | } | 89 | } |
75 | 90 | ||
76 | /** | 91 | /** |
92 | + * Returns the internal ID. | ||
93 | + * | ||
94 | + * @return the ID | ||
95 | + */ | ||
96 | + public String id() { | ||
97 | + return id; | ||
98 | + } | ||
99 | + | ||
100 | + /** | ||
77 | * Returns the list of properties to be displayed. | 101 | * Returns the list of properties to be displayed. |
78 | * | 102 | * |
79 | * @return the property list | 103 | * @return the property list |
... | @@ -137,6 +161,8 @@ public class PropertyPanel { | ... | @@ -137,6 +161,8 @@ public class PropertyPanel { |
137 | 161 | ||
138 | // ==================== | 162 | // ==================== |
139 | 163 | ||
164 | + private static final DecimalFormat DF0 = new DecimalFormat("#,###"); | ||
165 | + | ||
140 | /** | 166 | /** |
141 | * Simple data carrier for a property, composed of a key/value pair. | 167 | * Simple data carrier for a property, composed of a key/value pair. |
142 | */ | 168 | */ |
... | @@ -156,6 +182,26 @@ public class PropertyPanel { | ... | @@ -156,6 +182,26 @@ public class PropertyPanel { |
156 | } | 182 | } |
157 | 183 | ||
158 | /** | 184 | /** |
185 | + * Constructs a property data value. | ||
186 | + * @param key property key | ||
187 | + * @param value property value | ||
188 | + */ | ||
189 | + public Prop(String key, int value) { | ||
190 | + this.key = key; | ||
191 | + this.value = DF0.format(value); | ||
192 | + } | ||
193 | + | ||
194 | + /** | ||
195 | + * Constructs a property data value. | ||
196 | + * @param key property key | ||
197 | + * @param value property value | ||
198 | + */ | ||
199 | + public Prop(String key, long value) { | ||
200 | + this.key = key; | ||
201 | + this.value = DF0.format(value); | ||
202 | + } | ||
203 | + | ||
204 | + /** | ||
159 | * Returns the property's key. | 205 | * Returns the property's key. |
160 | * | 206 | * |
161 | * @return the key | 207 | * @return the key | ... | ... |
... | @@ -74,12 +74,20 @@ public class TopoOverlayCache { | ... | @@ -74,12 +74,20 @@ public class TopoOverlayCache { |
74 | return isNullOrEmpty(id) ? NONE : overlays.get(id); | 74 | return isNullOrEmpty(id) ? NONE : overlays.get(id); |
75 | } | 75 | } |
76 | 76 | ||
77 | + /** | ||
78 | + * Returns the current overlay instance. | ||
79 | + * Note that this method always returns a reference; when there is no | ||
80 | + * overlay selected the "NULL" overlay instance is returned. | ||
81 | + * | ||
82 | + * @return the current overlay | ||
83 | + */ | ||
77 | public UiTopoOverlay currentOverlay() { | 84 | public UiTopoOverlay currentOverlay() { |
78 | return current; | 85 | return current; |
79 | } | 86 | } |
80 | 87 | ||
81 | /** | 88 | /** |
82 | - * Returns the number of overlays in the cache. | 89 | + * Returns the number of overlays in the cache. Remember that this |
90 | + * includes the "NULL" overlay, representing "no overlay selected". | ||
83 | * | 91 | * |
84 | * @return number of overlays | 92 | * @return number of overlays |
85 | */ | 93 | */ |
... | @@ -88,16 +96,13 @@ public class TopoOverlayCache { | ... | @@ -88,16 +96,13 @@ public class TopoOverlayCache { |
88 | } | 96 | } |
89 | 97 | ||
90 | 98 | ||
91 | - | 99 | + // overlay instance representing "no overlay selected" |
92 | private static class NullOverlay extends UiTopoOverlay { | 100 | private static class NullOverlay extends UiTopoOverlay { |
93 | public NullOverlay() { | 101 | public NullOverlay() { |
94 | super(null); | 102 | super(null); |
95 | } | 103 | } |
96 | 104 | ||
97 | - @Override | 105 | + // override activate and deactivate, so no log messages are written |
98 | - public void init() { | ||
99 | - } | ||
100 | - | ||
101 | @Override | 106 | @Override |
102 | public void activate() { | 107 | public void activate() { |
103 | } | 108 | } |
... | @@ -105,9 +110,5 @@ public class TopoOverlayCache { | ... | @@ -105,9 +110,5 @@ public class TopoOverlayCache { |
105 | @Override | 110 | @Override |
106 | public void deactivate() { | 111 | public void deactivate() { |
107 | } | 112 | } |
108 | - | ||
109 | - @Override | ||
110 | - public void destroy() { | ||
111 | - } | ||
112 | } | 113 | } |
113 | } | 114 | } | ... | ... |
... | @@ -85,6 +85,7 @@ import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED; | ... | @@ -85,6 +85,7 @@ import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED; |
85 | */ | 85 | */ |
86 | public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | 86 | public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
87 | 87 | ||
88 | + // incoming event types | ||
88 | private static final String REQ_DETAILS = "requestDetails"; | 89 | private static final String REQ_DETAILS = "requestDetails"; |
89 | private static final String UPDATE_META = "updateMeta"; | 90 | private static final String UPDATE_META = "updateMeta"; |
90 | private static final String ADD_HOST_INTENT = "addHostIntent"; | 91 | private static final String ADD_HOST_INTENT = "addHostIntent"; |
... | @@ -107,6 +108,33 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -107,6 +108,33 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
107 | private static final String TOPO_SELECT_OVERLAY = "topoSelectOverlay"; | 108 | private static final String TOPO_SELECT_OVERLAY = "topoSelectOverlay"; |
108 | private static final String TOPO_STOP = "topoStop"; | 109 | private static final String TOPO_STOP = "topoStop"; |
109 | 110 | ||
111 | + // outgoing event types | ||
112 | + private static final String SHOW_SUMMARY = "showSummary"; | ||
113 | + private static final String SHOW_DETAILS = "showDetails"; | ||
114 | + private static final String SPRITE_LIST_RESPONSE = "spriteListResponse"; | ||
115 | + private static final String SPRITE_DATA_RESPONSE = "spriteDataResponse"; | ||
116 | + private static final String UPDATE_INSTANCE = "updateInstance"; | ||
117 | + | ||
118 | + // fields | ||
119 | + private static final String ID = "id"; | ||
120 | + private static final String IDS = "ids"; | ||
121 | + private static final String HOVER = "hover"; | ||
122 | + private static final String DEVICE = "device"; | ||
123 | + private static final String HOST = "host"; | ||
124 | + private static final String CLASS = "class"; | ||
125 | + private static final String UNKNOWN = "unknown"; | ||
126 | + private static final String ONE = "one"; | ||
127 | + private static final String TWO = "two"; | ||
128 | + private static final String SRC = "src"; | ||
129 | + private static final String DST = "dst"; | ||
130 | + private static final String DATA = "data"; | ||
131 | + private static final String NAME = "name"; | ||
132 | + private static final String NAMES = "names"; | ||
133 | + private static final String ACTIVATE = "activate"; | ||
134 | + private static final String DEACTIVATE = "deactivate"; | ||
135 | + private static final String PRIMARY = "primary"; | ||
136 | + private static final String SECONDARY = "secondary"; | ||
137 | + | ||
110 | 138 | ||
111 | private static final String APP_ID = "org.onosproject.gui"; | 139 | private static final String APP_ID = "org.onosproject.gui"; |
112 | 140 | ||
... | @@ -244,8 +272,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -244,8 +272,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
244 | 272 | ||
245 | @Override | 273 | @Override |
246 | public void process(long sid, ObjectNode payload) { | 274 | public void process(long sid, ObjectNode payload) { |
247 | - String deact = string(payload, "deactivate"); | 275 | + String deact = string(payload, DEACTIVATE); |
248 | - String act = string(payload, "activate"); | 276 | + String act = string(payload, ACTIVATE); |
249 | overlayCache.switchOverlay(deact, act); | 277 | overlayCache.switchOverlay(deact, act); |
250 | } | 278 | } |
251 | } | 279 | } |
... | @@ -295,8 +323,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -295,8 +323,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
295 | ObjectNode root = objectNode(); | 323 | ObjectNode root = objectNode(); |
296 | ArrayNode names = arrayNode(); | 324 | ArrayNode names = arrayNode(); |
297 | get(SpriteService.class).getNames().forEach(names::add); | 325 | get(SpriteService.class).getNames().forEach(names::add); |
298 | - root.set("names", names); | 326 | + root.set(NAMES, names); |
299 | - sendMessage("spriteListResponse", sid, root); | 327 | + sendMessage(SPRITE_LIST_RESPONSE, sid, root); |
300 | } | 328 | } |
301 | } | 329 | } |
302 | 330 | ||
... | @@ -307,10 +335,10 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -307,10 +335,10 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
307 | 335 | ||
308 | @Override | 336 | @Override |
309 | public void process(long sid, ObjectNode payload) { | 337 | public void process(long sid, ObjectNode payload) { |
310 | - String name = string(payload, "name"); | 338 | + String name = string(payload, NAME); |
311 | ObjectNode root = objectNode(); | 339 | ObjectNode root = objectNode(); |
312 | - root.set("data", get(SpriteService.class).get(name)); | 340 | + root.set(DATA, get(SpriteService.class).get(name)); |
313 | - sendMessage("spriteDataResponse", sid, root); | 341 | + sendMessage(SPRITE_DATA_RESPONSE, sid, root); |
314 | } | 342 | } |
315 | } | 343 | } |
316 | 344 | ||
... | @@ -321,14 +349,20 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -321,14 +349,20 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
321 | 349 | ||
322 | @Override | 350 | @Override |
323 | public void process(long sid, ObjectNode payload) { | 351 | public void process(long sid, ObjectNode payload) { |
324 | - String type = string(payload, "class", "unknown"); | 352 | + String type = string(payload, CLASS, UNKNOWN); |
325 | - String id = string(payload, "id"); | 353 | + String id = string(payload, ID); |
354 | + PropertyPanel pp = null; | ||
326 | 355 | ||
327 | - if (type.equals("device")) { | 356 | + if (type.equals(DEVICE)) { |
328 | - sendMessage(deviceDetails(deviceId(id), sid)); | 357 | + pp = deviceDetails(deviceId(id), sid); |
329 | - } else if (type.equals("host")) { | 358 | + overlayCache.currentOverlay().modifyDeviceDetails(pp); |
330 | - sendMessage(hostDetails(hostId(id), sid)); | 359 | + } else if (type.equals(HOST)) { |
360 | + pp = hostDetails(hostId(id), sid); | ||
361 | + overlayCache.currentOverlay().modifyHostDetails(pp); | ||
331 | } | 362 | } |
363 | + | ||
364 | + ObjectNode json = JsonUtils.envelope(SHOW_DETAILS, sid, json(pp)); | ||
365 | + sendMessage(json); | ||
332 | } | 366 | } |
333 | } | 367 | } |
334 | 368 | ||
... | @@ -364,8 +398,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -364,8 +398,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
364 | @Override | 398 | @Override |
365 | public void process(long sid, ObjectNode payload) { | 399 | public void process(long sid, ObjectNode payload) { |
366 | // TODO: add protection against device ids and non-existent hosts. | 400 | // TODO: add protection against device ids and non-existent hosts. |
367 | - HostId one = hostId(string(payload, "one")); | 401 | + HostId one = hostId(string(payload, ONE)); |
368 | - HostId two = hostId(string(payload, "two")); | 402 | + HostId two = hostId(string(payload, TWO)); |
369 | 403 | ||
370 | HostToHostIntent intent = HostToHostIntent.builder() | 404 | HostToHostIntent intent = HostToHostIntent.builder() |
371 | .appId(appId) | 405 | .appId(appId) |
... | @@ -386,8 +420,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -386,8 +420,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
386 | @Override | 420 | @Override |
387 | public void process(long sid, ObjectNode payload) { | 421 | public void process(long sid, ObjectNode payload) { |
388 | // TODO: add protection against device ids and non-existent hosts. | 422 | // TODO: add protection against device ids and non-existent hosts. |
389 | - Set<HostId> src = getHostIds((ArrayNode) payload.path("src")); | 423 | + Set<HostId> src = getHostIds((ArrayNode) payload.path(SRC)); |
390 | - HostId dst = hostId(string(payload, "dst")); | 424 | + HostId dst = hostId(string(payload, DST)); |
391 | Host dstHost = hostService.getHost(dst); | 425 | Host dstHost = hostService.getHost(dst); |
392 | 426 | ||
393 | Set<ConnectPoint> ingressPoints = getHostLocations(src); | 427 | Set<ConnectPoint> ingressPoints = getHostLocations(src); |
... | @@ -421,12 +455,12 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -421,12 +455,12 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
421 | // Cancel any other traffic monitoring mode. | 455 | // Cancel any other traffic monitoring mode. |
422 | stopTrafficMonitoring(); | 456 | stopTrafficMonitoring(); |
423 | 457 | ||
424 | - if (!payload.has("ids")) { | 458 | + if (!payload.has(IDS)) { |
425 | return; | 459 | return; |
426 | } | 460 | } |
427 | 461 | ||
428 | // Get the set of selected hosts and their intents. | 462 | // Get the set of selected hosts and their intents. |
429 | - ArrayNode ids = (ArrayNode) payload.path("ids"); | 463 | + ArrayNode ids = (ArrayNode) payload.path(IDS); |
430 | selectedHosts = getHosts(ids); | 464 | selectedHosts = getHosts(ids); |
431 | selectedDevices = getDevices(ids); | 465 | selectedDevices = getDevices(ids); |
432 | selectedIntents = intentFilter.findPathIntents( | 466 | selectedIntents = intentFilter.findPathIntents( |
... | @@ -435,7 +469,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -435,7 +469,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
435 | 469 | ||
436 | if (haveSelectedIntents()) { | 470 | if (haveSelectedIntents()) { |
437 | // Send a message to highlight all links of all monitored intents. | 471 | // Send a message to highlight all links of all monitored intents. |
438 | - sendMessage(trafficMessage(new TrafficClass("primary", selectedIntents))); | 472 | + sendMessage(trafficMessage(new TrafficClass(PRIMARY, selectedIntents))); |
439 | } | 473 | } |
440 | 474 | ||
441 | // TODO: Re-introduce once the client click vs hover gesture stuff is sorted out. | 475 | // TODO: Re-introduce once the client click vs hover gesture stuff is sorted out. |
... | @@ -548,7 +582,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -548,7 +582,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
548 | private synchronized void requestSummary(long sid) { | 582 | private synchronized void requestSummary(long sid) { |
549 | PropertyPanel pp = summmaryMessage(sid); | 583 | PropertyPanel pp = summmaryMessage(sid); |
550 | overlayCache.currentOverlay().modifySummary(pp); | 584 | overlayCache.currentOverlay().modifySummary(pp); |
551 | - ObjectNode json = JsonUtils.envelope("showSummary", sid, json(pp)); | 585 | + ObjectNode json = JsonUtils.envelope(SHOW_SUMMARY, sid, json(pp)); |
552 | sendMessage(json); | 586 | sendMessage(json); |
553 | } | 587 | } |
554 | 588 | ||
... | @@ -668,12 +702,12 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -668,12 +702,12 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
668 | startTrafficMonitoring(); | 702 | startTrafficMonitoring(); |
669 | 703 | ||
670 | // Get the set of selected hosts and their intents. | 704 | // Get the set of selected hosts and their intents. |
671 | - ArrayNode ids = (ArrayNode) payload.path("ids"); | 705 | + ArrayNode ids = (ArrayNode) payload.path(IDS); |
672 | Set<Host> hosts = new HashSet<>(); | 706 | Set<Host> hosts = new HashSet<>(); |
673 | Set<Device> devices = getDevices(ids); | 707 | Set<Device> devices = getDevices(ids); |
674 | 708 | ||
675 | // If there is a hover node, include it in the hosts and find intents. | 709 | // If there is a hover node, include it in the hosts and find intents. |
676 | - String hover = JsonUtils.string(payload, "hover"); | 710 | + String hover = JsonUtils.string(payload, HOVER); |
677 | if (!isNullOrEmpty(hover)) { | 711 | if (!isNullOrEmpty(hover)) { |
678 | addHover(hosts, devices, hover); | 712 | addHover(hosts, devices, hover); |
679 | } | 713 | } |
... | @@ -699,8 +733,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -699,8 +733,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
699 | secondary.removeAll(primary); | 733 | secondary.removeAll(primary); |
700 | 734 | ||
701 | // Send a message to highlight all links of all monitored intents. | 735 | // Send a message to highlight all links of all monitored intents. |
702 | - sendMessage(trafficMessage(new TrafficClass("primary", primary), | 736 | + sendMessage(trafficMessage(new TrafficClass(PRIMARY, primary), |
703 | - new TrafficClass("secondary", secondary))); | 737 | + new TrafficClass(SECONDARY, secondary))); |
704 | } | 738 | } |
705 | 739 | ||
706 | // Requests next or previous related intent. | 740 | // Requests next or previous related intent. |
... | @@ -720,7 +754,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -720,7 +754,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
720 | // selected intent highlighted. | 754 | // selected intent highlighted. |
721 | private void sendSelectedIntent() { | 755 | private void sendSelectedIntent() { |
722 | Intent selectedIntent = selectedIntents.get(currentIntentIndex); | 756 | Intent selectedIntent = selectedIntents.get(currentIntentIndex); |
723 | - log.info("Requested next intent {}", selectedIntent.id()); | 757 | + log.debug("Requested next intent {}", selectedIntent.id()); |
724 | 758 | ||
725 | Set<Intent> primary = new HashSet<>(); | 759 | Set<Intent> primary = new HashSet<>(); |
726 | primary.add(selectedIntent); | 760 | primary.add(selectedIntent); |
... | @@ -729,8 +763,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -729,8 +763,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
729 | secondary.remove(selectedIntent); | 763 | secondary.remove(selectedIntent); |
730 | 764 | ||
731 | // Send a message to highlight all links of the selected intent. | 765 | // Send a message to highlight all links of the selected intent. |
732 | - sendMessage(trafficMessage(new TrafficClass("primary", primary), | 766 | + sendMessage(trafficMessage(new TrafficClass(PRIMARY, primary), |
733 | - new TrafficClass("secondary", secondary))); | 767 | + new TrafficClass(SECONDARY, secondary))); |
734 | } | 768 | } |
735 | 769 | ||
736 | // Requests monitoring of traffic for the selected intent. | 770 | // Requests monitoring of traffic for the selected intent. |
... | @@ -740,13 +774,13 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -740,13 +774,13 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
740 | currentIntentIndex = 0; | 774 | currentIntentIndex = 0; |
741 | } | 775 | } |
742 | Intent selectedIntent = selectedIntents.get(currentIntentIndex); | 776 | Intent selectedIntent = selectedIntents.get(currentIntentIndex); |
743 | - log.info("Requested traffic for selected {}", selectedIntent.id()); | 777 | + log.debug("Requested traffic for selected {}", selectedIntent.id()); |
744 | 778 | ||
745 | Set<Intent> primary = new HashSet<>(); | 779 | Set<Intent> primary = new HashSet<>(); |
746 | primary.add(selectedIntent); | 780 | primary.add(selectedIntent); |
747 | 781 | ||
748 | // Send a message to highlight all links of the selected intent. | 782 | // Send a message to highlight all links of the selected intent. |
749 | - sendMessage(trafficMessage(new TrafficClass("primary", primary, true))); | 783 | + sendMessage(trafficMessage(new TrafficClass(PRIMARY, primary, true))); |
750 | } | 784 | } |
751 | } | 785 | } |
752 | 786 | ||
... | @@ -805,7 +839,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { | ... | @@ -805,7 +839,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { |
805 | @Override | 839 | @Override |
806 | public void event(MastershipEvent event) { | 840 | public void event(MastershipEvent event) { |
807 | msgSender.execute(() -> { | 841 | msgSender.execute(() -> { |
808 | - sendAllInstances("updateInstance"); | 842 | + sendAllInstances(UPDATE_INSTANCE); |
809 | Device device = deviceService.getDevice(event.subject()); | 843 | Device device = deviceService.getDevice(event.subject()); |
810 | if (device != null) { | 844 | if (device != null) { |
811 | sendMessage(deviceMessage(new DeviceEvent(DEVICE_UPDATED, device))); | 845 | sendMessage(deviceMessage(new DeviceEvent(DEVICE_UPDATED, device))); | ... | ... |
... | @@ -440,57 +440,61 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -440,57 +440,61 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
440 | JsonUtils.node(payload, "memento")); | 440 | JsonUtils.node(payload, "memento")); |
441 | } | 441 | } |
442 | 442 | ||
443 | - // Returns summary response. | 443 | + // ----------------------------------------------------------------------- |
444 | + // Create models of the data to return, that overlays can adjust / augment | ||
445 | + | ||
446 | + // Returns property panel model for summary response. | ||
444 | protected PropertyPanel summmaryMessage(long sid) { | 447 | protected PropertyPanel summmaryMessage(long sid) { |
445 | Topology topology = topologyService.currentTopology(); | 448 | Topology topology = topologyService.currentTopology(); |
446 | PropertyPanel pp = new PropertyPanel("ONOS Summary", "node") | 449 | PropertyPanel pp = new PropertyPanel("ONOS Summary", "node") |
447 | - .add(new PropertyPanel.Prop("Devices", format(topology.deviceCount()))) | 450 | + .add(new PropertyPanel.Prop("Devices", topology.deviceCount())) |
448 | - .add(new PropertyPanel.Prop("Links", format(topology.linkCount()))) | 451 | + .add(new PropertyPanel.Prop("Links", topology.linkCount())) |
449 | - .add(new PropertyPanel.Prop("Hosts", format(hostService.getHostCount()))) | 452 | + .add(new PropertyPanel.Prop("Hosts", hostService.getHostCount())) |
450 | - .add(new PropertyPanel.Prop("Topology SCCs", format(topology.clusterCount()))) | 453 | + .add(new PropertyPanel.Prop("Topology SCCs", topology.clusterCount())) |
451 | .add(new PropertyPanel.Separator()) | 454 | .add(new PropertyPanel.Separator()) |
452 | - .add(new PropertyPanel.Prop("Intents", format(intentService.getIntentCount()))) | 455 | + .add(new PropertyPanel.Prop("Intents", intentService.getIntentCount())) |
453 | - .add(new PropertyPanel.Prop("Tunnels", format(tunnelService.tunnelCount()))) | 456 | + .add(new PropertyPanel.Prop("Tunnels", tunnelService.tunnelCount())) |
454 | - .add(new PropertyPanel.Prop("Flows", format(flowService.getFlowRuleCount()))) | 457 | + .add(new PropertyPanel.Prop("Flows", flowService.getFlowRuleCount())) |
455 | .add(new PropertyPanel.Prop("Version", version)); | 458 | .add(new PropertyPanel.Prop("Version", version)); |
456 | 459 | ||
457 | return pp; | 460 | return pp; |
458 | } | 461 | } |
459 | 462 | ||
460 | - // Returns device details response. | 463 | + // Returns property panel model for device details response. |
461 | - protected ObjectNode deviceDetails(DeviceId deviceId, long sid) { | 464 | + protected PropertyPanel deviceDetails(DeviceId deviceId, long sid) { |
462 | Device device = deviceService.getDevice(deviceId); | 465 | Device device = deviceService.getDevice(deviceId); |
463 | Annotations annot = device.annotations(); | 466 | Annotations annot = device.annotations(); |
464 | String name = annot.value(AnnotationKeys.NAME); | 467 | String name = annot.value(AnnotationKeys.NAME); |
465 | int portCount = deviceService.getPorts(deviceId).size(); | 468 | int portCount = deviceService.getPorts(deviceId).size(); |
466 | int flowCount = getFlowCount(deviceId); | 469 | int flowCount = getFlowCount(deviceId); |
467 | int tunnelCount = getTunnelCount(deviceId); | 470 | int tunnelCount = getTunnelCount(deviceId); |
468 | - return JsonUtils.envelope("showDetails", sid, | 471 | + |
469 | - json(isNullOrEmpty(name) ? deviceId.toString() : name, | 472 | + String title = isNullOrEmpty(name) ? deviceId.toString() : name; |
470 | - device.type().toString().toLowerCase(), | 473 | + String typeId = device.type().toString().toLowerCase(); |
471 | - new Prop("URI", deviceId.toString()), | 474 | + |
472 | - new Prop("Vendor", device.manufacturer()), | 475 | + PropertyPanel pp = new PropertyPanel(title, typeId) |
473 | - new Prop("H/W Version", device.hwVersion()), | 476 | + .id(deviceId.toString()) |
474 | - new Prop("S/W Version", device.swVersion()), | 477 | + .add(new PropertyPanel.Prop("URI", deviceId.toString())) |
475 | - new Prop("Serial Number", device.serialNumber()), | 478 | + .add(new PropertyPanel.Prop("Vendor", device.manufacturer())) |
476 | - new Prop("Protocol", annot.value(AnnotationKeys.PROTOCOL)), | 479 | + .add(new PropertyPanel.Prop("H/W Version", device.hwVersion())) |
477 | - new Separator(), | 480 | + .add(new PropertyPanel.Prop("S/W Version", device.swVersion())) |
478 | - new Prop("Master", master(deviceId)), | 481 | + .add(new PropertyPanel.Prop("Serial Number", device.serialNumber())) |
479 | - new Prop("Latitude", annot.value(AnnotationKeys.LATITUDE)), | 482 | + .add(new PropertyPanel.Prop("Protocol", annot.value(AnnotationKeys.PROTOCOL))) |
480 | - new Prop("Longitude", annot.value(AnnotationKeys.LONGITUDE)), | 483 | + .add(new PropertyPanel.Separator()) |
481 | - new Separator(), | 484 | + .add(new PropertyPanel.Prop("Latitude", annot.value(AnnotationKeys.LATITUDE))) |
482 | - new Prop("Ports", Integer.toString(portCount)), | 485 | + .add(new PropertyPanel.Prop("Longitude", annot.value(AnnotationKeys.LONGITUDE))) |
483 | - new Prop("Flows", Integer.toString(flowCount)), | 486 | + .add(new PropertyPanel.Separator()) |
484 | - new Prop("Tunnels", Integer.toString(tunnelCount)) | 487 | + .add(new PropertyPanel.Prop("Ports", portCount)) |
485 | - )); | 488 | + .add(new PropertyPanel.Prop("Flows", flowCount)) |
489 | + .add(new PropertyPanel.Prop("Tunnels", tunnelCount)); | ||
490 | + | ||
491 | + return pp; | ||
486 | } | 492 | } |
487 | 493 | ||
488 | protected int getFlowCount(DeviceId deviceId) { | 494 | protected int getFlowCount(DeviceId deviceId) { |
489 | int count = 0; | 495 | int count = 0; |
490 | - Iterator<FlowEntry> it = flowService.getFlowEntries(deviceId).iterator(); | 496 | + for (FlowEntry flowEntry : flowService.getFlowEntries(deviceId)) { |
491 | - while (it.hasNext()) { | ||
492 | count++; | 497 | count++; |
493 | - it.next(); | ||
494 | } | 498 | } |
495 | return count; | 499 | return count; |
496 | } | 500 | } |
... | @@ -503,8 +507,8 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -503,8 +507,8 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
503 | OpticalTunnelEndPoint dst = (OpticalTunnelEndPoint) tunnel.dst(); | 507 | OpticalTunnelEndPoint dst = (OpticalTunnelEndPoint) tunnel.dst(); |
504 | DeviceId srcDevice = (DeviceId) src.elementId().get(); | 508 | DeviceId srcDevice = (DeviceId) src.elementId().get(); |
505 | DeviceId dstDevice = (DeviceId) dst.elementId().get(); | 509 | DeviceId dstDevice = (DeviceId) dst.elementId().get(); |
506 | - if (srcDevice.toString().equals(deviceId.toString()) | 510 | + if (srcDevice.toString().equals(deviceId.toString()) || |
507 | - || dstDevice.toString().equals(deviceId.toString())) { | 511 | + dstDevice.toString().equals(deviceId.toString())) { |
508 | count++; | 512 | count++; |
509 | } | 513 | } |
510 | } | 514 | } |
... | @@ -516,9 +520,8 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -516,9 +520,8 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
516 | List<FlowEntry> entries = new ArrayList<>(); | 520 | List<FlowEntry> entries = new ArrayList<>(); |
517 | Set<Link> links = new HashSet<>(linkService.getDeviceEgressLinks(deviceId)); | 521 | Set<Link> links = new HashSet<>(linkService.getDeviceEgressLinks(deviceId)); |
518 | Set<Host> hosts = hostService.getConnectedHosts(deviceId); | 522 | Set<Host> hosts = hostService.getConnectedHosts(deviceId); |
519 | - Iterator<FlowEntry> it = flowService.getFlowEntries(deviceId).iterator(); | 523 | + for (FlowEntry flowEntry : flowService.getFlowEntries(deviceId)) { |
520 | - while (it.hasNext()) { | 524 | + entries.add(flowEntry); |
521 | - entries.add(it.next()); | ||
522 | } | 525 | } |
523 | 526 | ||
524 | // Add all edge links to the set | 527 | // Add all edge links to the set |
... | @@ -555,24 +558,30 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -555,24 +558,30 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
555 | 558 | ||
556 | 559 | ||
557 | // Returns host details response. | 560 | // Returns host details response. |
558 | - protected ObjectNode hostDetails(HostId hostId, long sid) { | 561 | + protected PropertyPanel hostDetails(HostId hostId, long sid) { |
559 | Host host = hostService.getHost(hostId); | 562 | Host host = hostService.getHost(hostId); |
560 | Annotations annot = host.annotations(); | 563 | Annotations annot = host.annotations(); |
561 | String type = annot.value(AnnotationKeys.TYPE); | 564 | String type = annot.value(AnnotationKeys.TYPE); |
562 | String name = annot.value(AnnotationKeys.NAME); | 565 | String name = annot.value(AnnotationKeys.NAME); |
563 | String vlan = host.vlan().toString(); | 566 | String vlan = host.vlan().toString(); |
564 | - return JsonUtils.envelope("showDetails", sid, | 567 | + |
565 | - json(isNullOrEmpty(name) ? hostId.toString() : name, | 568 | + String title = isNullOrEmpty(name) ? hostId.toString() : name; |
566 | - isNullOrEmpty(type) ? "endstation" : type, | 569 | + String typeId = isNullOrEmpty(type) ? "endstation" : type; |
567 | - new Prop("MAC", host.mac().toString()), | 570 | + |
568 | - new Prop("IP", host.ipAddresses().toString().replaceAll("[\\[\\]]", "")), | 571 | + PropertyPanel pp = new PropertyPanel(title, typeId) |
569 | - new Prop("VLAN", vlan.equals("-1") ? "none" : vlan), | 572 | + .id(hostId.toString()) |
570 | - new Separator(), | 573 | + .add(new PropertyPanel.Prop("MAC", host.mac().toString())) |
571 | - new Prop("Latitude", annot.value(AnnotationKeys.LATITUDE)), | 574 | + .add(new PropertyPanel.Prop("IP", host.ipAddresses().toString().replaceAll("[\\[\\]]", ""))) |
572 | - new Prop("Longitude", annot.value(AnnotationKeys.LONGITUDE)))); | 575 | + .add(new PropertyPanel.Prop("VLAN", vlan.equals("-1") ? "none" : vlan)) |
576 | + .add(new PropertyPanel.Separator()) | ||
577 | + .add(new PropertyPanel.Prop("Latitude", annot.value(AnnotationKeys.LATITUDE))) | ||
578 | + .add(new PropertyPanel.Prop("Longitude", annot.value(AnnotationKeys.LONGITUDE))); | ||
579 | + | ||
580 | + return pp; | ||
573 | } | 581 | } |
574 | 582 | ||
575 | 583 | ||
584 | + // TODO: migrate to Traffic overlay | ||
576 | // Produces JSON message to trigger flow traffic overview visualization | 585 | // Produces JSON message to trigger flow traffic overview visualization |
577 | protected ObjectNode trafficSummaryMessage(StatsType type) { | 586 | protected ObjectNode trafficSummaryMessage(StatsType type) { |
578 | ObjectNode payload = objectNode(); | 587 | ObjectNode payload = objectNode(); |
... | @@ -827,21 +836,19 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -827,21 +836,19 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
827 | return format.format(value) + " " + unit; | 836 | return format.format(value) + " " + unit; |
828 | } | 837 | } |
829 | 838 | ||
830 | - // Formats the given number into a string. | ||
831 | - private String format(Number number) { | ||
832 | - DecimalFormat format = new DecimalFormat("#,###"); | ||
833 | - return format.format(number); | ||
834 | - } | ||
835 | - | ||
836 | // Produces compact string representation of a link. | 839 | // Produces compact string representation of a link. |
837 | private static String compactLinkString(Link link) { | 840 | private static String compactLinkString(Link link) { |
838 | return String.format(COMPACT, link.src().elementId(), link.src().port(), | 841 | return String.format(COMPACT, link.src().elementId(), link.src().port(), |
839 | link.dst().elementId(), link.dst().port()); | 842 | link.dst().elementId(), link.dst().port()); |
840 | } | 843 | } |
841 | 844 | ||
845 | + // translates the property panel into JSON, for returning to the client | ||
842 | protected ObjectNode json(PropertyPanel pp) { | 846 | protected ObjectNode json(PropertyPanel pp) { |
843 | ObjectNode result = objectNode() | 847 | ObjectNode result = objectNode() |
844 | - .put("title", pp.title()).put("type", pp.typeId()); | 848 | + .put("title", pp.title()) |
849 | + .put("type", pp.typeId()) | ||
850 | + .put("id", pp.id()); | ||
851 | + | ||
845 | ObjectNode pnode = objectNode(); | 852 | ObjectNode pnode = objectNode(); |
846 | ArrayNode porder = arrayNode(); | 853 | ArrayNode porder = arrayNode(); |
847 | for (PropertyPanel.Prop p : pp.properties()) { | 854 | for (PropertyPanel.Prop p : pp.properties()) { | ... | ... |
... | @@ -219,6 +219,11 @@ | ... | @@ -219,6 +219,11 @@ |
219 | // === ----------------------------------------------------- | 219 | // === ----------------------------------------------------- |
220 | // Functions for populating the detail panel | 220 | // Functions for populating the detail panel |
221 | 221 | ||
222 | + var isDevice = { | ||
223 | + switch: 1, | ||
224 | + roadm: 1 | ||
225 | + }; | ||
226 | + | ||
222 | function displaySingle(data) { | 227 | function displaySingle(data) { |
223 | detail.setup(); | 228 | detail.setup(); |
224 | 229 | ||
... | @@ -228,16 +233,21 @@ | ... | @@ -228,16 +233,21 @@ |
228 | title = detail.appendHeader('h2') | 233 | title = detail.appendHeader('h2') |
229 | .classed('clickable', true), | 234 | .classed('clickable', true), |
230 | table = detail.appendBody('table'), | 235 | table = detail.appendBody('table'), |
231 | - tbody = table.append('tbody'); | 236 | + tbody = table.append('tbody'), |
237 | + navFn; | ||
232 | 238 | ||
233 | gs.addGlyph(svg, (data.type || 'unknown'), 40); | 239 | gs.addGlyph(svg, (data.type || 'unknown'), 40); |
234 | - title.text(data.id); | 240 | + title.text(data.title); |
235 | - svg.on('click', function () { | 241 | + |
236 | - ns.navTo(devPath, { devId: data.id }); | 242 | + // only add navigation when displaying a device |
237 | - }); | 243 | + if (isDevice[data.type]) { |
238 | - title.on('click', function () { | 244 | + navFn = function () { |
239 | ns.navTo(devPath, { devId: data.id }); | 245 | ns.navTo(devPath, { devId: data.id }); |
240 | - }); | 246 | + }; |
247 | + | ||
248 | + svg.on('click', navFn); | ||
249 | + title.on('click', navFn); | ||
250 | + } | ||
241 | 251 | ||
242 | listProps(tbody, data); | 252 | listProps(tbody, data); |
243 | addBtnFooter(); | 253 | addBtnFooter(); | ... | ... |
-
Please register or login to post a comment