ONOS-4646: Provide temp. mechanism for topology overlays to modify link details data.
Change-Id: I00b78b1da1580883e09af87ed470e6142a1ec19b
diff --git a/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java b/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java
index 7175bc6..b598bdd 100644
--- a/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java
+++ b/core/api/src/main/java/org/onosproject/ui/UiTopoOverlay.java
@@ -18,10 +18,13 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostId;
+import org.onosproject.net.link.LinkEvent;
import org.onosproject.ui.topo.PropertyPanel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Map;
+
/**
* Represents user interface topology view overlay.
*/
@@ -106,7 +109,7 @@
* a selected device.
* This default implementation does nothing.
*
- * @param pp property panel model of summary data
+ * @param pp property panel model of summary data
* @param deviceId device id
*/
public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) {
@@ -117,9 +120,29 @@
* a selected host.
* This default implementation does nothing.
*
- * @param pp property panel model of summary data
+ * @param pp property panel model of summary data
* @param hostId host id
*/
public void modifyHostDetails(PropertyPanel pp, HostId hostId) {
}
+
+ /**
+ * Callback invoked when a link event is processed (e.g. link added).
+ * A subclass may override this method to return a map of property
+ * key/value pairs to be included in the JSON event back to the client,
+ * so that those additional properties are available to be displayed as
+ * link details.
+ * <p>
+ * The default implementation returns {@code null}, that is, no additional
+ * properties to be added.
+ *
+ * @param event the link event
+ * @return map of additional key/value pairs to be added to the JSON event
+ * @deprecated this is a temporary addition for Goldeneye (1.6) release,
+ * and expected to be replaced in the Hummingbird (1.7) release
+ */
+ @Deprecated
+ public Map<String, String> additionalLinkData(LinkEvent event) {
+ return null;
+ }
}
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
index 57c5a7b..7ba4609 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
@@ -71,6 +71,7 @@
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
@@ -128,6 +129,8 @@
private static final String TOPO_START_DONE = "topoStartDone";
// fields
+ private static final String PAYLOAD = "payload";
+ private static final String EXTRA = "extra";
private static final String ID = "id";
private static final String KEY = "key";
private static final String APP_ID = "appId";
@@ -603,7 +606,7 @@
Collections.sort(nodes, NODE_COMPARATOR);
for (ControllerNode node : nodes) {
sendMessage(instanceMessage(new ClusterEvent(INSTANCE_ADDED, node),
- messageType));
+ messageType));
}
}
@@ -612,13 +615,13 @@
// Send optical first, others later for layered rendering
for (Device device : deviceService.getDevices()) {
if ((device.type() == Device.Type.ROADM) ||
- (device.type() == Device.Type.OTN)) {
+ (device.type() == Device.Type.OTN)) {
sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
}
}
for (Device device : deviceService.getDevices()) {
if ((device.type() != Device.Type.ROADM) &&
- (device.type() != Device.Type.OTN)) {
+ (device.type() != Device.Type.OTN)) {
sendMessage(deviceMessage(new DeviceEvent(DEVICE_ADDED, device)));
}
}
@@ -629,16 +632,40 @@
// Send optical first, others later for layered rendering
for (Link link : linkService.getLinks()) {
if (link.type() == Link.Type.OPTICAL) {
- sendMessage(linkMessage(new LinkEvent(LINK_ADDED, link)));
+ sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
}
}
for (Link link : linkService.getLinks()) {
if (link.type() != Link.Type.OPTICAL) {
- sendMessage(linkMessage(new LinkEvent(LINK_ADDED, link)));
+ sendMessage(composeLinkMessage(new LinkEvent(LINK_ADDED, link)));
}
}
}
+ // Temporary mechanism to support topology overlays adding their own
+ // properties to the link events.
+ private ObjectNode composeLinkMessage(LinkEvent event) {
+ // start with base message
+ ObjectNode msg = linkMessage(event);
+ Map<String, String> additional =
+ overlayCache.currentOverlay().additionalLinkData(event);
+
+ if (additional != null) {
+ // attach additional key-value pairs as extra data structure
+ ObjectNode payload = (ObjectNode) msg.get(PAYLOAD);
+ payload.set(EXTRA, createExtra(additional));
+ }
+ return msg;
+ }
+
+ private ObjectNode createExtra(Map<String, String> additional) {
+ ObjectNode extra = objectNode();
+ for (Map.Entry<String, String> entry : additional.entrySet()) {
+ extra.put(entry.getKey(), entry.getValue());
+ }
+ return extra;
+ }
+
// Sends all hosts to the client as host-added messages.
private void sendAllHosts() {
for (Host host : hostService.getHosts()) {
@@ -759,7 +786,7 @@
private class InternalLinkListener implements LinkListener {
@Override
public void event(LinkEvent event) {
- msgSender.execute(() -> sendMessage(linkMessage(event)));
+ msgSender.execute(() -> sendMessage(composeLinkMessage(event)));
msgSender.execute(traffic::pokeIntent);
eventAccummulator.add(event);
}
@@ -829,7 +856,7 @@
String me = this.toString();
String miniMe = me.replaceAll("^.*@", "me@");
log.debug("Time: {}; this: {}, processing items ({} events)",
- now, miniMe, items.size());
+ now, miniMe, items.size());
// End-of-Debugging
try {
diff --git a/web/gui/src/main/webapp/app/view/topo/topoLink.js b/web/gui/src/main/webapp/app/view/topo/topoLink.js
index 7a9ad1d..95a9daa 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoLink.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoLink.js
@@ -23,7 +23,7 @@
'use strict';
// injected refs
- var $log, fs, sus, ts, flash, tss, tps;
+ var $log, fs, sus, ts, flash, tss, tps, tov;
// internal state
var api,
@@ -238,7 +238,7 @@
d.el.classed('selected', true);
- tps.displayLink(d);
+ tps.displayLink(d, tov.hooks.modifyLinkData);
tps.displaySomething();
}
@@ -300,9 +300,9 @@
angular.module('ovTopo')
.factory('TopoLinkService',
['$log', 'FnService', 'SvgUtilService', 'ThemeService', 'FlashService',
- 'TopoSelectService', 'TopoPanelService',
+ 'TopoSelectService', 'TopoPanelService', 'TopoOverlayService',
- function (_$log_, _fs_, _sus_, _ts_, _flash_, _tss_, _tps_) {
+ function (_$log_, _fs_, _sus_, _ts_, _flash_, _tss_, _tps_, _tov_) {
$log = _$log_;
fs = _fs_;
sus = _sus_;
@@ -310,6 +310,7 @@
flash = _flash_;
tss = _tss_;
tps = _tps_;
+ tov = _tov_;
function initLink(_api_, _td3_) {
api = _api_;
diff --git a/web/gui/src/main/webapp/app/view/topo/topoModel.js b/web/gui/src/main/webapp/app/view/topo/topoModel.js
index d8f279b..d104449 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoModel.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoModel.js
@@ -230,7 +230,8 @@
ws = (s && s.linkWidth) || 0,
wt = (t && t.linkWidth) || 0;
return lnk.position.multiLink ? 5 : Math.max(ws, wt);
- }
+ },
+ extra: link.extra
});
return lnk;
}
diff --git a/web/gui/src/main/webapp/app/view/topo/topoOverlay.js b/web/gui/src/main/webapp/app/view/topo/topoOverlay.js
index 0add26c..b04bd53 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoOverlay.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoOverlay.js
@@ -277,6 +277,13 @@
cb && cb();
}
+ // Temporary function to allow overlays to modify link detail data
+ // in the client. (In the near future, this will be done on the server).
+ function modifyLinkDataHook(data, extra) {
+ var cb = _hook('modifylinkdata');
+ return cb && extra ? cb(data, extra) : data;
+ }
+
// === -----------------------------------------------------
// Event (from server) Handlers
@@ -427,7 +434,8 @@
singleSelect: singleSelectHook,
multiSelect: multiSelectHook,
mouseOver: mouseOverHook,
- mouseOut: mouseOutHook
+ mouseOut: mouseOutHook,
+ modifyLinkData: modifyLinkDataHook
},
showHighlights: showHighlights
diff --git a/web/gui/src/main/webapp/app/view/topo/topoPanel.js b/web/gui/src/main/webapp/app/view/topo/topoPanel.js
index f5730dd..edea27b 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoPanel.js
@@ -309,7 +309,7 @@
var coreOrder = [
'Type', 'Expected', '-',
'A_type', 'A_id', 'A_label', 'A_port', '-',
- 'B_type', 'B_id', 'B_label', 'B_port', '-'
+ 'B_type', 'B_id', 'B_label', 'B_port'
],
edgeOrder = [
'Type', '-',
@@ -317,7 +317,7 @@
'B_type', 'B_id', 'B_label', 'B_port'
];
- function displayLink(data) {
+ function displayLink(data, modifyCb) {
detail.setup();
var svg = detail.appendHeader('div')
@@ -332,9 +332,8 @@
gs.addGlyph(svg, 'ports', 40);
title.text('Link');
-
- listProps(tbody, {
- propOrder: order,
+ var linkData = {
+ propOrder: order.slice(0), // makes a copy of the array
props: {
Type: linkType(data),
Expected: linkExpected(data),
@@ -349,9 +348,11 @@
B_label: friendly(data.target),
B_port: data.tgtPort
}
- });
+ };
+ listProps(tbody, modifyCb(linkData, data.extra));
if (!edgeLink) {
+ addSep(tbody);
addProp(tbody, 'A → B', linkSummary(data.fromSource));
addProp(tbody, 'B → A', linkSummary(data.fromTarget));
}