GUI -- Continued work on supporting GUI failover. WIP
- Thomas to complete.
Change-Id: I4ed40a0d5b0b48cd1d9fac175a1f66e81df7dacf
diff --git a/web/gui/src/main/webapp/app/fw/remote/urlfn.js b/web/gui/src/main/webapp/app/fw/remote/urlfn.js
index c2addef..6ec01b4 100644
--- a/web/gui/src/main/webapp/app/fw/remote/urlfn.js
+++ b/web/gui/src/main/webapp/app/fw/remote/urlfn.js
@@ -33,25 +33,25 @@
return secure ? protocol + 's' : protocol;
}
- function urlBase(protocol, port) {
+ function urlBase(protocol, port, host) {
return matchSecure(protocol) + '://' +
- $loc.host() + ':' + (port || $loc.port());
+ (host || $loc.host()) + ':' + (port || $loc.port());
}
function httpPrefix(suffix) {
return urlBase('http') + suffix;
}
- function wsPrefix(suffix, wsport) {
- return urlBase('ws', wsport) + suffix;
+ function wsPrefix(suffix, wsport, host) {
+ return urlBase('ws', wsport, host) + suffix;
}
function rsUrl(path) {
return httpPrefix(rsSuffix) + path;
}
- function wsUrl(path, wsport) {
- return wsPrefix(wsSuffix, wsport) + path;
+ function wsUrl(path, wsport, host) {
+ return wsPrefix(wsSuffix, wsport, host) + path;
}
return {
diff --git a/web/gui/src/main/webapp/app/fw/remote/websocket.js b/web/gui/src/main/webapp/app/fw/remote/websocket.js
index 861bb40..f1a4d52 100644
--- a/web/gui/src/main/webapp/app/fw/remote/websocket.js
+++ b/web/gui/src/main/webapp/app/fw/remote/websocket.js
@@ -24,30 +24,45 @@
var $log, $loc, fs, ufs, wsock, vs;
// internal state
- var ws = null, // web socket reference
+ var webSockOpts, // web socket options
+ ws = null, // web socket reference
wsUp = false, // web socket is good to go
sid = 0, // event sequence identifier
handlers = {}, // event handler bindings
pendingEvents = [], // events TX'd while socket not up
url, // web socket URL
- instances = [];
+ clusterNodes = [], // ONOS instances data for failover
+ clusterIndex = -1, // the instance to which we are connected
+ connectRetries = 0;
+
+ // =======================
+ // === Bootstrap Handler
var builtinHandlers = {
- onosInstances: function (data) {
- instances = data.instances;
- }
- }
+ bootstrap: function (data) {
+ clusterNodes = data.instances;
+ clusterNodes.forEach(function (d, i) {
+ if (d.uiAttached) {
+ clusterIndex = i;
+ }
+ });
+ }
+ };
// ==========================
// === Web socket callbacks
function handleOpen() {
$log.info('Web socket open');
+ vs.hide();
+
$log.debug('Sending ' + pendingEvents.length + ' pending event(s)...');
pendingEvents.forEach(function (ev) {
_send(ev);
});
pendingEvents = [];
+
+ connectRetries = 0;
wsUp = true;
}
@@ -76,23 +91,42 @@
}
function handleClose() {
+ var gsucc;
+
$log.info('Web socket closed');
wsUp = false;
- // FIXME: implement controller failover logic
-
- // If no controllers left to contact, show the Veil...
- vs.show([
- 'Oops!',
- 'Web-socket connection to server closed...',
- 'Try refreshing the page.'
- ]);
+ if (gsucc = findGuiSuccessor()) {
+ createWebSocket(webSockOpts, gsucc);
+ } else {
+ // If no controllers left to contact, show the Veil...
+ vs.show([
+ 'Oops!',
+ 'Web-socket connection to server closed...',
+ 'Try refreshing the page.'
+ ]);
+ }
}
// ==============================
// === Private Helper Functions
+ function findGuiSuccessor() {
+ var ncn = clusterNodes.length,
+ ip = undefined,
+ node;
+
+ while (connectRetries < ncn && !ip) {
+ connectRetries++;
+ clusterIndex = (clusterIndex + 1) % ncn;
+ node = clusterNodes[clusterIndex];
+ ip = node && node.ip;
+ }
+
+ return ip;
+ }
+
function _send(ev) {
$log.debug(' *Tx* >> ', ev.event, ev.payload);
ws.send(JSON.stringify(ev));
@@ -109,10 +143,12 @@
// Currently supported opts:
// wsport: web socket port (other than default 8181)
- function createWebSocket(opts) {
+ // server: if defined, is the server address to use
+ function createWebSocket(opts, server) {
var wsport = (opts && opts.wsport) || null;
+ webSockOpts = opts; // preserved for future calls
- url = ufs.wsUrl('core', wsport);
+ url = ufs.wsUrl('core', wsport, server);
$log.debug('Attempting to open websocket to: ' + url);
ws = wsock.newWebSocket(url);
@@ -192,10 +228,7 @@
wsock = _wsock_;
vs = _vs_;
- // Bind instance handlers
- bindHandlers({
- onosInstances: builtinHandlers
- });
+ bindHandlers(builtinHandlers);
return {
resetSid: resetSid,
diff --git a/web/gui/src/main/webapp/tests/app/fw/remote/urlfn-spec.js b/web/gui/src/main/webapp/tests/app/fw/remote/urlfn-spec.js
index ebcfba5..eddbf8b 100644
--- a/web/gui/src/main/webapp/tests/app/fw/remote/urlfn-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/remote/urlfn-spec.js
@@ -81,4 +81,9 @@
setLoc('http', 'foo', '123');
expect(ufs.wsUrl('xyyzy', 456)).toEqual('ws://foo:456/onos/ui/websock/xyyzy');
});
+
+ it('should allow us to define an alternate host', function () {
+ setLoc('http', 'foo', '123');
+ expect(ufs.wsUrl('core', 456, 'bar')).toEqual('ws://bar:456/onos/ui/websock/core');
+ });
});