Simon Hunt

ONOS-4646: Provide temp. mechanism for topology overlays to modify link details data.

Change-Id: I00b78b1da1580883e09af87ed470e6142a1ec19b
...@@ -18,10 +18,13 @@ package org.onosproject.ui; ...@@ -18,10 +18,13 @@ package org.onosproject.ui;
18 18
19 import org.onosproject.net.DeviceId; 19 import org.onosproject.net.DeviceId;
20 import org.onosproject.net.HostId; 20 import org.onosproject.net.HostId;
21 +import org.onosproject.net.link.LinkEvent;
21 import org.onosproject.ui.topo.PropertyPanel; 22 import org.onosproject.ui.topo.PropertyPanel;
22 import org.slf4j.Logger; 23 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory; 24 import org.slf4j.LoggerFactory;
24 25
26 +import java.util.Map;
27 +
25 /** 28 /**
26 * Represents user interface topology view overlay. 29 * Represents user interface topology view overlay.
27 */ 30 */
...@@ -106,7 +109,7 @@ public class UiTopoOverlay { ...@@ -106,7 +109,7 @@ public class UiTopoOverlay {
106 * a selected device. 109 * a selected device.
107 * This default implementation does nothing. 110 * This default implementation does nothing.
108 * 111 *
109 - * @param pp property panel model of summary data 112 + * @param pp property panel model of summary data
110 * @param deviceId device id 113 * @param deviceId device id
111 */ 114 */
112 public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) { 115 public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) {
...@@ -117,9 +120,29 @@ public class UiTopoOverlay { ...@@ -117,9 +120,29 @@ public class UiTopoOverlay {
117 * a selected host. 120 * a selected host.
118 * This default implementation does nothing. 121 * This default implementation does nothing.
119 * 122 *
120 - * @param pp property panel model of summary data 123 + * @param pp property panel model of summary data
121 * @param hostId host id 124 * @param hostId host id
122 */ 125 */
123 public void modifyHostDetails(PropertyPanel pp, HostId hostId) { 126 public void modifyHostDetails(PropertyPanel pp, HostId hostId) {
124 } 127 }
128 +
129 + /**
130 + * Callback invoked when a link event is processed (e.g. link added).
131 + * A subclass may override this method to return a map of property
132 + * key/value pairs to be included in the JSON event back to the client,
133 + * so that those additional properties are available to be displayed as
134 + * link details.
135 + * <p>
136 + * The default implementation returns {@code null}, that is, no additional
137 + * properties to be added.
138 + *
139 + * @param event the link event
140 + * @return map of additional key/value pairs to be added to the JSON event
141 + * @deprecated this is a temporary addition for Goldeneye (1.6) release,
142 + * and expected to be replaced in the Hummingbird (1.7) release
143 + */
144 + @Deprecated
145 + public Map<String, String> additionalLinkData(LinkEvent event) {
146 + return null;
147 + }
125 } 148 }
......
...@@ -71,6 +71,7 @@ import java.util.Collections; ...@@ -71,6 +71,7 @@ import java.util.Collections;
71 import java.util.Comparator; 71 import java.util.Comparator;
72 import java.util.HashSet; 72 import java.util.HashSet;
73 import java.util.List; 73 import java.util.List;
74 +import java.util.Map;
74 import java.util.Set; 75 import java.util.Set;
75 import java.util.Timer; 76 import java.util.Timer;
76 import java.util.TimerTask; 77 import java.util.TimerTask;
...@@ -128,6 +129,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -128,6 +129,8 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
128 private static final String TOPO_START_DONE = "topoStartDone"; 129 private static final String TOPO_START_DONE = "topoStartDone";
129 130
130 // fields 131 // fields
132 + private static final String PAYLOAD = "payload";
133 + private static final String EXTRA = "extra";
131 private static final String ID = "id"; 134 private static final String ID = "id";
132 private static final String KEY = "key"; 135 private static final String KEY = "key";
133 private static final String APP_ID = "appId"; 136 private static final String APP_ID = "appId";
...@@ -603,7 +606,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -603,7 +606,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
603 Collections.sort(nodes, NODE_COMPARATOR); 606 Collections.sort(nodes, NODE_COMPARATOR);
604 for (ControllerNode node : nodes) { 607 for (ControllerNode node : nodes) {
605 sendMessage(instanceMessage(new ClusterEvent(INSTANCE_ADDED, node), 608 sendMessage(instanceMessage(new ClusterEvent(INSTANCE_ADDED, node),
606 - messageType)); 609 + messageType));
607 } 610 }
608 } 611 }
609 612
...@@ -612,13 +615,13 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -612,13 +615,13 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
612 // Send optical first, others later for layered rendering 615 // Send optical first, others later for layered rendering
613 for (Device device : deviceService.getDevices()) { 616 for (Device device : deviceService.getDevices()) {
614 if ((device.type() == Device.Type.ROADM) || 617 if ((device.type() == Device.Type.ROADM) ||
615 - (device.type() == Device.Type.OTN)) { 618 + (device.type() == Device.Type.OTN)) {
616 sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device))); 619 sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
617 } 620 }
618 } 621 }
619 for (Device device : deviceService.getDevices()) { 622 for (Device device : deviceService.getDevices()) {
620 if ((device.type() != Device.Type.ROADM) && 623 if ((device.type() != Device.Type.ROADM) &&
621 - (device.type() != Device.Type.OTN)) { 624 + (device.type() != Device.Type.OTN)) {
622 sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device))); 625 sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
623 } 626 }
624 } 627 }
...@@ -629,16 +632,40 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -629,16 +632,40 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
629 // Send optical first, others later for layered rendering 632 // Send optical first, others later for layered rendering
630 for (Link link : linkService.getLinks()) { 633 for (Link link : linkService.getLinks()) {
631 if (link.type() == Link.Type.OPTICAL) { 634 if (link.type() == Link.Type.OPTICAL) {
632 - sendMessage(linkMessage(new LinkEvent(LINK_ADDED, link))); 635 + sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
633 } 636 }
634 } 637 }
635 for (Link link : linkService.getLinks()) { 638 for (Link link : linkService.getLinks()) {
636 if (link.type() != Link.Type.OPTICAL) { 639 if (link.type() != Link.Type.OPTICAL) {
637 - sendMessage(linkMessage(new LinkEvent(LINK_ADDED, link))); 640 + sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
638 } 641 }
639 } 642 }
640 } 643 }
641 644
645 + // Temporary mechanism to support topology overlays adding their own
646 + // properties to the link events.
647 + private ObjectNode composeLinkMessage(LinkEvent event) {
648 + // start with base message
649 + ObjectNode msg = linkMessage(event);
650 + Map<String, String> additional =
651 + overlayCache.currentOverlay().additionalLinkData(event);
652 +
653 + if (additional != null) {
654 + // attach additional key-value pairs as extra data structure
655 + ObjectNode payload = (ObjectNode) msg.get(PAYLOAD);
656 + payload.set(EXTRA, createExtra(additional));
657 + }
658 + return msg;
659 + }
660 +
661 + private ObjectNode createExtra(Map<String, String> additional) {
662 + ObjectNode extra = objectNode();
663 + for (Map.Entry<String, String> entry : additional.entrySet()) {
664 + extra.put(entry.getKey(), entry.getValue());
665 + }
666 + return extra;
667 + }
668 +
642 // Sends all hosts to the client as host-added messages. 669 // Sends all hosts to the client as host-added messages.
643 private void sendAllHosts() { 670 private void sendAllHosts() {
644 for (Host host : hostService.getHosts()) { 671 for (Host host : hostService.getHosts()) {
...@@ -759,7 +786,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -759,7 +786,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
759 private class InternalLinkListener implements LinkListener { 786 private class InternalLinkListener implements LinkListener {
760 @Override 787 @Override
761 public void event(LinkEvent event) { 788 public void event(LinkEvent event) {
762 - msgSender.execute(() -> sendMessage(linkMessage(event))); 789 + msgSender.execute(() -> sendMessage(composeLinkMessage(event)));
763 msgSender.execute(traffic::pokeIntent); 790 msgSender.execute(traffic::pokeIntent);
764 eventAccummulator.add(event); 791 eventAccummulator.add(event);
765 } 792 }
...@@ -829,7 +856,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase { ...@@ -829,7 +856,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
829 String me = this.toString(); 856 String me = this.toString();
830 String miniMe = me.replaceAll("^.*@", "me@"); 857 String miniMe = me.replaceAll("^.*@", "me@");
831 log.debug("Time: {}; this: {}, processing items ({} events)", 858 log.debug("Time: {}; this: {}, processing items ({} events)",
832 - now, miniMe, items.size()); 859 + now, miniMe, items.size());
833 // End-of-Debugging 860 // End-of-Debugging
834 861
835 try { 862 try {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
23 'use strict'; 23 'use strict';
24 24
25 // injected refs 25 // injected refs
26 - var $log, fs, sus, ts, flash, tss, tps; 26 + var $log, fs, sus, ts, flash, tss, tps, tov;
27 27
28 // internal state 28 // internal state
29 var api, 29 var api,
...@@ -238,7 +238,7 @@ ...@@ -238,7 +238,7 @@
238 238
239 d.el.classed('selected', true); 239 d.el.classed('selected', true);
240 240
241 - tps.displayLink(d); 241 + tps.displayLink(d, tov.hooks.modifyLinkData);
242 tps.displaySomething(); 242 tps.displaySomething();
243 } 243 }
244 244
...@@ -300,9 +300,9 @@ ...@@ -300,9 +300,9 @@
300 angular.module('ovTopo') 300 angular.module('ovTopo')
301 .factory('TopoLinkService', 301 .factory('TopoLinkService',
302 ['$log', 'FnService', 'SvgUtilService', 'ThemeService', 'FlashService', 302 ['$log', 'FnService', 'SvgUtilService', 'ThemeService', 'FlashService',
303 - 'TopoSelectService', 'TopoPanelService', 303 + 'TopoSelectService', 'TopoPanelService', 'TopoOverlayService',
304 304
305 - function (_$log_, _fs_, _sus_, _ts_, _flash_, _tss_, _tps_) { 305 + function (_$log_, _fs_, _sus_, _ts_, _flash_, _tss_, _tps_, _tov_) {
306 $log = _$log_; 306 $log = _$log_;
307 fs = _fs_; 307 fs = _fs_;
308 sus = _sus_; 308 sus = _sus_;
...@@ -310,6 +310,7 @@ ...@@ -310,6 +310,7 @@
310 flash = _flash_; 310 flash = _flash_;
311 tss = _tss_; 311 tss = _tss_;
312 tps = _tps_; 312 tps = _tps_;
313 + tov = _tov_;
313 314
314 function initLink(_api_, _td3_) { 315 function initLink(_api_, _td3_) {
315 api = _api_; 316 api = _api_;
......
...@@ -230,7 +230,8 @@ ...@@ -230,7 +230,8 @@
230 ws = (s && s.linkWidth) || 0, 230 ws = (s && s.linkWidth) || 0,
231 wt = (t && t.linkWidth) || 0; 231 wt = (t && t.linkWidth) || 0;
232 return lnk.position.multiLink ? 5 : Math.max(ws, wt); 232 return lnk.position.multiLink ? 5 : Math.max(ws, wt);
233 - } 233 + },
234 + extra: link.extra
234 }); 235 });
235 return lnk; 236 return lnk;
236 } 237 }
......
...@@ -277,6 +277,13 @@ ...@@ -277,6 +277,13 @@
277 cb && cb(); 277 cb && cb();
278 } 278 }
279 279
280 + // Temporary function to allow overlays to modify link detail data
281 + // in the client. (In the near future, this will be done on the server).
282 + function modifyLinkDataHook(data, extra) {
283 + var cb = _hook('modifylinkdata');
284 + return cb && extra ? cb(data, extra) : data;
285 + }
286 +
280 // === ----------------------------------------------------- 287 // === -----------------------------------------------------
281 // Event (from server) Handlers 288 // Event (from server) Handlers
282 289
...@@ -427,7 +434,8 @@ ...@@ -427,7 +434,8 @@
427 singleSelect: singleSelectHook, 434 singleSelect: singleSelectHook,
428 multiSelect: multiSelectHook, 435 multiSelect: multiSelectHook,
429 mouseOver: mouseOverHook, 436 mouseOver: mouseOverHook,
430 - mouseOut: mouseOutHook 437 + mouseOut: mouseOutHook,
438 + modifyLinkData: modifyLinkDataHook
431 }, 439 },
432 440
433 showHighlights: showHighlights 441 showHighlights: showHighlights
......
...@@ -309,7 +309,7 @@ ...@@ -309,7 +309,7 @@
309 var coreOrder = [ 309 var coreOrder = [
310 'Type', 'Expected', '-', 310 'Type', 'Expected', '-',
311 'A_type', 'A_id', 'A_label', 'A_port', '-', 311 'A_type', 'A_id', 'A_label', 'A_port', '-',
312 - 'B_type', 'B_id', 'B_label', 'B_port', '-' 312 + 'B_type', 'B_id', 'B_label', 'B_port'
313 ], 313 ],
314 edgeOrder = [ 314 edgeOrder = [
315 'Type', '-', 315 'Type', '-',
...@@ -317,7 +317,7 @@ ...@@ -317,7 +317,7 @@
317 'B_type', 'B_id', 'B_label', 'B_port' 317 'B_type', 'B_id', 'B_label', 'B_port'
318 ]; 318 ];
319 319
320 - function displayLink(data) { 320 + function displayLink(data, modifyCb) {
321 detail.setup(); 321 detail.setup();
322 322
323 var svg = detail.appendHeader('div') 323 var svg = detail.appendHeader('div')
...@@ -332,9 +332,8 @@ ...@@ -332,9 +332,8 @@
332 gs.addGlyph(svg, 'ports', 40); 332 gs.addGlyph(svg, 'ports', 40);
333 title.text('Link'); 333 title.text('Link');
334 334
335 - 335 + var linkData = {
336 - listProps(tbody, { 336 + propOrder: order.slice(0), // makes a copy of the array
337 - propOrder: order,
338 props: { 337 props: {
339 Type: linkType(data), 338 Type: linkType(data),
340 Expected: linkExpected(data), 339 Expected: linkExpected(data),
...@@ -349,9 +348,11 @@ ...@@ -349,9 +348,11 @@
349 B_label: friendly(data.target), 348 B_label: friendly(data.target),
350 B_port: data.tgtPort 349 B_port: data.tgtPort
351 } 350 }
352 - }); 351 + };
352 + listProps(tbody, modifyCb(linkData, data.extra));
353 353
354 if (!edgeLink) { 354 if (!edgeLink) {
355 + addSep(tbody);
355 addProp(tbody, 'A &rarr; B', linkSummary(data.fromSource)); 356 addProp(tbody, 'A &rarr; B', linkSummary(data.fromSource));
356 addProp(tbody, 'B &rarr; A', linkSummary(data.fromTarget)); 357 addProp(tbody, 'B &rarr; A', linkSummary(data.fromTarget));
357 } 358 }
......