mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-17 10:21:52 +02:00
Added Collections and Models for a Region.
Change-Id: Ic033b2890dad18e47b057e6b1d1c8535d812590d
This commit is contained in:
parent
9f0af2db68
commit
57e24e9d66
2
.gitignore
vendored
2
.gitignore
vendored
@ -22,5 +22,7 @@ bucklets/plugins/
|
||||
/bin/
|
||||
|
||||
web/gui/src/main/webapp/tests/node_modules
|
||||
web/gui/src/test/_karma/node_modules
|
||||
web/gui/src/main/webapp/node_modules/
|
||||
|
||||
npm-debug.log
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
ONOS GUI -- Topology View Module
|
||||
@ -28,7 +28,7 @@
|
||||
fs, mast, ks, zs,
|
||||
gs, ms, sus, flash,
|
||||
wss, ps, th,
|
||||
t2es, t2fs;
|
||||
t2es, t2fs, t2is;
|
||||
|
||||
// DOM elements
|
||||
var ovtopo2, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer;
|
||||
@ -37,32 +37,66 @@
|
||||
var zoomer, actionMap;
|
||||
|
||||
|
||||
// === Helper Functions
|
||||
// --- Glyphs, Icons, and the like -----------------------------------
|
||||
|
||||
function setUpDefs() {
|
||||
defs = svg.append('defs');
|
||||
gs.loadDefs(defs);
|
||||
sus.loadGlowDefs(defs);
|
||||
}
|
||||
|
||||
// callback invoked when the SVG view has been resized..
|
||||
function svgResized(s) {
|
||||
$log.debug("topo2 view resized", s);
|
||||
$log.debug('topo2 view resized', s);
|
||||
}
|
||||
|
||||
function setUpKeys(overlayKeys) {
|
||||
$log.debug('topo2: set up keys....');
|
||||
}
|
||||
|
||||
// --- Pan and Zoom --------------------------------------------------
|
||||
|
||||
// zoom enabled predicate. ev is a D3 source event.
|
||||
function zoomEnabled(ev) {
|
||||
return fs.isMobile() || (ev.metaKey || ev.altKey);
|
||||
}
|
||||
|
||||
function zoomCallback() {
|
||||
var sc = zoomer.scale(),
|
||||
tr = zoomer.translate();
|
||||
|
||||
ps.setPrefs('topo_zoom', {tx:tr[0], ty:tr[1], sc:sc});
|
||||
|
||||
// keep the map lines constant width while zooming
|
||||
mapG.style('stroke-width', (2.0 / sc) + 'px');
|
||||
}
|
||||
|
||||
function setUpZoom() {
|
||||
zoomLayer = svg.append('g').attr('id', 'topo-zoomlayer');
|
||||
zoomer = zs.createZoomer({
|
||||
svg: svg,
|
||||
zoomLayer: zoomLayer,
|
||||
zoomEnabled: zoomEnabled,
|
||||
zoomCallback: zoomCallback
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// === Controller Definition -----------------------------------------
|
||||
|
||||
angular.module('ovTopo2', ['onosUtil', 'onosSvg', 'onosRemote'])
|
||||
.controller('OvTopo2Ctrl',
|
||||
.controller('OvTopo2Ctrl',
|
||||
['$scope', '$log', '$location',
|
||||
'FnService', 'MastService', 'KeyService', 'ZoomService',
|
||||
'GlyphService', 'MapService', 'SvgUtilService', 'FlashService',
|
||||
'WebSocketService', 'PrefsService', 'ThemeService',
|
||||
'Topo2EventService', 'Topo2ForceService',
|
||||
'Topo2EventService', 'Topo2ForceService', 'Topo2InstanceService',
|
||||
|
||||
function (_$scope_, _$log_, _$loc_,
|
||||
_fs_, _mast_, _ks_, _zs_,
|
||||
_gs_, _ms_, _sus_, _flash_,
|
||||
_wss_, _ps_, _th_,
|
||||
_t2es_, _t2fs_) {
|
||||
_fs_, _mast_, _ks_, _zs_,
|
||||
_gs_, _ms_, _sus_, _flash_,
|
||||
_wss_, _ps_, _th_,
|
||||
_t2es_, _t2fs_, _t2is_) {
|
||||
|
||||
var params = _$loc_.search(),
|
||||
projection,
|
||||
@ -95,9 +129,10 @@
|
||||
wss = _wss_;
|
||||
ps = _ps_;
|
||||
th = _th_;
|
||||
|
||||
|
||||
t2es = _t2es_;
|
||||
t2fs = _t2fs_;
|
||||
t2is = _t2is_;
|
||||
|
||||
// capture selected intent parameters (if they are set in the
|
||||
// query string) so that the traffic overlay can highlight
|
||||
@ -134,24 +169,32 @@
|
||||
|
||||
// set up our keyboard shortcut bindings
|
||||
setUpKeys();
|
||||
setUpZoom();
|
||||
setUpDefs();
|
||||
|
||||
// make sure we can respond to topology events from the server
|
||||
t2es.bindHandlers();
|
||||
|
||||
// initialize the force layout, ready to render the topology
|
||||
t2fs.init();
|
||||
forceG = zoomLayer.append('g').attr('id', 'topo-force');
|
||||
t2fs.init(svg, forceG, uplink, dim);
|
||||
|
||||
|
||||
// =-=-=-=-=-=-=-=-
|
||||
// TODO: in future, we will load background map data
|
||||
// asynchronously (hence the promise) and then chain off
|
||||
// asynchronously (hence the promise) and then chain off
|
||||
// there to send the topo2start event to the server.
|
||||
// For now, we'll send the event inline...
|
||||
t2es.start();
|
||||
|
||||
|
||||
|
||||
|
||||
t2is.initInst({ showMastership: t2fs.showMastership });
|
||||
|
||||
|
||||
|
||||
// === ORIGINAL CODE ===
|
||||
|
||||
|
||||
// setUpKeys();
|
||||
// setUpToolbar();
|
||||
// setUpDefs();
|
||||
@ -192,7 +235,7 @@
|
||||
// ttbs.setDefaultOverlay(prefsState.ovidx);
|
||||
|
||||
// $log.debug('registered overlays...', tov.list());
|
||||
|
||||
|
||||
$log.log('OvTopo2Ctrl has been created');
|
||||
}]);
|
||||
}());
|
||||
|
116
web/gui/src/main/webapp/app/view/topo2/topo2Collection.js
Normal file
116
web/gui/src/main/webapp/app/view/topo2/topo2Collection.js
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
ONOS GUI -- Topology Collection Module.
|
||||
A Data Store that contains model data from the server
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var Model;
|
||||
|
||||
function Collection(models, options) {
|
||||
|
||||
options || (options = {});
|
||||
|
||||
this.models = [];
|
||||
this._reset();
|
||||
|
||||
if (options.comparator !== void 0) this.comparator = options.comparator;
|
||||
|
||||
if (models) {
|
||||
this.add(models);
|
||||
}
|
||||
}
|
||||
|
||||
Collection.prototype = {
|
||||
model: Model,
|
||||
add: function (data) {
|
||||
|
||||
var _this = this;
|
||||
|
||||
if (angular.isArray(data)) {
|
||||
|
||||
data.forEach(function (d) {
|
||||
|
||||
var model = new _this.model(d);
|
||||
model.collection = _this;
|
||||
|
||||
_this.models.push(model);
|
||||
_this._byId[d.id] = model;
|
||||
});
|
||||
}
|
||||
|
||||
// this.sort();
|
||||
},
|
||||
get: function (id) {
|
||||
if (!id) {
|
||||
return void 0;
|
||||
}
|
||||
return this._byId[id] || null;
|
||||
},
|
||||
sort: function () {
|
||||
|
||||
var comparator = this.comparator;
|
||||
|
||||
// Check if function
|
||||
comparator = comparator.bind(this);
|
||||
this.models.sort(comparator);
|
||||
|
||||
return this;
|
||||
},
|
||||
_reset: function () {
|
||||
this._byId = [];
|
||||
this.models = [];
|
||||
}
|
||||
};
|
||||
|
||||
Collection.extend = function (protoProps, staticProps) {
|
||||
|
||||
var parent = this;
|
||||
var child;
|
||||
|
||||
child = function () {
|
||||
return parent.apply(this, arguments);
|
||||
};
|
||||
|
||||
angular.extend(child, parent, staticProps);
|
||||
|
||||
// Set the prototype chain to inherit from `parent`, without calling
|
||||
// `parent`'s constructor function and add the prototype properties.
|
||||
child.prototype = angular.extend({}, parent.prototype, protoProps);
|
||||
child.prototype.constructor = child;
|
||||
|
||||
// Set a convenience property in case the parent's prototype is needed
|
||||
// later.
|
||||
child.__super__ = parent.prototype;
|
||||
|
||||
return child;
|
||||
};
|
||||
|
||||
angular.module('ovTopo2')
|
||||
.factory('Topo2Collection',
|
||||
['Topo2Model',
|
||||
function (_Model_) {
|
||||
|
||||
Model = _Model_;
|
||||
return Collection;
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
67
web/gui/src/main/webapp/app/view/topo2/topo2Device.js
Normal file
67
web/gui/src/main/webapp/app/view/topo2/topo2Device.js
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
ONOS GUI -- Topology Devices Module.
|
||||
Module that holds the devices for a region
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var Collection, Model;
|
||||
|
||||
function createDeviceCollection(data, region) {
|
||||
|
||||
var DeviceCollection = Collection.extend({
|
||||
model: Model,
|
||||
get: function () {},
|
||||
comparator: function(a, b) {
|
||||
|
||||
var order = region.layerOrder;
|
||||
return order.indexOf(a.get('layer')) - order.indexOf(b.get('layer'));
|
||||
}
|
||||
});
|
||||
|
||||
var devices = [];
|
||||
data.forEach(function (deviceLayer) {
|
||||
deviceLayer.forEach(function (device) {
|
||||
devices.push(device);
|
||||
});
|
||||
});
|
||||
|
||||
var deviceCollection = new DeviceCollection(devices);
|
||||
deviceCollection.sort();
|
||||
|
||||
return deviceCollection;
|
||||
}
|
||||
|
||||
angular.module('ovTopo2')
|
||||
.factory('Topo2DeviceService',
|
||||
['Topo2Collection', 'Topo2Model',
|
||||
|
||||
function (_Collection_, _Model_) {
|
||||
|
||||
Collection = _Collection_;
|
||||
Model = _Model_.extend({});
|
||||
|
||||
return {
|
||||
createDeviceCollection: createDeviceCollection
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
@ -23,12 +23,99 @@
|
||||
'use strict';
|
||||
|
||||
// injected refs
|
||||
var $log, wss;
|
||||
var $log,
|
||||
wss;
|
||||
|
||||
// SVG elements;
|
||||
var linkG,
|
||||
linkLabelG,
|
||||
numLinkLblsG,
|
||||
portLabelG,
|
||||
nodeG;
|
||||
|
||||
// internal state
|
||||
var settings, // merged default settings and options
|
||||
force, // force layout object
|
||||
drag, // drag behavior handler
|
||||
network = {
|
||||
nodes: [],
|
||||
links: [],
|
||||
linksByDevice: {},
|
||||
lookup: {},
|
||||
revLinkToKey: {}
|
||||
},
|
||||
lu, // shorthand for lookup
|
||||
rlk, // shorthand for revLinktoKey
|
||||
showHosts = false, // whether hosts are displayed
|
||||
showOffline = true, // whether offline devices are displayed
|
||||
nodeLock = false, // whether nodes can be dragged or not (locked)
|
||||
fTimer, // timer for delayed force layout
|
||||
fNodesTimer, // timer for delayed nodes update
|
||||
fLinksTimer, // timer for delayed links update
|
||||
dim, // the dimensions of the force layout [w,h]
|
||||
linkNums = []; // array of link number labels
|
||||
|
||||
// D3 selections;
|
||||
var link,
|
||||
linkLabel,
|
||||
node;
|
||||
|
||||
var $log, wss, t2is, t2rs;
|
||||
|
||||
// ========================== Helper Functions
|
||||
|
||||
function init() {
|
||||
function init(_svg_, forceG, _uplink_, _dim_, opts) {
|
||||
|
||||
$log.debug('Initialize topo force layout');
|
||||
|
||||
nodeG = forceG.append('g').attr('id', 'topo-nodes');
|
||||
node = nodeG.selectAll('.node');
|
||||
|
||||
linkG = forceG.append('g').attr('id', 'topo-links');
|
||||
linkLabelG = forceG.append('g').attr('id', 'topo-linkLabels');
|
||||
numLinkLblsG = forceG.append('g').attr('id', 'topo-numLinkLabels');
|
||||
nodeG = forceG.append('g').attr('id', 'topo-nodes');
|
||||
portLabelG = forceG.append('g').attr('id', 'topo-portLabels');
|
||||
|
||||
link = linkG.selectAll('.link');
|
||||
linkLabel = linkLabelG.selectAll('.linkLabel');
|
||||
node = nodeG.selectAll('.node');
|
||||
|
||||
var width = 640,
|
||||
height = 480;
|
||||
|
||||
var nodes = [
|
||||
{ x: width/3, y: height/2 },
|
||||
{ x: 2*width/3, y: height/2 }
|
||||
];
|
||||
|
||||
var links = [
|
||||
{ source: 0, target: 1 }
|
||||
];
|
||||
|
||||
var svg = d3.select('body').append('svg')
|
||||
.attr('width', width)
|
||||
.attr('height', height);
|
||||
|
||||
var force = d3.layout.force()
|
||||
.size([width, height])
|
||||
.nodes(nodes)
|
||||
.links(links);
|
||||
|
||||
force.linkDistance(width/2);
|
||||
|
||||
|
||||
var link = svg.selectAll('.link')
|
||||
.data(links)
|
||||
.enter().append('line')
|
||||
.attr('class', 'link');
|
||||
|
||||
var node = svg.selectAll('.node')
|
||||
.data(nodes)
|
||||
.enter().append('circle')
|
||||
.attr('class', 'node');
|
||||
|
||||
force.start();
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
@ -106,17 +193,19 @@
|
||||
// ========================== Event Handlers
|
||||
|
||||
function allInstances(data) {
|
||||
$log.debug('>> topo2AllInstances event:', data)
|
||||
$log.debug('>> topo2AllInstances event:', data);
|
||||
doTmpCurrentLayout(data);
|
||||
t2is.allInstances(data);
|
||||
}
|
||||
|
||||
function currentLayout(data) {
|
||||
$log.debug('>> topo2CurrentLayout event:', data)
|
||||
$log.debug('>> topo2CurrentLayout event:', data);
|
||||
}
|
||||
|
||||
function currentRegion(data) {
|
||||
$log.debug('>> topo2CurrentRegion event:', data)
|
||||
$log.debug('>> topo2CurrentRegion event:', data);
|
||||
doTmpCurrentRegion(data);
|
||||
t2rs.addRegion(data);
|
||||
}
|
||||
|
||||
function topo2PeerRegions(data) {
|
||||
@ -129,27 +218,68 @@
|
||||
}
|
||||
|
||||
function startDone(data) {
|
||||
$log.debug('>> topo2StartDone event:', data)
|
||||
$log.debug('>> topo2StartDone event:', data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function showMastership(masterId) {
|
||||
if (!masterId) {
|
||||
restoreLayerState();
|
||||
} else {
|
||||
showMastershipFor(masterId);
|
||||
}
|
||||
}
|
||||
|
||||
function restoreLayerState() {
|
||||
// NOTE: this level of indirection required, for when we have
|
||||
// the layer filter functionality re-implemented
|
||||
suppressLayers(false);
|
||||
}
|
||||
|
||||
// ========================== Main Service Definition
|
||||
|
||||
function showMastershipFor(id) {
|
||||
suppressLayers(true);
|
||||
node.each(function (n) {
|
||||
if (n.master === id) {
|
||||
n.el.classed('suppressedmax', false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function supAmt(less) {
|
||||
return less ? 'suppressed' : 'suppressedmax';
|
||||
}
|
||||
|
||||
function suppressLayers(b, less) {
|
||||
var cls = supAmt(less);
|
||||
node.classed(cls, b);
|
||||
// link.classed(cls, b);
|
||||
}
|
||||
|
||||
// ========================== Main Service Definition
|
||||
|
||||
angular.module('ovTopo2')
|
||||
.factory('Topo2ForceService',
|
||||
['$log', 'WebSocketService',
|
||||
|
||||
function (_$log_, _wss_) {
|
||||
['$log', 'WebSocketService', 'Topo2InstanceService', 'Topo2RegionService',
|
||||
function (_$log_, _wss_, _t2is_, _t2rs_) {
|
||||
$log = _$log_;
|
||||
wss = _wss_;
|
||||
|
||||
t2is = _t2is_;
|
||||
t2rs = _t2rs_;
|
||||
|
||||
return {
|
||||
|
||||
init: init,
|
||||
|
||||
destroy: destroy,
|
||||
topo2AllInstances: allInstances,
|
||||
topo2CurrentLayout: currentLayout,
|
||||
topo2CurrentRegion: currentRegion,
|
||||
topo2PeerRegions: topo2PeerRegions,
|
||||
topo2StartDone: startDone
|
||||
topo2StartDone: startDone,
|
||||
|
||||
showMastership: showMastership,
|
||||
topo2PeerRegions: topo2PeerRegions
|
||||
};
|
||||
}]);
|
||||
}());
|
||||
|
58
web/gui/src/main/webapp/app/view/topo2/topo2Host.js
Normal file
58
web/gui/src/main/webapp/app/view/topo2/topo2Host.js
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
ONOS GUI -- Topology Hosts Module.
|
||||
Module that holds the hosts for a region
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var Collection, Model;
|
||||
|
||||
function createHostCollection(data, region) {
|
||||
|
||||
var HostCollection = Collection.extend({
|
||||
model: Model
|
||||
});
|
||||
|
||||
var hosts = [];
|
||||
data.forEach(function (hostsLayer) {
|
||||
hostsLayer.forEach(function (host) {
|
||||
hosts.push(host);
|
||||
});
|
||||
});
|
||||
|
||||
return new HostCollection(hosts);
|
||||
}
|
||||
|
||||
angular.module('ovTopo2')
|
||||
.factory('Topo2HostService',
|
||||
['Topo2Collection', 'Topo2Model',
|
||||
|
||||
function (_Collection_, _Model_) {
|
||||
|
||||
Collection = _Collection_;
|
||||
Model = _Model_.extend();
|
||||
|
||||
return {
|
||||
createHostCollection: createHostCollection
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
301
web/gui/src/main/webapp/app/view/topo2/topo2Instance.js
Normal file
301
web/gui/src/main/webapp/app/view/topo2/topo2Instance.js
Normal file
@ -0,0 +1,301 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
// injected refs
|
||||
var $log,
|
||||
ps,
|
||||
sus,
|
||||
gs,
|
||||
ts,
|
||||
fs,
|
||||
flash;
|
||||
|
||||
// api from topo
|
||||
var api;
|
||||
|
||||
// configuration
|
||||
var showLogicErrors = true,
|
||||
idIns = 'topo-p-instance',
|
||||
instOpts = {
|
||||
edge: 'left',
|
||||
width: 20
|
||||
};
|
||||
|
||||
// internal state
|
||||
var onosInstances,
|
||||
onosOrder,
|
||||
oiShowMaster,
|
||||
oiBox;
|
||||
|
||||
|
||||
function addInstance(data) {
|
||||
var id = data.id;
|
||||
|
||||
if (onosInstances[id]) {
|
||||
updateInstance(data);
|
||||
return;
|
||||
}
|
||||
onosInstances[id] = data;
|
||||
onosOrder.push(data);
|
||||
updateInstances();
|
||||
}
|
||||
|
||||
function updateInstance(data) {
|
||||
var id = data.id,
|
||||
d = onosInstances[id];
|
||||
if (d) {
|
||||
angular.extend(d, data);
|
||||
updateInstances();
|
||||
} else {
|
||||
logicError('updateInstance: lookup fail: ID = "' + id + '"');
|
||||
}
|
||||
}
|
||||
|
||||
function removeInstance(data) {
|
||||
var id = data.id,
|
||||
d = onosInstances[id];
|
||||
if (d) {
|
||||
var idx = fs.find(id, onosOrder);
|
||||
if (idx >= 0) {
|
||||
onosOrder.splice(idx, 1);
|
||||
}
|
||||
delete onosInstances[id];
|
||||
updateInstances();
|
||||
} else {
|
||||
logicError('removeInstance lookup fail. ID = "' + id + '"');
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================
|
||||
|
||||
function clickInst(d) {
|
||||
var el = d3.select(this),
|
||||
aff = el.classed('affinity');
|
||||
if (!aff) {
|
||||
setAffinity(el, d);
|
||||
} else {
|
||||
cancelAffinity();
|
||||
}
|
||||
}
|
||||
|
||||
function setAffinity(el, d) {
|
||||
d3.selectAll('.onosInst')
|
||||
.classed('mastership', true)
|
||||
.classed('affinity', false);
|
||||
el.classed('affinity', true);
|
||||
|
||||
// suppress all elements except nodes whose master is this instance
|
||||
api.showMastership(d.id);
|
||||
oiShowMaster = true;
|
||||
}
|
||||
|
||||
function cancelAffinity() {
|
||||
d3.selectAll('.onosInst')
|
||||
.classed('mastership affinity', false);
|
||||
|
||||
api.showMastership(null);
|
||||
oiShowMaster = false;
|
||||
}
|
||||
|
||||
function attachUiBadge(svg) {
|
||||
gs.addGlyph(svg, 'uiAttached', 24, true, [14, 54])
|
||||
.classed('badgeIcon uiBadge', true);
|
||||
}
|
||||
|
||||
function attachReadyBadge(svg) {
|
||||
gs.addGlyph(svg, 'checkMark', 16, true, [18, 40])
|
||||
.classed('badgeIcon readyBadge', true);
|
||||
}
|
||||
|
||||
function instColor(id, online) {
|
||||
return sus.cat7().getColor(id, !online, ts.theme());
|
||||
}
|
||||
|
||||
// ==============================
|
||||
|
||||
function updateInstances() {
|
||||
var rox = 5,
|
||||
roy = 5,
|
||||
rw = 160,
|
||||
rhh = 30,
|
||||
rbh = 45,
|
||||
tx = 48,
|
||||
instSvg = {
|
||||
width: 170,
|
||||
height: 85,
|
||||
viewBox: '0 0 170 85'
|
||||
},
|
||||
headRect = {
|
||||
x: rox,
|
||||
y: roy,
|
||||
width: rw,
|
||||
height: rhh
|
||||
},
|
||||
bodyRect = {
|
||||
x: rox,
|
||||
y: roy + rhh,
|
||||
width: rw,
|
||||
height: rbh
|
||||
},
|
||||
titleAttr = {
|
||||
class: 'instTitle',
|
||||
x: tx,
|
||||
y: 27
|
||||
};
|
||||
|
||||
var onoses = oiBox.el().selectAll('.onosInst')
|
||||
.data(onosOrder, function (d) { return d.id; });
|
||||
|
||||
function nSw(n) {
|
||||
return 'Devices: ' + n;
|
||||
}
|
||||
|
||||
// operate on existing onos instances if necessary
|
||||
onoses.each(function (d) {
|
||||
var el = d3.select(this),
|
||||
svg = el.select('svg');
|
||||
|
||||
// update online state
|
||||
el.classed('online', d.online);
|
||||
el.classed('ready', d.ready);
|
||||
|
||||
// update ui-attached state
|
||||
svg.select('use.uiBadge').remove();
|
||||
if (d.uiAttached) {
|
||||
attachUiBadge(svg);
|
||||
}
|
||||
|
||||
function updAttr(id, value) {
|
||||
svg.select('text.instLabel.' + id).text(value);
|
||||
}
|
||||
|
||||
updAttr('ip', d.ip);
|
||||
updAttr('ns', nSw(d.switches));
|
||||
});
|
||||
|
||||
|
||||
// operate on new onos instances
|
||||
var entering = onoses.enter()
|
||||
.append('div')
|
||||
.classed('onosInst', true)
|
||||
.classed('online', function (d) { return d.online; })
|
||||
.classed('ready', function (d) { return d.ready; })
|
||||
.on('click', clickInst);
|
||||
|
||||
entering.each(function (d) {
|
||||
var el = d3.select(this),
|
||||
svg = el.append('svg').attr(instSvg);
|
||||
|
||||
svg.append('rect').attr(headRect);
|
||||
svg.append('rect').attr(bodyRect);
|
||||
|
||||
gs.addGlyph(svg, 'bird', 20, false, [15, 10])
|
||||
.classed('badgeIcon bird', true);
|
||||
|
||||
attachReadyBadge(svg);
|
||||
|
||||
if (d.uiAttached) {
|
||||
attachUiBadge(svg);
|
||||
}
|
||||
|
||||
svg.append('text')
|
||||
.attr(titleAttr)
|
||||
.text(d.id);
|
||||
|
||||
var ty = 55;
|
||||
function addAttr(id, label) {
|
||||
svg.append('text').attr({
|
||||
class: 'instLabel ' + id,
|
||||
x: tx,
|
||||
y: ty
|
||||
}).text(label);
|
||||
ty += 18;
|
||||
}
|
||||
|
||||
addAttr('ip', d.ip);
|
||||
addAttr('ns', nSw(d.switches));
|
||||
});
|
||||
|
||||
// operate on existing + new onoses here
|
||||
// set the affinity colors...
|
||||
onoses.each(function (d) {
|
||||
|
||||
var el = d3.select(this),
|
||||
rect = el.select('svg').select('rect'),
|
||||
col = instColor(d.id, d.online);
|
||||
|
||||
rect.style('fill', col);
|
||||
});
|
||||
|
||||
// adjust the panel size appropriately...
|
||||
oiBox.width(instSvg.width * onosOrder.length);
|
||||
oiBox.height(instSvg.height);
|
||||
|
||||
// remove any outgoing instances
|
||||
onoses.exit().remove();
|
||||
}
|
||||
|
||||
|
||||
// ==========================
|
||||
|
||||
function logicError(msg) {
|
||||
if (showLogicErrors) {
|
||||
$log.warn('TopoInstService: ' + msg);
|
||||
}
|
||||
}
|
||||
|
||||
function initInst(_api_) {
|
||||
api = _api_;
|
||||
oiBox = ps.createPanel(idIns, instOpts);
|
||||
oiBox.show();
|
||||
|
||||
onosInstances = {};
|
||||
onosOrder = [];
|
||||
oiShowMaster = false;
|
||||
|
||||
// we want to update the instances, each time the theme changes
|
||||
ts.addListener(updateInstances);
|
||||
}
|
||||
|
||||
function destroyInst() {
|
||||
ts.removeListener(updateInstances);
|
||||
|
||||
ps.destroyPanel(idIns);
|
||||
oiBox = null;
|
||||
|
||||
onosInstances = {};
|
||||
onosOrder = [];
|
||||
oiShowMaster = false;
|
||||
}
|
||||
|
||||
function allInstances(data) {
|
||||
$log.debug('Update all instances', data);
|
||||
|
||||
var members = data.members;
|
||||
|
||||
members.forEach(function (member) {
|
||||
addInstance(member);
|
||||
});
|
||||
}
|
||||
|
||||
angular.module('ovTopo2')
|
||||
.factory('Topo2InstanceService',
|
||||
['$log', 'PanelService', 'SvgUtilService', 'GlyphService',
|
||||
'ThemeService', 'FnService', 'FlashService',
|
||||
|
||||
function (_$log_, _ps_, _sus_, _gs_, _ts_, _fs_, _flash_) {
|
||||
$log = _$log_;
|
||||
ps = _ps_;
|
||||
sus = _sus_;
|
||||
gs = _gs_;
|
||||
ts = _ts_;
|
||||
fs = _fs_;
|
||||
flash = _flash_;
|
||||
|
||||
return {
|
||||
initInst: initInst,
|
||||
allInstances: allInstances
|
||||
};
|
||||
}]);
|
||||
|
||||
}());
|
51
web/gui/src/main/webapp/app/view/topo2/topo2Link.js
Normal file
51
web/gui/src/main/webapp/app/view/topo2/topo2Link.js
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
ONOS GUI -- Topology Links Module.
|
||||
Module that holds the links for a region
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var Collection, Model;
|
||||
|
||||
function createLinkCollection(data, region) {
|
||||
|
||||
var LinkCollection = Collection.extend({
|
||||
model: Model
|
||||
});
|
||||
|
||||
return new LinkCollection(data);
|
||||
}
|
||||
|
||||
angular.module('ovTopo2')
|
||||
.factory('Topo2LinkService',
|
||||
['Topo2Collection', 'Topo2Model',
|
||||
|
||||
function (_Collection_, _Model_) {
|
||||
|
||||
Collection = _Collection_;
|
||||
Model = _Model_.extend({});
|
||||
|
||||
return {
|
||||
createLinkCollection: createLinkCollection
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
77
web/gui/src/main/webapp/app/view/topo2/topo2Model.js
Normal file
77
web/gui/src/main/webapp/app/view/topo2/topo2Model.js
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
ONOS GUI -- Topology Force Module.
|
||||
Visualization of the topology in an SVG layer, using a D3 Force Layout.
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function Model(attributes) {
|
||||
|
||||
var attrs = attributes || {};
|
||||
this.attributes = {};
|
||||
|
||||
attrs = angular.extend({}, attrs);
|
||||
this.set(attrs);
|
||||
}
|
||||
|
||||
Model.prototype = {
|
||||
|
||||
get: function (attr) {
|
||||
return this.attributes[attr];
|
||||
},
|
||||
|
||||
set: function(data) {
|
||||
angular.extend(this.attributes, data);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Model.extend = function (protoProps, staticProps) {
|
||||
|
||||
var parent = this;
|
||||
var child;
|
||||
|
||||
child = function () {
|
||||
return parent.apply(this, arguments);
|
||||
};
|
||||
|
||||
angular.extend(child, parent, staticProps);
|
||||
|
||||
// Set the prototype chain to inherit from `parent`, without calling
|
||||
// `parent`'s constructor function and add the prototype properties.
|
||||
child.prototype = angular.extend({}, parent.prototype, protoProps);
|
||||
child.prototype.constructor = child;
|
||||
|
||||
// Set a convenience property in case the parent's prototype is needed
|
||||
// later.
|
||||
child.__super__ = parent.prototype;
|
||||
|
||||
return child;
|
||||
};
|
||||
|
||||
angular.module('ovTopo2')
|
||||
.factory('Topo2Model',
|
||||
[
|
||||
function () {
|
||||
return Model;
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
72
web/gui/src/main/webapp/app/view/topo2/topo2Region.js
Normal file
72
web/gui/src/main/webapp/app/view/topo2/topo2Region.js
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
ONOS GUI -- Topology Region Module.
|
||||
Module that holds the current region in memory
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var $log,
|
||||
wss,
|
||||
t2sr,
|
||||
t2ds,
|
||||
t2hs,
|
||||
t2ls;
|
||||
|
||||
var regions;
|
||||
|
||||
function init() {
|
||||
regions = {};
|
||||
}
|
||||
|
||||
function addRegion(data) {
|
||||
|
||||
var region = {
|
||||
subregions: t2sr.createSubRegionCollection(data.subregions),
|
||||
devices: t2ds.createDeviceCollection(data.devices, data),
|
||||
hosts: t2hs.createHostCollection(data.hosts),
|
||||
links: t2ls.createLinkCollection(data.links),
|
||||
};
|
||||
|
||||
$log.debug('Region: ', region);
|
||||
}
|
||||
|
||||
angular.module('ovTopo2')
|
||||
.factory('Topo2RegionService',
|
||||
['$log', 'WebSocketService', 'Topo2SubRegionService', 'Topo2DeviceService',
|
||||
'Topo2HostService', 'Topo2LinkService',
|
||||
|
||||
function (_$log_, _wss_, _t2sr_, _t2ds_, _t2hs_, _t2ls_) {
|
||||
|
||||
$log = _$log_;
|
||||
wss = _wss_;
|
||||
t2sr = _t2sr_;
|
||||
t2ds = _t2ds_;
|
||||
t2hs = _t2hs_;
|
||||
t2ls = _t2ls_;
|
||||
|
||||
return {
|
||||
init: init,
|
||||
|
||||
addRegion: addRegion,
|
||||
getSubRegions: t2sr.getSubRegions
|
||||
};
|
||||
}]);
|
||||
|
||||
})();
|
51
web/gui/src/main/webapp/app/view/topo2/topo2SubRegion.js
Normal file
51
web/gui/src/main/webapp/app/view/topo2/topo2SubRegion.js
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
ONOS GUI -- Topology SubRegion Module.
|
||||
Module that holds the sub-regions for a region
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var Collection, Model;
|
||||
|
||||
function createSubRegionCollection(data, region) {
|
||||
|
||||
var SubRegionCollection = Collection.extend({
|
||||
model: Model
|
||||
});
|
||||
|
||||
return new SubRegionCollection(data);
|
||||
}
|
||||
|
||||
angular.module('ovTopo2')
|
||||
.factory('Topo2SubRegionService',
|
||||
['Topo2Collection', 'Topo2Model',
|
||||
|
||||
function (_Collection_, _Model_) {
|
||||
|
||||
Collection = _Collection_;
|
||||
Model = _Model_.extend({});
|
||||
|
||||
return {
|
||||
createSubRegionCollection: createSubRegionCollection
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
})();
|
@ -127,8 +127,16 @@
|
||||
|
||||
<!-- Under development for Region support. -->
|
||||
<script src="app/view/topo2/topo2.js"></script>
|
||||
<script src="app/view/topo2/topo2Collection.js"></script>
|
||||
<script src="app/view/topo2/topo2Device.js"></script>
|
||||
<script src="app/view/topo2/topo2Model.js"></script>
|
||||
<script src="app/view/topo2/topo2Event.js"></script>
|
||||
<script src="app/view/topo2/topo2Force.js"></script>
|
||||
<script src="app/view/topo2/topo2Host.js"></script>
|
||||
<script src="app/view/topo2/topo2Instance.js"></script>
|
||||
<script src="app/view/topo2/topo2Link.js"></script>
|
||||
<script src="app/view/topo2/topo2Region.js"></script>
|
||||
<script src="app/view/topo2/topo2SubRegion.js"></script>
|
||||
<link rel="stylesheet" href="app/view/topo2/topo2.css">
|
||||
<link rel="stylesheet" href="app/view/topo2/topo2-theme.css">
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user