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
226 additions
and
107 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); |
| 326 | - | 354 | + PropertyPanel pp = null; |
| 327 | - if (type.equals("device")) { | 355 | + |
| 328 | - sendMessage(deviceDetails(deviceId(id), sid)); | 356 | + if (type.equals(DEVICE)) { |
| 329 | - } else if (type.equals("host")) { | 357 | + pp = deviceDetails(deviceId(id), sid); |
| 330 | - sendMessage(hostDetails(hostId(id), sid)); | 358 | + overlayCache.currentOverlay().modifyDeviceDetails(pp); |
| 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