Topo2: Adding peer region node to the topology
Change-Id: I846d2f1ca27faa4602c772aba006f5be55da6106
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2-theme.css b/web/gui/src/main/webapp/app/view/topo2/topo2-theme.css
index 7ce65ad..e3d0c90 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2-theme.css
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2-theme.css
@@ -187,6 +187,10 @@
fill: #454545;
}
+#ov-topo2 svg .node.peer-region rect {
+ fill: #ffffff;
+}
+
#ov-topo2 svg .node.selected .node-container {
stroke-width: 2.0;
stroke: #009fdb;
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Background.js b/web/gui/src/main/webapp/app/view/topo2/topo2Background.js
index 611273b..c90b06d 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Background.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Background.js
@@ -28,8 +28,8 @@
angular.module('ovTopo2')
.factory('Topo2BackgroundService', [
'$log', 'Topo2ViewController', 'Topo2SpriteLayerService', 'Topo2MapService',
- 'Topo2MapConfigService', 'Topo2RegionService',
- function (_$log_, ViewController, t2sls, t2ms, t2mcs, t2rs) {
+ 'Topo2MapConfigService',
+ function (_$log_, ViewController, t2sls, t2ms, t2mcs) {
$log = _$log_;
@@ -45,10 +45,14 @@
t2ms.init();
},
addLayout: function (data) {
- this.background = data;
- t2rs.bgRendered = false;
- if (data.bgType === 'geo') {
+ var _this = this;
+
+ this.background = data;
+ this.bgType = data.bgType;
+ _this.region.loaded('bgRendered', false);
+
+ if (this.bgType === 'geo') {
// Hide Sprite Layer and show Map
t2sls.hide();
@@ -62,20 +66,24 @@
t2mcs.projection(proj);
// $log.debug('** Zoom restored:', z);
$log.debug('** We installed the projection:', proj);
- t2rs.backgroundRendered();
+ _this.region.loaded('bgRendered', true);
});
}
- if (data.bgType === 'grid') {
+ if (this.bgType === 'grid') {
// Hide Sprite Layer and show Map
t2ms.hide();
t2sls.show();
- t2sls.loadLayout(data.bgId).then(function () {
- t2rs.backgroundRendered();
+ t2sls.loadLayout(data.bgId).then(function (spriteLayout) {
+ _this.background.layout = spriteLayout;
+ _this.region.loaded('bgRendered', true);
});
}
+ },
+ getBackgroundType: function () {
+ return this.bgType;
}
});
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Collection.js b/web/gui/src/main/webapp/app/view/topo2/topo2Collection.js
index b49de81..5472f65 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Collection.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Collection.js
@@ -44,8 +44,7 @@
model: Model,
addModel: function (data) {
var CollectionModel = this.model;
- var model = new CollectionModel(data);
- model.collection = this;
+ var model = new CollectionModel(data, this);
this.models.push(model);
this._byId[data.id] = model;
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2D3.js b/web/gui/src/main/webapp/app/view/topo2/topo2D3.js
index 932101c..e036020 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2D3.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2D3.js
@@ -30,14 +30,6 @@
node.onExit(this, node);
}
- function hostEnter(node) {
- node.onEnter(this, node);
- }
-
- function linkEntering(link) {
- link.onEnter(this);
- }
-
angular.module('ovTopo2')
.factory('Topo2D3Service', [
@@ -45,8 +37,6 @@
return {
nodeEnter: nodeEnter,
nodeExit: nodeExit,
- hostEnter: hostEnter,
- linkEntering: linkEntering
};
}
]
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Force.js b/web/gui/src/main/webapp/app/view/topo2/topo2Force.js
index 78f37a3..e1e392b 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Force.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Force.js
@@ -43,6 +43,7 @@
t2bgs.init();
+ t2bgs.region = t2rs;
t2ls.init(svg, uplink, dim, zoomer, opts);
t2bcs.addLayout(t2ls);
t2rs.layout = t2ls;
@@ -83,11 +84,12 @@
function currentRegion(data) {
$log.debug('>> topo2CurrentRegion event:', data);
- t2rs.addRegion(data);
+ t2rs.loaded('regionData', data);
}
function topo2PeerRegions(data) {
$log.debug('>> topo2PeerRegions event:', data);
+ t2rs.loaded('peers', data.peers);
}
function modelEvent(data) {
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js b/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js
index 36a5ced..4e21040 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Layout.js
@@ -136,8 +136,7 @@
return this.settings[settingName][nodeType] || this.settings[settingName]._def_;
},
createForceLayout: function () {
- var _this = this,
- regionLinks = t2rs.regionLinks(),
+ var regionLinks = t2rs.regionLinks(),
regionNodes = t2rs.regionNodes();
this.force = d3.layout.force()
@@ -150,14 +149,6 @@
.nodes(regionNodes)
.links(regionLinks)
.on("tick", this.tick.bind(this))
- .on("start", function () {
-
- // TODO: Find a better way to do this
- // TODO: BROKEN - Click and dragging and element triggers this event
-// setTimeout(function () {
-// _this.centerLayout();
-// }, 500);
- })
.start();
this.link = this.elements.linkG.selectAll('.link')
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Link.js b/web/gui/src/main/webapp/app/view/topo2/topo2Link.js
index e644c7c..7c674c3 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Link.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Link.js
@@ -117,6 +117,11 @@
function createLinkCollection(data, _region) {
var LinkModel = Model.extend({
+ initialize: function () {
+ this.super = this.constructor.__super__;
+ this.super.initialize.apply(this, arguments);
+ this.createLink();
+ },
region: _region,
createLink: createLink,
linkEndPoints: linkEndPoints,
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Model.js b/web/gui/src/main/webapp/app/view/topo2/topo2Model.js
index c8430fb..31ec0f6 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Model.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Model.js
@@ -22,13 +22,14 @@
(function () {
'use strict';
- function Model(attributes) {
+ function Model(attributes, collection) {
var attrs = attributes || {};
this.attributes = {};
attrs = angular.extend({}, attrs);
this.set(attrs, { silent: true });
+ this.collection = collection;
this.initialize.apply(this, arguments);
}
@@ -82,11 +83,11 @@
val = attribute;
- if (!angular.equals(current[index], val)) {
+ if (!_.isEqual(current[index], val)) {
changes.push(index);
}
- if (angular.equals(previous[index], val)) {
+ if (!_.isEqual(previous[index], val)) {
delete changed[index];
} else {
changed[index] = val;
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2NodeModel.js b/web/gui/src/main/webapp/app/view/topo2/topo2NodeModel.js
index 94ab15f..9d46494 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2NodeModel.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2NodeModel.js
@@ -93,6 +93,17 @@
return selected;
},
+ index: function () {
+
+ var models = this.collection.models,
+ id = this.get('id');
+
+ var index = _.find(models, function (model, i) {
+ return model.get('id') === id;
+ });
+
+ return index || models.length;
+ },
deselect: function () {
this.set('selected', false);
},
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2NodePosition.js b/web/gui/src/main/webapp/app/view/topo2/topo2NodePosition.js
index 2c78a00..af708fb 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2NodePosition.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2NodePosition.js
@@ -23,18 +23,39 @@
'use strict';
// Injected vars
- var rs, t2mcs, t2sls;
+ var rs, t2mcs, t2sls, t2bgs;
// Internal state;
var nearDist = 15;
function positionNode(node, forUpdate) {
+
var meta = node.get('metaUi'),
x = meta && meta.x,
y = meta && meta.y,
dim = [800, 600],
xy;
+ if (node.nodeType === 'peer-region') {
+
+ var coord = [0, 0],
+ loc = {};
+
+ if (t2bgs.getBackgroundType() === 'geo') {
+ // TODO: Set coords for geo (lat/long)
+ } else {
+ loc.gridX = -20;
+ loc.gridY = 10 * node.index();
+ coord = coordFromXY(loc);
+ }
+
+ node.px = node.x = coord[0];
+ node.py = node.y = coord[1];
+
+ node.fix(true);
+ return;
+ }
+
// If the device contains explicit LONG/LAT data, use that to position
if (setLongLat(node)) {
// Indicate we want to update cached meta data...
@@ -146,12 +167,13 @@
angular.module('ovTopo2')
.factory('Topo2NodePositionService',
- ['RandomService', 'Topo2MapConfigService', 'Topo2SpriteLayerService',
- function (_rs_, _t2mcs_, _t2sls_) {
+ ['RandomService', 'Topo2MapConfigService', 'Topo2SpriteLayerService', 'Topo2BackgroundService',
+ function (_rs_, _t2mcs_, _t2sls_, _t2bgs_) {
rs = _rs_;
t2mcs = _t2mcs_;
t2sls = _t2sls_;
+ t2bgs = _t2bgs_;
return {
positionNode: positionNode,
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2PeerRegion.js b/web/gui/src/main/webapp/app/view/topo2/topo2PeerRegion.js
new file mode 100644
index 0000000..2ae8e64
--- /dev/null
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2PeerRegion.js
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2017-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 PeerRegion Module.
+ Module that creates a peer region node for the topology
+ */
+
+(function () {
+ 'use strict';
+
+ var Collection, Model;
+
+ var remappedDeviceTypes = {
+ virtual: 'cord'
+ };
+
+ function createCollection(data, region) {
+
+ var PeerRegionCollection = Collection.extend({
+ model: Model,
+ region: region
+ });
+
+ return new PeerRegionCollection(data);
+ }
+
+ angular.module('ovTopo2')
+ .factory('Topo2PeerRegionService', [
+ 'WebSocketService', 'Topo2Collection', 'Topo2NodeModel',
+ 'Topo2SubRegionPanelService',
+
+ function (wss, _c_, NodeModel, t2srp) {
+
+ Collection = _c_;
+
+ Model = NodeModel.extend({
+ initialize: function () {
+ this.super = this.constructor.__super__;
+ this.super.initialize.apply(this, arguments);
+ },
+ events: {
+ 'dblclick': 'navigateToRegion',
+ 'click': 'onClick'
+ },
+ onChange: function () {
+ // Update class names when the model changes
+ if (this.el) {
+ this.el.attr('class', this.svgClassName());
+ }
+ },
+ nodeType: 'peer-region',
+ icon: function () {
+ var type = this.get('type');
+ return remappedDeviceTypes[type] || type || 'm_cloud';
+ },
+ onClick: function () {
+ var selected = this.select(d3.event);
+
+ if (selected.length > 0) {
+ t2srp.displayPanel(this);
+ } else {
+ t2srp.hide();
+ }
+ },
+ navigateToRegion: function () {
+
+ if (d3.event.defaultPrevented) return;
+
+ wss.sendEvent('topo2navRegion', {
+ dir: 'down',
+ rid: this.get('id')
+ });
+
+ var layout = this.collection.region.layout;
+ layout.createForceElements();
+ layout.transitionDownRegion();
+
+ t2srp.hide();
+ }
+ });
+
+ return {
+ createCollection: createCollection
+ };
+ }
+ ]);
+
+})();
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Region.js b/web/gui/src/main/webapp/app/view/topo2/topo2Region.js
index 5895871..67b2a7c 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Region.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Region.js
@@ -36,9 +36,9 @@
'$log', 'Topo2Model', 'Topo2SubRegionService', 'Topo2DeviceService',
'Topo2HostService', 'Topo2LinkService', 'Topo2ZoomService', 'Topo2DetailsPanelService',
'Topo2BreadcrumbService', 'Topo2ViewController', 'Topo2SpriteLayerService', 'Topo2MapService',
- 'Topo2MapConfigService',
+ 'Topo2MapConfigService', 'Topo2PeerRegionService',
function ($log, _Model_, t2sr, t2ds, t2hs, t2ls, t2zs, t2dps, t2bcs, ViewController,
- t2sls, t2ms, t2mcs) {
+ t2sls, t2ms, t2mcs, t2pr) {
Model = _Model_;
@@ -46,7 +46,10 @@
initialize: function () {
instance = this;
this.model = null;
+
this.bgRendered = false;
+ this.regionData = null;
+ this.peers = null;
var RegionModel = Model.extend({
findNodeById: this.findNodeById,
@@ -55,35 +58,26 @@
this.model = new RegionModel();
},
- backgroundRendered: function () {
- this.bgRendered = true;
-
- if (this.regionData) {
- this.startRegion();
- }
- },
- addRegion: function (data) {
- this.clear();
- this.regionData = data;
-
- if (this.bgRendered) {
+ loaded: function (key, value) {
+ this[key] = value;
+ if (this.bgRendered && this.regionData && this.peers) {
this.startRegion();
}
},
startRegion: function () {
+ var _this = this;
+
this.model.set({
id: this.regionData.id,
- layerOrder: this.regionData.layerOrder,
- subregions: t2sr.createSubRegionCollection(this.regionData.subregions, this),
- devices: t2ds.createDeviceCollection(this.regionData.devices, this),
- hosts: t2hs.createHostCollection(this.regionData.hosts, this),
- links: t2ls.createLinkCollection(this.regionData.links, this)
+ layerOrder: this.regionData.layerOrder
});
- angular.forEach(this.model.get('links').models, function (link) {
- link.createLink();
- });
+ this.model.set({ subregions: t2sr.createSubRegionCollection(this.regionData.subregions, this) });
+ this.model.set({ devices: t2ds.createDeviceCollection(this.regionData.devices, this) });
+ this.model.set({ hosts: t2hs.createHostCollection(this.regionData.hosts, this) });
+ this.model.set({ peerRegions: t2pr.createCollection(this.peers, this) });
+ this.model.set({ links: t2ls.createLinkCollection(this.regionData.links, this) });
// Hide Breadcrumbs if there are no subregions configured in the root region
if (this.isRootRegion() && !this.model.get('subregions').models.length) {
@@ -98,15 +92,6 @@
if (!this.model)
return;
-
- this.model.set({
- id: null,
- layerOrder: null,
- subregions: t2sr.createSubRegionCollection([], this),
- devices: t2ds.createDeviceCollection([], this),
- hosts: t2hs.createHostCollection([], this),
- links: t2ls.createLinkCollection([], this)
- });
},
isRootRegion: function () {
return this.model.get('id') === ROOT;
@@ -126,7 +111,8 @@
return [].concat(
this.model.get('devices').models,
this.model.get('hosts').models,
- this.model.get('subregions').models
+ this.model.get('subregions').models,
+ this.model.get('peerRegions').models
);
}
return [];
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js b/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js
index 6de99fe..b3452c2 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2SpriteLayer.js
@@ -46,6 +46,7 @@
this.container = this.appendElement('#topo2-background', 'g');
},
loadLayout: function (id) {
+ var _this = this;
this.container.selectAll("*").remove();
this.layout = ss.layout(id);
@@ -60,7 +61,7 @@
// Returns a promise for consistency with Topo2MapService
return new Promise(function(resolve) {
- resolve();
+ resolve(_this);
});
},
createSpriteDefs: function () {