blob: 4e89822edb8c436002cefdf000ae78abd6290ed9 [file] [log] [blame]
Simon Hunt4b668592015-01-29 17:33:53 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Simon Hunt4b668592015-01-29 17:33:53 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 ONOS GUI -- Topology Instances Module.
19 Defines modeling of ONOS instances.
20 */
21
22(function () {
23 'use strict';
24
25 // injected refs
Simon Huntee7a3ce2015-04-09 13:28:37 -070026 var $log, ps, sus, gs, ts, fs, flash;
Simon Hunt4b668592015-01-29 17:33:53 -080027
Simon Hunta142dd22015-02-12 22:07:51 -080028 // api from topo
29 var api;
30 /*
31 showMastership( id )
32 */
33
Simon Hunt4b668592015-01-29 17:33:53 -080034 // configuration
Simon Hunta9761342016-06-10 18:02:53 -070035 var showLogicErrors = true,
Simon Hunt4b668592015-01-29 17:33:53 -080036 idIns = 'topo-p-instance',
37 instOpts = {
38 edge: 'left',
Steven Burrows1c2a9682017-07-14 16:52:46 +010039 width: 20,
Simon Hunt4b668592015-01-29 17:33:53 -080040 };
41
42 // internal state
43 var onosInstances,
44 onosOrder,
45 oiShowMaster,
Simon Huntf51bf462016-06-29 16:22:57 -070046 oiBox;
Simon Hunt4b668592015-01-29 17:33:53 -080047
Simon Hunte2d9dc72017-08-10 15:21:04 -070048 // function to be replaced by the localization bundle function
49 var topoLion = function (x) {
50 return '#tinst#' + x + '#';
51 };
52
Simon Hunt4b668592015-01-29 17:33:53 -080053
Simon Hunt4b668592015-01-29 17:33:53 -080054 function addInstance(data) {
55 var id = data.id;
56
57 if (onosInstances[id]) {
58 updateInstance(data);
59 return;
60 }
61 onosInstances[id] = data;
62 onosOrder.push(data);
63 updateInstances();
64 }
65
66 function updateInstance(data) {
67 var id = data.id,
68 d = onosInstances[id];
69 if (d) {
70 angular.extend(d, data);
71 updateInstances();
72 } else {
73 logicError('updateInstance: lookup fail: ID = "' + id + '"');
74 }
75 }
76
Simon Hunt48e61672015-01-30 14:48:25 -080077 function removeInstance(data) {
78 var id = data.id,
79 d = onosInstances[id];
80 if (d) {
81 var idx = fs.find(id, onosOrder);
82 if (idx >= 0) {
83 onosOrder.splice(idx, 1);
84 }
85 delete onosInstances[id];
86 updateInstances();
87 } else {
88 logicError('removeInstance lookup fail. ID = "' + id + '"');
89 }
90 }
91
92 // ==========================
93
Simon Hunt4b668592015-01-29 17:33:53 -080094 function clickInst(d) {
95 var el = d3.select(this),
96 aff = el.classed('affinity');
97 if (!aff) {
98 setAffinity(el, d);
99 } else {
100 cancelAffinity();
101 }
102 }
103
104 function setAffinity(el, d) {
105 d3.selectAll('.onosInst')
106 .classed('mastership', true)
107 .classed('affinity', false);
108 el.classed('affinity', true);
109
Simon Hunta142dd22015-02-12 22:07:51 -0800110 // suppress all elements except nodes whose master is this instance
111 api.showMastership(d.id);
Simon Hunt4b668592015-01-29 17:33:53 -0800112 oiShowMaster = true;
113 }
114
115 function cancelAffinity() {
116 d3.selectAll('.onosInst')
117 .classed('mastership affinity', false);
118
Simon Hunta142dd22015-02-12 22:07:51 -0800119 api.showMastership(null);
Simon Hunt4b668592015-01-29 17:33:53 -0800120 oiShowMaster = false;
121 }
122
Simon Hunt4b668592015-01-29 17:33:53 -0800123 function attachUiBadge(svg) {
Simon Hunta9761342016-06-10 18:02:53 -0700124 gs.addGlyph(svg, 'uiAttached', 24, true, [14, 54])
Simon Hunt4b668592015-01-29 17:33:53 -0800125 .classed('badgeIcon uiBadge', true);
126 }
127
Thomas Vachuskafba7f3d2016-03-23 15:46:25 -0700128 function attachReadyBadge(svg) {
Simon Hunta9761342016-06-10 18:02:53 -0700129 gs.addGlyph(svg, 'checkMark', 16, true, [18, 40])
Thomas Vachuskafba7f3d2016-03-23 15:46:25 -0700130 .classed('badgeIcon readyBadge', true);
131 }
132
Simon Hunt4b668592015-01-29 17:33:53 -0800133 function instColor(id, online) {
Simon Hunt48e61672015-01-30 14:48:25 -0800134 return sus.cat7().getColor(id, !online, ts.theme());
Simon Hunt4b668592015-01-29 17:33:53 -0800135 }
136
137 // ==============================
138
139 function updateInstances() {
Simon Hunta9761342016-06-10 18:02:53 -0700140 var rox = 5,
141 roy = 5,
142 rw = 160,
143 rhh = 30,
144 rbh = 45,
145 tx = 48,
146 instSvg = {
147 width: 170,
148 height: 85,
Steven Burrows1c2a9682017-07-14 16:52:46 +0100149 viewBox: '0 0 170 85',
Simon Hunta9761342016-06-10 18:02:53 -0700150 },
151 headRect = {
152 x: rox,
153 y: roy,
154 width: rw,
Steven Burrows1c2a9682017-07-14 16:52:46 +0100155 height: rhh,
Simon Hunta9761342016-06-10 18:02:53 -0700156 },
157 bodyRect = {
158 x: rox,
159 y: roy + rhh,
160 width: rw,
Steven Burrows1c2a9682017-07-14 16:52:46 +0100161 height: rbh,
Simon Hunta9761342016-06-10 18:02:53 -0700162 },
163 titleAttr = {
164 class: 'instTitle',
165 x: tx,
Steven Burrows1c2a9682017-07-14 16:52:46 +0100166 y: 27,
Simon Hunta9761342016-06-10 18:02:53 -0700167 };
168
Simon Hunt4b668592015-01-29 17:33:53 -0800169 var onoses = oiBox.el().selectAll('.onosInst')
Simon Hunta9761342016-06-10 18:02:53 -0700170 .data(onosOrder, function (d) { return d.id; });
Simon Hunt4b668592015-01-29 17:33:53 -0800171
172 function nSw(n) {
Simon Hunte2d9dc72017-08-10 15:21:04 -0700173 return topoLion('devices') + ': ' + n;
Simon Hunt4b668592015-01-29 17:33:53 -0800174 }
175
176 // operate on existing onos instances if necessary
177 onoses.each(function (d) {
178 var el = d3.select(this),
179 svg = el.select('svg');
Simon Hunt4b668592015-01-29 17:33:53 -0800180
181 // update online state
182 el.classed('online', d.online);
Simon Hunta9761342016-06-10 18:02:53 -0700183 el.classed('ready', d.ready);
Simon Hunt4b668592015-01-29 17:33:53 -0800184
185 // update ui-attached state
186 svg.select('use.uiBadge').remove();
187 if (d.uiAttached) {
188 attachUiBadge(svg);
189 }
190
191 function updAttr(id, value) {
192 svg.select('text.instLabel.'+id).text(value);
193 }
194
195 updAttr('ip', d.ip);
196 updAttr('ns', nSw(d.switches));
197 });
198
199
200 // operate on new onos instances
201 var entering = onoses.enter()
202 .append('div')
Simon Hunta9761342016-06-10 18:02:53 -0700203 .classed('onosInst', true)
Simon Hunt4b668592015-01-29 17:33:53 -0800204 .classed('online', function (d) { return d.online; })
Simon Hunta9761342016-06-10 18:02:53 -0700205 .classed('ready', function (d) { return d.ready; })
Simon Hunt4b668592015-01-29 17:33:53 -0800206 .on('click', clickInst);
207
208 entering.each(function (d) {
209 var el = d3.select(this),
Simon Hunta9761342016-06-10 18:02:53 -0700210 svg = el.append('svg').attr(instSvg);
Simon Hunt4b668592015-01-29 17:33:53 -0800211
Simon Hunta9761342016-06-10 18:02:53 -0700212 svg.append('rect').attr(headRect);
213 svg.append('rect').attr(bodyRect);
Simon Hunt4b668592015-01-29 17:33:53 -0800214
Simon Hunta9761342016-06-10 18:02:53 -0700215 gs.addGlyph(svg, 'bird', 20, false, [15, 10])
216 .classed('badgeIcon bird', true);
Simon Hunt4b668592015-01-29 17:33:53 -0800217
Simon Hunta9761342016-06-10 18:02:53 -0700218 attachReadyBadge(svg);
Simon Hunt4b668592015-01-29 17:33:53 -0800219
220 if (d.uiAttached) {
221 attachUiBadge(svg);
222 }
223
Simon Hunt4b668592015-01-29 17:33:53 -0800224 svg.append('text')
Simon Hunta9761342016-06-10 18:02:53 -0700225 .attr(titleAttr)
Simon Hunt4b668592015-01-29 17:33:53 -0800226 .text(d.id);
227
Simon Hunta9761342016-06-10 18:02:53 -0700228 var ty = 55;
Simon Hunt4b668592015-01-29 17:33:53 -0800229 function addAttr(id, label) {
230 svg.append('text').attr({
231 class: 'instLabel ' + id,
Simon Hunta9761342016-06-10 18:02:53 -0700232 x: tx,
Steven Burrows1c2a9682017-07-14 16:52:46 +0100233 y: ty,
Simon Hunt4b668592015-01-29 17:33:53 -0800234 }).text(label);
Simon Hunta9761342016-06-10 18:02:53 -0700235 ty += 18;
Simon Hunt4b668592015-01-29 17:33:53 -0800236 }
237
238 addAttr('ip', d.ip);
239 addAttr('ns', nSw(d.switches));
240 });
241
242 // operate on existing + new onoses here
243 // set the affinity colors...
244 onoses.each(function (d) {
245 var el = d3.select(this),
246 rect = el.select('svg').select('rect'),
247 col = instColor(d.id, d.online);
248 rect.style('fill', col);
249 });
250
251 // adjust the panel size appropriately...
Simon Hunta9761342016-06-10 18:02:53 -0700252 oiBox.width(instSvg.width * onosOrder.length);
253 oiBox.height(instSvg.height);
Simon Hunt4b668592015-01-29 17:33:53 -0800254
255 // remove any outgoing instances
256 onoses.exit().remove();
257 }
258
259
260 // ==========================
261
262 function logicError(msg) {
263 if (showLogicErrors) {
264 $log.warn('TopoInstService: ' + msg);
265 }
266 }
267
Simon Hunta142dd22015-02-12 22:07:51 -0800268 function initInst(_api_) {
269 api = _api_;
Simon Hunt4b668592015-01-29 17:33:53 -0800270 oiBox = ps.createPanel(idIns, instOpts);
271 oiBox.show();
272
273 onosInstances = {};
274 onosOrder = [];
275 oiShowMaster = false;
Simon Hunt245a88e2015-02-02 13:26:04 -0800276
277 // we want to update the instances, each time the theme changes
Simon Huntf51bf462016-06-29 16:22:57 -0700278 ts.addListener(updateInstances);
Simon Hunt4b668592015-01-29 17:33:53 -0800279 }
280
281 function destroyInst() {
Simon Huntf51bf462016-06-29 16:22:57 -0700282 ts.removeListener(updateInstances);
Simon Hunt245a88e2015-02-02 13:26:04 -0800283
Simon Hunt4b668592015-01-29 17:33:53 -0800284 ps.destroyPanel(idIns);
285 oiBox = null;
Simon Hunt3ab20282015-02-26 20:32:19 -0800286
287 onosInstances = {};
288 onosOrder = [];
289 oiShowMaster = false;
Simon Hunt4b668592015-01-29 17:33:53 -0800290 }
291
Simon Huntee7a3ce2015-04-09 13:28:37 -0700292 function showInsts() {
293 oiBox.show();
294 }
295
296 function hideInsts() {
297 oiBox.hide();
298 }
299
300 function toggleInsts(x) {
301 var kev = (x === 'keyev'),
302 on,
303 verb;
304
305 if (kev) {
306 on = oiBox.toggle();
307 } else {
308 on = !!x;
309 if (on) {
310 showInsts();
311 } else {
312 hideInsts();
313 }
314 }
Simon Hunte2d9dc72017-08-10 15:21:04 -0700315 verb = on ? topoLion('show') : topoLion('hide');
316 flash.flash(verb + ' ' + topoLion('fl_panel_instances'));
Simon Huntee7a3ce2015-04-09 13:28:37 -0700317 return on;
318 }
319
Simon Hunte2d9dc72017-08-10 15:21:04 -0700320 // invoked after the localization bundle has been received from the server
321 function setLionBundle(bundle) {
322 topoLion = bundle;
323 }
324
Simon Hunt4b668592015-01-29 17:33:53 -0800325 // ==========================
326
327 angular.module('ovTopo')
328 .factory('TopoInstService',
329 ['$log', 'PanelService', 'SvgUtilService', 'GlyphService',
Simon Huntee7a3ce2015-04-09 13:28:37 -0700330 'ThemeService', 'FnService', 'FlashService',
Simon Hunt4b668592015-01-29 17:33:53 -0800331
Simon Huntee7a3ce2015-04-09 13:28:37 -0700332 function (_$log_, _ps_, _sus_, _gs_, _ts_, _fs_, _flash_) {
Simon Hunt4b668592015-01-29 17:33:53 -0800333 $log = _$log_;
334 ps = _ps_;
335 sus = _sus_;
336 gs = _gs_;
Simon Hunt48e61672015-01-30 14:48:25 -0800337 ts = _ts_;
338 fs = _fs_;
Simon Huntee7a3ce2015-04-09 13:28:37 -0700339 flash = _flash_;
Simon Hunt4b668592015-01-29 17:33:53 -0800340
341 return {
342 initInst: initInst,
343 destroyInst: destroyInst,
Simon Hunt1894d792015-02-04 17:09:20 -0800344
Simon Hunt48e61672015-01-30 14:48:25 -0800345 addInstance: addInstance,
346 updateInstance: updateInstance,
Simon Huntac4c6f72015-02-03 19:50:53 -0800347 removeInstance: removeInstance,
Simon Hunt1894d792015-02-04 17:09:20 -0800348
Simon Hunta142dd22015-02-12 22:07:51 -0800349 cancelAffinity: cancelAffinity,
350
Simon Huntac4c6f72015-02-03 19:50:53 -0800351 isVisible: function () { return oiBox.isVisible(); },
Simon Huntee7a3ce2015-04-09 13:28:37 -0700352 show: showInsts,
353 hide: hideInsts,
354 toggle: toggleInsts,
Steven Burrows1c2a9682017-07-14 16:52:46 +0100355 showMaster: function () { return oiShowMaster; },
Simon Hunte2d9dc72017-08-10 15:21:04 -0700356 setLionBundle: setLionBundle,
Simon Hunt4b668592015-01-29 17:33:53 -0800357 };
358 }]);
359}());