ONOS-3129 : GUI Intents to Topo :: part 2 - pushing data through topo view and having the intent path show up.
Change-Id: Ie626a46e189d2b704d683e0f58762a68cd3d3a7d
diff --git a/core/api/src/main/java/org/onosproject/ui/table/cell/AppIdFormatter.java b/core/api/src/main/java/org/onosproject/ui/table/cell/AppIdFormatter.java
index 0e1c248..f7947a7 100644
--- a/core/api/src/main/java/org/onosproject/ui/table/cell/AppIdFormatter.java
+++ b/core/api/src/main/java/org/onosproject/ui/table/cell/AppIdFormatter.java
@@ -27,6 +27,7 @@
// non-instantiable
private AppIdFormatter() { }
+ // NOTE: do not change this format; we parse it on the client side.
@Override
protected String nonNullFormat(Object value) {
ApplicationId appId = (ApplicationId) value;
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 292a5f9..82b7a78 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
@@ -27,6 +27,7 @@
import org.onosproject.cluster.ControllerNode;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
+import org.onosproject.core.DefaultApplicationId;
import org.onosproject.event.Event;
import org.onosproject.mastership.MastershipAdminService;
import org.onosproject.mastership.MastershipEvent;
@@ -49,11 +50,14 @@
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.intent.HostToHostIntent;
+import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentEvent;
import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.link.LinkListener;
+import org.onosproject.ui.JsonUtils;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.impl.TrafficMonitor.Mode;
@@ -77,7 +81,9 @@
import static org.onosproject.cluster.ClusterEvent.Type.INSTANCE_ADDED;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.HostId.hostId;
-import static org.onosproject.net.device.DeviceEvent.Type.*;
+import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
+import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_UPDATED;
+import static org.onosproject.net.device.DeviceEvent.Type.PORT_STATS_UPDATED;
import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
import static org.onosproject.ui.JsonUtils.envelope;
@@ -98,6 +104,7 @@
private static final String REQ_NEXT_INTENT = "requestNextRelatedIntent";
private static final String REQ_PREV_INTENT = "requestPrevRelatedIntent";
private static final String REQ_SEL_INTENT_TRAFFIC = "requestSelectedIntentTraffic";
+ private static final String SEL_INTENT = "selectIntent";
private static final String REQ_ALL_FLOW_TRAFFIC = "requestAllFlowTraffic";
private static final String REQ_ALL_PORT_TRAFFIC = "requestAllPortTraffic";
private static final String REQ_DEV_LINK_FLOWS = "requestDeviceLinkFlows";
@@ -118,9 +125,13 @@
private static final String SPRITE_LIST_RESPONSE = "spriteListResponse";
private static final String SPRITE_DATA_RESPONSE = "spriteDataResponse";
private static final String UPDATE_INSTANCE = "updateInstance";
+ private static final String TOPO_START_DONE = "topoStartDone";
// fields
private static final String ID = "id";
+ private static final String KEY = "key";
+ private static final String APP_ID = "appId";
+ private static final String APP_NAME = "appName";
private static final String DEVICE = "device";
private static final String HOST = "host";
private static final String CLASS = "class";
@@ -136,7 +147,7 @@
private static final String DEACTIVATE = "deactivate";
- private static final String APP_ID = "org.onosproject.gui";
+ private static final String MY_APP_ID = "org.onosproject.gui";
private static final long TRAFFIC_PERIOD = 5000;
private static final long SUMMARY_PERIOD = 30000;
@@ -177,7 +188,7 @@
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
- appId = directory.get(CoreService.class).registerApplication(APP_ID);
+ appId = directory.get(CoreService.class).registerApplication(MY_APP_ID);
traffic = new TrafficMonitor(TRAFFIC_PERIOD, servicesBundle, this);
}
@@ -214,6 +225,7 @@
new ReqNextIntent(),
new ReqPrevIntent(),
new ReqSelectedIntentTraffic(),
+ new SelIntent(),
new CancelTraffic()
);
@@ -242,6 +254,7 @@
sendAllDevices();
sendAllLinks();
sendAllHosts();
+ sendTopoStartDone();
}
}
@@ -527,6 +540,31 @@
}
}
+ private final class SelIntent extends RequestHandler {
+ private SelIntent() {
+ super(SEL_INTENT);
+ }
+
+ @Override
+ public void process(long sid, ObjectNode payload) {
+ int appId = Integer.parseInt(string(payload, APP_ID));
+ String appName = string(payload, APP_NAME);
+ ApplicationId applicId = new DefaultApplicationId(appId, appName);
+ long intentKey = Long.decode(string(payload, KEY));
+
+ Key key = Key.of(intentKey, applicId);
+ log.debug("Attempting to select intent key={}", key);
+
+ Intent intent = intentService.getIntent(key);
+ if (intent == null) {
+ log.debug("no such intent found!");
+ } else {
+ log.debug("starting to monitor intent {}", key);
+ traffic.monitor(intent);
+ }
+ }
+ }
+
private final class CancelTraffic extends RequestHandler {
private CancelTraffic() {
super(CANCEL_TRAFFIC);
@@ -626,6 +664,9 @@
return hostIds;
}
+ private void sendTopoStartDone() {
+ sendMessage(JsonUtils.envelope(TOPO_START_DONE, objectNode()));
+ }
private synchronized void startSummaryMonitoring() {
stopSummaryMonitoring();
diff --git a/web/gui/src/main/webapp/app/view/intent/intent.js b/web/gui/src/main/webapp/app/view/intent/intent.js
index cec9062..3ed9cf2 100644
--- a/web/gui/src/main/webapp/app/view/intent/intent.js
+++ b/web/gui/src/main/webapp/app/view/intent/intent.js
@@ -23,12 +23,21 @@
angular.module('ovIntent', [])
.controller('OvIntentCtrl',
- ['$log', '$scope', 'TableBuilderService',
+ ['$log', '$scope', 'TableBuilderService', 'NavService',
- function ($log, $scope, tbs) {
+ function ($log, $scope, tbs, ns) {
function selCb($event, row) {
$log.debug('Got a click on:', row);
+ var m = /(\d+)\s:\s(.*)/.exec(row.appId),
+ id = m ? m[1] : null,
+ name = m ? m[2] : null;
+
+ $scope.intentData = m ? {
+ intentAppId: id,
+ intentAppName: name,
+ intentKey: row.key
+ } : null;
}
tbs.buildTable({
@@ -41,8 +50,9 @@
$scope.topoTip = 'Show selected intent on topology view';
$scope.showIntent = function () {
- // TODO: navigate to topology view with selected intent context
- $log.debug("+++ showIntent +++", $scope.selId);
+ var d = $scope.intentData;
+ $log.debug("+++ showIntent +++", d);
+ ns.navTo('topo', d);
};
$log.log('OvIntentCtrl has been created');
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index 0dfd628..7ddfd13 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -412,6 +412,12 @@
flash.enable(true);
}
+ function topoStartDone() {
+ var d = $scope.intentData;
+ if (d) {
+ tts.selectIntent(d);
+ }
+ }
// --- Controller Definition -----------------------------------------
@@ -430,7 +436,8 @@
_zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _tes_, _tfs_,
_tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_, _ttbs_, tspr,
_ttip_, _tov_) {
- var projection,
+ var params = $loc.search(),
+ projection,
dim,
uplink = {
// provides function calls back into this space
@@ -438,7 +445,8 @@
projection: function () { return projection; },
zoomLayer: function () { return zoomLayer; },
zoomer: function () { return zoomer; },
- opacifyMap: opacifyMap
+ opacifyMap: opacifyMap,
+ topoStartDone: topoStartDone
};
$scope = _$scope_;
@@ -469,6 +477,14 @@
ttip = _ttip_;
tov = _tov_;
+ if (params.intentKey && params.intentAppId && params.intentAppName) {
+ $scope.intentData = {
+ key: params.intentKey,
+ appId: params.intentAppId,
+ appName: params.intentAppName
+ };
+ }
+
$scope.notifyResize = function () {
svgResized(fs.windowSize(mast.mastHeight()));
};
diff --git a/web/gui/src/main/webapp/app/view/topo/topoEvent.js b/web/gui/src/main/webapp/app/view/topo/topoEvent.js
index 5fd38bf..2957629 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoEvent.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoEvent.js
@@ -60,6 +60,8 @@
updateLink: tfs,
removeLink: tfs,
+ topoStartDone: tfs,
+
spriteListResponse: tspr,
spriteDataResponse: tspr
};
diff --git a/web/gui/src/main/webapp/app/view/topo/topoForce.js b/web/gui/src/main/webapp/app/view/topo/topoForce.js
index f00b87f..844d7dc 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoForce.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoForce.js
@@ -240,6 +240,11 @@
}
}
+ function topoStartDone(data) {
+ // called when the initial barrage of data has been sent from server
+ uplink.topoStartDone();
+ }
+
// ========================
function nodeById(id) {
@@ -1140,7 +1145,8 @@
removeHost: removeHost,
addLink: addLink,
updateLink: updateLink,
- removeLink: removeLink
+ removeLink: removeLink,
+ topoStartDone: topoStartDone
};
}]);
}());
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 9a3b435..2dee4c4 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoOverlay.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoOverlay.js
@@ -34,7 +34,8 @@
// internal state
var overlays = {},
- current = null;
+ current = null,
+ reset = true;
function error(fn, msg) {
$log.error(tos + fn + '(): ' + msg);
@@ -144,7 +145,8 @@
payload[op] = oid;
}
- if (!same) {
+ if (reset || !same) {
+ reset = false;
current && doop('deactivate');
current = overlays[id];
current && doop('activate');
@@ -390,6 +392,7 @@
tbSelection: tbSelection,
installButtons: installButtons,
addDetailButton: addDetailButton,
+ resetOnToolbarDestroy: function () { reset = true; },
hooks: {
escape: escapeHook,
emptySelect: emptySelectHook,
diff --git a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
index 3928cd2..0628544 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
@@ -243,6 +243,7 @@
function destroyToolbar() {
tbs.destroyToolbar(name);
+ tov.resetOnToolbarDestroy();
}
// allows us to ensure the button states track key strokes
diff --git a/web/gui/src/main/webapp/app/view/topo/topoTraffic.js b/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
index ca37936..ff690c4 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
@@ -152,6 +152,14 @@
}
}
+ // force the system to create a single intent selection
+ function selectIntent(data) {
+ trafficMode = 'intents';
+ hoverMode = null;
+ wss.sendEvent('selectIntent', data);
+ flash.flash('Selecting Intent ' + data.key);
+ }
+
// === ------------------------------------------------------
// action buttons on detail panel (multiple selection)
@@ -207,6 +215,7 @@
showPrevIntent: showPrevIntent,
showNextIntent: showNextIntent,
showSelectedIntentTraffic: showSelectedIntentTraffic,
+ selectIntent: selectIntent,
// invoked from mouseover/mouseout and selection change
requestTrafficForMode: requestTrafficForMode,