blob: 044e3d6d5eed803cb650c22887b080af750fce52 [file] [log] [blame]
Steven Burrows57e24e92016-08-04 18:38:24 +01001(function () {
2 'use strict';
3
4 // injected refs
Steven Burrowsc515e602017-04-13 11:17:40 -07005 var $log, ps, sus, gs, flash, ts, t2mss;
Steven Burrows57e24e92016-08-04 18:38:24 +01006
7 // api from topo
8 var api;
9
10 // configuration
11 var showLogicErrors = true,
Steven Burrows7a9d04e2016-09-26 17:05:37 -070012 idIns = 'topo2-p-instance',
Steven Burrows57e24e92016-08-04 18:38:24 +010013 instOpts = {
14 edge: 'left',
15 width: 20
16 };
17
18 // internal state
19 var onosInstances,
20 onosOrder,
Steven Burrows57e24e92016-08-04 18:38:24 +010021 oiBox;
22
Steven Burrows57e24e92016-08-04 18:38:24 +010023 function addInstance(data) {
24 var id = data.id;
25
26 if (onosInstances[id]) {
27 updateInstance(data);
28 return;
29 }
30 onosInstances[id] = data;
31 onosOrder.push(data);
32 updateInstances();
33 }
34
35 function updateInstance(data) {
36 var id = data.id,
37 d = onosInstances[id];
38 if (d) {
39 angular.extend(d, data);
40 updateInstances();
41 } else {
42 logicError('updateInstance: lookup fail: ID = "' + id + '"');
43 }
44 }
45
Steven Burrows57e24e92016-08-04 18:38:24 +010046 // ==========================
47
48 function clickInst(d) {
49 var el = d3.select(this),
50 aff = el.classed('affinity');
Steven Burrowsdfa52b02016-09-02 13:50:43 +010051 if (aff) {
Steven Burrows57e24e92016-08-04 18:38:24 +010052 cancelAffinity();
Steven Burrowsdfa52b02016-09-02 13:50:43 +010053 } else {
54 setAffinity(el, d);
Steven Burrows57e24e92016-08-04 18:38:24 +010055 }
56 }
57
58 function setAffinity(el, d) {
59 d3.selectAll('.onosInst')
60 .classed('mastership', true)
61 .classed('affinity', false);
62 el.classed('affinity', true);
63
Steven Burrowsc515e602017-04-13 11:17:40 -070064 t2mss.setMastership(d.id);
Steven Burrows57e24e92016-08-04 18:38:24 +010065 }
66
67 function cancelAffinity() {
68 d3.selectAll('.onosInst')
69 .classed('mastership affinity', false);
70
Steven Burrowsc515e602017-04-13 11:17:40 -070071 t2mss.setMastership(null);
Steven Burrows57e24e92016-08-04 18:38:24 +010072 }
73
74 function attachUiBadge(svg) {
75 gs.addGlyph(svg, 'uiAttached', 24, true, [14, 54])
76 .classed('badgeIcon uiBadge', true);
77 }
78
79 function attachReadyBadge(svg) {
80 gs.addGlyph(svg, 'checkMark', 16, true, [18, 40])
81 .classed('badgeIcon readyBadge', true);
82 }
83
84 function instColor(id, online) {
85 return sus.cat7().getColor(id, !online, ts.theme());
86 }
87
88 // ==============================
89
90 function updateInstances() {
91 var rox = 5,
92 roy = 5,
93 rw = 160,
94 rhh = 30,
95 rbh = 45,
96 tx = 48,
97 instSvg = {
98 width: 170,
99 height: 85,
100 viewBox: '0 0 170 85'
101 },
102 headRect = {
103 x: rox,
104 y: roy,
105 width: rw,
106 height: rhh
107 },
108 bodyRect = {
109 x: rox,
110 y: roy + rhh,
111 width: rw,
112 height: rbh
113 },
114 titleAttr = {
115 class: 'instTitle',
116 x: tx,
117 y: 27
118 };
119
120 var onoses = oiBox.el().selectAll('.onosInst')
121 .data(onosOrder, function (d) { return d.id; });
122
123 function nSw(n) {
124 return 'Devices: ' + n;
125 }
126
127 // operate on existing onos instances if necessary
128 onoses.each(function (d) {
129 var el = d3.select(this),
130 svg = el.select('svg');
131
132 // update online state
133 el.classed('online', d.online);
134 el.classed('ready', d.ready);
135
136 // update ui-attached state
137 svg.select('use.uiBadge').remove();
138 if (d.uiAttached) {
139 attachUiBadge(svg);
140 }
141
142 function updAttr(id, value) {
143 svg.select('text.instLabel.' + id).text(value);
144 }
145
146 updAttr('ip', d.ip);
147 updAttr('ns', nSw(d.switches));
148 });
149
Steven Burrows57e24e92016-08-04 18:38:24 +0100150 // operate on new onos instances
151 var entering = onoses.enter()
152 .append('div')
153 .classed('onosInst', true)
154 .classed('online', function (d) { return d.online; })
155 .classed('ready', function (d) { return d.ready; })
156 .on('click', clickInst);
157
158 entering.each(function (d) {
159 var el = d3.select(this),
160 svg = el.append('svg').attr(instSvg);
161
162 svg.append('rect').attr(headRect);
163 svg.append('rect').attr(bodyRect);
164
165 gs.addGlyph(svg, 'bird', 20, false, [15, 10])
166 .classed('badgeIcon bird', true);
167
168 attachReadyBadge(svg);
169
170 if (d.uiAttached) {
171 attachUiBadge(svg);
172 }
173
174 svg.append('text')
175 .attr(titleAttr)
176 .text(d.id);
177
178 var ty = 55;
179 function addAttr(id, label) {
180 svg.append('text').attr({
181 class: 'instLabel ' + id,
182 x: tx,
183 y: ty
184 }).text(label);
185 ty += 18;
186 }
187
188 addAttr('ip', d.ip);
189 addAttr('ns', nSw(d.switches));
190 });
191
192 // operate on existing + new onoses here
193 // set the affinity colors...
194 onoses.each(function (d) {
195
196 var el = d3.select(this),
197 rect = el.select('svg').select('rect'),
198 col = instColor(d.id, d.online);
199
200 rect.style('fill', col);
201 });
202
203 // adjust the panel size appropriately...
204 oiBox.width(instSvg.width * onosOrder.length);
205 oiBox.height(instSvg.height);
206
207 // remove any outgoing instances
208 onoses.exit().remove();
209 }
210
Steven Burrows57e24e92016-08-04 18:38:24 +0100211 // ==========================
Steven Burrows57e24e92016-08-04 18:38:24 +0100212 function logicError(msg) {
213 if (showLogicErrors) {
Simon Hunt95f4b422017-03-03 13:49:05 -0800214 $log.warn('Topo2InstService: ' + msg);
Steven Burrows57e24e92016-08-04 18:38:24 +0100215 }
216 }
217
218 function initInst(_api_) {
219 api = _api_;
220 oiBox = ps.createPanel(idIns, instOpts);
221 oiBox.show();
222
223 onosInstances = {};
224 onosOrder = [];
Steven Burrows57e24e92016-08-04 18:38:24 +0100225
226 // we want to update the instances, each time the theme changes
227 ts.addListener(updateInstances);
228 }
229
Steven Burrows57e24e92016-08-04 18:38:24 +0100230 function allInstances(data) {
231 $log.debug('Update all instances', data);
232
233 var members = data.members;
234
235 members.forEach(function (member) {
236 addInstance(member);
237 });
238 }
239
Steven Burrows01ddf602016-09-28 14:21:00 -0700240 function toggle(x) {
241 var kev = (x === 'keyev'),
242 on,
243 verb;
244
245 if (kev) {
246 on = oiBox.toggle();
247 } else {
248 on = Boolean(x);
249 if (on) {
250 oiBox.show();
251 } else {
252 oiBox.hide();
253 }
254 }
255 verb = on ? 'Show' : 'Hide';
256 flash.flash(verb + ' instances panel');
257 return on;
258 }
259
Steven Burrows7a9d04e2016-09-26 17:05:37 -0700260 function destroy() {
261 ts.removeListener(updateInstances);
262
263 ps.destroyPanel(idIns);
264 oiBox = null;
265
266 onosInstances = {};
267 onosOrder = [];
268 }
269
Steven Burrows57e24e92016-08-04 18:38:24 +0100270 angular.module('ovTopo2')
Steven Burrowsaf96a212016-12-28 12:57:02 +0000271 .factory('Topo2InstanceService', [
272 '$log', 'PanelService', 'SvgUtilService', 'GlyphService',
Steven Burrowsc515e602017-04-13 11:17:40 -0700273 'FlashService', 'ThemeService', 'Topo2MastershipService',
Steven Burrows57e24e92016-08-04 18:38:24 +0100274
Steven Burrowsc515e602017-04-13 11:17:40 -0700275 function (_$log_, _ps_, _sus_, _gs_, _flash_, _ts_, _t2mss_) {
Steven Burrowsaf96a212016-12-28 12:57:02 +0000276 $log = _$log_;
277 ps = _ps_;
278 sus = _sus_;
279 gs = _gs_;
280 flash = _flash_;
281 ts = _ts_;
Steven Burrowsc515e602017-04-13 11:17:40 -0700282 t2mss = _t2mss_;
Steven Burrows57e24e92016-08-04 18:38:24 +0100283
Steven Burrowsaf96a212016-12-28 12:57:02 +0000284 return {
285 initInst: initInst,
286 allInstances: allInstances,
287 destroy: destroy,
288 toggle: toggle,
289 isVisible: function () { return oiBox.isVisible(); }
290 };
291 }
292 ]);
Steven Burrows57e24e92016-08-04 18:38:24 +0100293
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100294})();