blob: 11726622578ef77cfd05806181685b895cd10528 [file] [log] [blame]
Steven Burrows57e24e92016-08-04 18:38:24 +01001(function () {
2 'use strict';
3
4 // injected refs
Steven Burrowsdfa52b02016-09-02 13:50:43 +01005 var $log, ps, sus, gs, ts;
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
64 // suppress all elements except nodes whose master is this instance
65 api.showMastership(d.id);
Steven Burrows57e24e92016-08-04 18:38:24 +010066 }
67
68 function cancelAffinity() {
69 d3.selectAll('.onosInst')
70 .classed('mastership affinity', false);
71
72 api.showMastership(null);
Steven Burrows57e24e92016-08-04 18:38:24 +010073 }
74
75 function attachUiBadge(svg) {
76 gs.addGlyph(svg, 'uiAttached', 24, true, [14, 54])
77 .classed('badgeIcon uiBadge', true);
78 }
79
80 function attachReadyBadge(svg) {
81 gs.addGlyph(svg, 'checkMark', 16, true, [18, 40])
82 .classed('badgeIcon readyBadge', true);
83 }
84
85 function instColor(id, online) {
86 return sus.cat7().getColor(id, !online, ts.theme());
87 }
88
89 // ==============================
90
91 function updateInstances() {
92 var rox = 5,
93 roy = 5,
94 rw = 160,
95 rhh = 30,
96 rbh = 45,
97 tx = 48,
98 instSvg = {
99 width: 170,
100 height: 85,
101 viewBox: '0 0 170 85'
102 },
103 headRect = {
104 x: rox,
105 y: roy,
106 width: rw,
107 height: rhh
108 },
109 bodyRect = {
110 x: rox,
111 y: roy + rhh,
112 width: rw,
113 height: rbh
114 },
115 titleAttr = {
116 class: 'instTitle',
117 x: tx,
118 y: 27
119 };
120
121 var onoses = oiBox.el().selectAll('.onosInst')
122 .data(onosOrder, function (d) { return d.id; });
123
124 function nSw(n) {
125 return 'Devices: ' + n;
126 }
127
128 // operate on existing onos instances if necessary
129 onoses.each(function (d) {
130 var el = d3.select(this),
131 svg = el.select('svg');
132
133 // update online state
134 el.classed('online', d.online);
135 el.classed('ready', d.ready);
136
137 // update ui-attached state
138 svg.select('use.uiBadge').remove();
139 if (d.uiAttached) {
140 attachUiBadge(svg);
141 }
142
143 function updAttr(id, value) {
144 svg.select('text.instLabel.' + id).text(value);
145 }
146
147 updAttr('ip', d.ip);
148 updAttr('ns', nSw(d.switches));
149 });
150
Steven Burrows57e24e92016-08-04 18:38:24 +0100151 // operate on new onos instances
152 var entering = onoses.enter()
153 .append('div')
154 .classed('onosInst', true)
155 .classed('online', function (d) { return d.online; })
156 .classed('ready', function (d) { return d.ready; })
157 .on('click', clickInst);
158
159 entering.each(function (d) {
160 var el = d3.select(this),
161 svg = el.append('svg').attr(instSvg);
162
163 svg.append('rect').attr(headRect);
164 svg.append('rect').attr(bodyRect);
165
166 gs.addGlyph(svg, 'bird', 20, false, [15, 10])
167 .classed('badgeIcon bird', true);
168
169 attachReadyBadge(svg);
170
171 if (d.uiAttached) {
172 attachUiBadge(svg);
173 }
174
175 svg.append('text')
176 .attr(titleAttr)
177 .text(d.id);
178
179 var ty = 55;
180 function addAttr(id, label) {
181 svg.append('text').attr({
182 class: 'instLabel ' + id,
183 x: tx,
184 y: ty
185 }).text(label);
186 ty += 18;
187 }
188
189 addAttr('ip', d.ip);
190 addAttr('ns', nSw(d.switches));
191 });
192
193 // operate on existing + new onoses here
194 // set the affinity colors...
195 onoses.each(function (d) {
196
197 var el = d3.select(this),
198 rect = el.select('svg').select('rect'),
199 col = instColor(d.id, d.online);
200
201 rect.style('fill', col);
202 });
203
204 // adjust the panel size appropriately...
205 oiBox.width(instSvg.width * onosOrder.length);
206 oiBox.height(instSvg.height);
207
208 // remove any outgoing instances
209 onoses.exit().remove();
210 }
211
Steven Burrows57e24e92016-08-04 18:38:24 +0100212 // ==========================
Steven Burrows57e24e92016-08-04 18:38:24 +0100213 function logicError(msg) {
214 if (showLogicErrors) {
215 $log.warn('TopoInstService: ' + msg);
216 }
217 }
218
219 function initInst(_api_) {
220 api = _api_;
221 oiBox = ps.createPanel(idIns, instOpts);
222 oiBox.show();
223
224 onosInstances = {};
225 onosOrder = [];
Steven Burrows57e24e92016-08-04 18:38:24 +0100226
227 // we want to update the instances, each time the theme changes
228 ts.addListener(updateInstances);
229 }
230
Steven Burrows57e24e92016-08-04 18:38:24 +0100231 function allInstances(data) {
232 $log.debug('Update all instances', data);
233
234 var members = data.members;
235
236 members.forEach(function (member) {
237 addInstance(member);
238 });
239 }
240
Steven Burrows7a9d04e2016-09-26 17:05:37 -0700241 function destroy() {
242 ts.removeListener(updateInstances);
243
244 ps.destroyPanel(idIns);
245 oiBox = null;
246
247 onosInstances = {};
248 onosOrder = [];
249 }
250
Steven Burrows57e24e92016-08-04 18:38:24 +0100251 angular.module('ovTopo2')
252 .factory('Topo2InstanceService',
253 ['$log', 'PanelService', 'SvgUtilService', 'GlyphService',
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100254 'ThemeService',
Steven Burrows57e24e92016-08-04 18:38:24 +0100255
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100256 function (_$log_, _ps_, _sus_, _gs_, _ts_) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100257 $log = _$log_;
258 ps = _ps_;
259 sus = _sus_;
260 gs = _gs_;
261 ts = _ts_;
Steven Burrows57e24e92016-08-04 18:38:24 +0100262
263 return {
264 initInst: initInst,
Steven Burrows7a9d04e2016-09-26 17:05:37 -0700265 allInstances: allInstances,
266 destroy: destroy
Steven Burrows57e24e92016-08-04 18:38:24 +0100267 };
268 }]);
269
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100270})();