blob: a29abace31387729daa5237039669cac845e3197 [file] [log] [blame]
Simon Hunt1002cd82015-04-23 14:44:03 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Simon Hunt1002cd82015-04-23 14:44:03 -07003 *
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 -- Flow View Module
19 */
20
21(function () {
22 'use strict';
23
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -070024 // injected references
Viswanath KSP7bdc9172016-10-19 20:19:17 +053025 var $log, $scope, $location, fs, tbs, ns, mast, ps, wss, is, ks;
26
27 // internal state
28 var detailsPanel,
29 pStartY,
30 pHeight,
31 top,
Viswanath KSP70e0d142016-10-28 21:58:32 +053032 topTable,
Viswanath KSPed55ecf2016-12-22 18:15:45 +053033 trmtDiv,
34 selDiv,
35 topSelTable,
36 topTrmtTable,
Viswanath KSP7bdc9172016-10-19 20:19:17 +053037 bottom,
38 iconDiv,
39 nameDiv,
40 wSize;
41
42
43 // constants
44 var topPdg = 28,
45 ctnrPdg = 24,
46 scrollSize = 17,
47 portsTblPdg = 50,
48 htPdg = 479,
49 wtPdg = 532,
50
51 pName = 'flow-details-panel',
52 detailsReq = 'flowDetailsRequest',
Viswanath KSP70e0d142016-10-28 21:58:32 +053053 detailsResp = 'flowDetailsResponse',
54
55 propOrder = [
Simon Hunt9bff5952017-07-13 14:05:09 -070056 'flowId',
57 'state',
58
59 'bytes',
60 'packets',
61 'duration',
62
63 'priority',
64 'tableId',
Simon Hunt36b658d2017-07-14 16:20:11 -070065 'appName',
Simon Hunt9bff5952017-07-13 14:05:09 -070066 'appId',
67
68 'groupId',
69 'timeout',
70 'permanent'
Viswanath KSP70e0d142016-10-28 21:58:32 +053071 ],
72 friendlyProps = [
Simon Hunt9bff5952017-07-13 14:05:09 -070073 'Flow ID',
74 'State',
75
76 'Bytes',
77 'Packets',
78 'Duration',
79
80 'Flow Priority',
81 'Table ID',
Simon Hunt36b658d2017-07-14 16:20:11 -070082 'App Name',
Simon Hunt9bff5952017-07-13 14:05:09 -070083 'App ID',
84
85 'Group ID',
86 'Timeout',
87 'Permanent'
Viswanath KSP70e0d142016-10-28 21:58:32 +053088 ];
Viswanath KSP7bdc9172016-10-19 20:19:17 +053089
90 function closePanel() {
91 if (detailsPanel.isVisible()) {
92 $scope.selId = null;
93 detailsPanel.hide();
94 return true;
95 }
96 return false;
97 }
98
99 function addCloseBtn(div) {
100 is.loadEmbeddedIcon(div, 'close', 20);
101 div.on('click', closePanel);
102 }
103
Viswanath KSP70e0d142016-10-28 21:58:32 +0530104 function handleEscape() {
105 return closePanel();
106 }
107
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530108 function setUpPanel() {
109 var container, closeBtn, tblDiv;
110 detailsPanel.empty();
111
112 container = detailsPanel.append('div').classed('container', true);
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530113 top = container.append('div').classed('top', true);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530114 selDiv = container.append('div').classed('top', true);
Simon Hunt9bff5952017-07-13 14:05:09 -0700115 trmtDiv = container.append('div').classed('top', true);
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530116 closeBtn = top.append('div').classed('close-btn', true);
117 addCloseBtn(closeBtn);
118 iconDiv = top.append('div').classed('dev-icon', true);
119 top.append('h2');
Viswanath KSP70e0d142016-10-28 21:58:32 +0530120 topTable = top.append('div').classed('top-content', true)
121 .append('table');
Simon Hunt9bff5952017-07-13 14:05:09 -0700122
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530123 top.append('hr');
Simon Hunt9bff5952017-07-13 14:05:09 -0700124
Simon Hunt239f09e2017-05-18 13:10:09 -0700125 selDiv.append('h2').text('Selector');
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530126 topSelTable = selDiv.append('div').classed('top-content', true)
127 .append('table');
128
Simon Hunt9bff5952017-07-13 14:05:09 -0700129 selDiv.append('hr');
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530130
Simon Hunt9bff5952017-07-13 14:05:09 -0700131 trmtDiv.append('h2').text('Treatment');
132 topTrmtTable = trmtDiv.append('div').classed('top-content', true)
133 .append('table');
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530134 }
135
Viswanath KSP70e0d142016-10-28 21:58:32 +0530136 function addProp(tbody, index, value) {
137 var tr = tbody.append('tr');
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530138
Viswanath KSP70e0d142016-10-28 21:58:32 +0530139 function addCell(cls, txt) {
Simon Hunt239f09e2017-05-18 13:10:09 -0700140 tr.append('td').attr('class', cls).text(txt);
Viswanath KSP70e0d142016-10-28 21:58:32 +0530141 }
142 addCell('label', friendlyProps[index] + ' :');
143 addCell('value', value);
144 }
145
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530146 function populateTable(tbody, label, value) {
147 var tr = tbody.append('tr');
148
149 function addCell(cls, txt) {
Simon Hunt239f09e2017-05-18 13:10:09 -0700150 tr.append('td').attr('class', cls).text(txt);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530151 }
152 addCell('label', label + ' :');
153 addCell('value', value);
154 }
155
Viswanath KSP70e0d142016-10-28 21:58:32 +0530156 function populateTop(details) {
157 is.loadEmbeddedIcon(iconDiv, 'flowTable', 40);
Simon Hunt239f09e2017-05-18 13:10:09 -0700158 top.select('h2').text(details.flowId);
Viswanath KSP70e0d142016-10-28 21:58:32 +0530159
160 var tbody = topTable.append('tbody');
161
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530162 var topSelTablebody = topSelTable.append('tbody');
163 var selectorString = details['selector'];
164 var selectors = selectorString.split(',');
165
166 var topTrmtTablebody = topTrmtTable.append('tbody');
167 var treatmentString = details['treatment'];
168 var treatment = treatmentString.split(',');
169
Viswanath KSP70e0d142016-10-28 21:58:32 +0530170 propOrder.forEach(function (prop, i) {
171 addProp(tbody, i, details[prop]);
172 });
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530173
174 selectors.forEach(function (sel) {
Jian Li70c460a2017-05-11 02:26:07 +0900175 var selArray = sel.match(/^([^:]*):([\s\S]*)/);
176 populateTable(topSelTablebody, selArray[1], selArray[2]);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530177 });
178
179 treatment.forEach(function (sel) {
Jian Li70c460a2017-05-11 02:26:07 +0900180 var selArray = sel.match(/^([^:]*):([\s\S]*)/);
181 populateTable(topTrmtTable, selArray[1], selArray[2]);
Viswanath KSPed55ecf2016-12-22 18:15:45 +0530182 });
183
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530184 }
185
186 function createDetailsPane() {
187 detailsPanel = ps.createPanel(pName, {
188 width: wSize.width,
189 margin: 0,
190 hideMargin: 0
191 });
192 detailsPanel.el().style({
193 position: 'absolute',
194 top: pStartY + 'px'
195 });
196 $scope.hidePanel = function () { detailsPanel.hide(); };
197 detailsPanel.hide();
198 }
199
200 function populateDetails(details) {
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530201 setUpPanel();
202 populateTop(details);
203
204 //ToDo add more details
205 detailsPanel.height(pHeight);
206 detailsPanel.width(wtPdg);
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530207 }
208
209 function respDetailsCb(data) {
Viswanath KSP70e0d142016-10-28 21:58:32 +0530210 $log.debug("Got response from server :", data);
211 $scope.panelData = data.details;
212 $scope.$apply();
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530213 }
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700214
Simon Hunt1002cd82015-04-23 14:44:03 -0700215 angular.module('ovFlow', [])
216 .controller('OvFlowCtrl',
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700217 ['$log', '$scope', '$location',
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700218 'FnService', 'TableBuilderService', 'NavService',
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530219 'MastService', 'PanelService', 'KeyService', 'IconService',
220 'WebSocketService',
Simon Hunt1002cd82015-04-23 14:44:03 -0700221
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530222 function (_$log_, _$scope_, _$location_, _fs_, _tbs_, _ns_,
223 _mast_, _ps_, _ks_, _is_, _wss_) {
224 var params,
225 handlers = {};
226
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700227 $log = _$log_;
228 $scope = _$scope_;
229 $location = _$location_;
230 fs = _fs_;
231 tbs = _tbs_;
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700232 ns = _ns_;
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530233 is = _is_;
234 wss = _wss_;
235 mast = _mast_;
236 ps = _ps_;
Simon Hunt20856ec2015-11-16 15:58:14 -0800237 $scope.deviceTip = 'Show device table';
Bri Prebilic Coleeef67ae2015-07-01 16:26:59 -0700238 $scope.portTip = 'Show port view for this device';
239 $scope.groupTip = 'Show group view for this device';
Jian Li1f544732015-12-30 23:36:37 -0800240 $scope.meterTip = 'Show meter view for selected device';
Kavitha Alagesaneaf614c2016-08-22 23:46:05 -0700241 $scope.briefTip = 'Switch to brief view';
242 $scope.detailTip = 'Switch to detailed view';
243 $scope.brief = true;
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700244 params = $location.search();
245 if (params.hasOwnProperty('devId')) {
Bri Prebilic Colee568ead2015-05-01 09:51:28 -0700246 $scope.devId = params['devId'];
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700247 }
248
249 tbs.buildTable({
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700250 scope: $scope,
251 tag: 'flow',
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530252 selCb: selCb,
Bri Prebilic Colecdc188d2015-04-24 16:40:11 -0700253 query: params
254 });
Bri Prebilic Cole3d4d01c2015-04-30 13:48:36 -0700255
Bri Prebilic Cole9b1fb9a2015-07-01 13:57:11 -0700256 $scope.nav = function (path) {
257 if ($scope.devId) {
258 ns.navTo(path, { devId: $scope.devId });
259 }
260 };
261
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530262 // details panel handlers
263 handlers[detailsResp] = respDetailsCb;
264 wss.bindHandlers(handlers);
265
266 function selCb($event, row) {
267 if ($scope.selId) {
268 wss.sendEvent(detailsReq, {flowId: row.id, appId: row.appId});
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530269 } else {
270 $scope.hidePanel();
271 }
272 $log.debug('Got a click on:', row);
273 }
274
Viswanath KSP70e0d142016-10-28 21:58:32 +0530275 $scope.$on('$destroy', function () {
276 wss.unbindHandlers(handlers);
277 });
278
Kavitha Alagesaneaf614c2016-08-22 23:46:05 -0700279 $scope.briefToggle = function () {
280 $scope.brief = !$scope.brief;
281 };
282
sisubram9ada8d72016-09-02 13:54:40 +0530283 Object.defineProperty($scope, "queryFilter", {
284 get: function() {
Simon Huntc8f06d92016-09-28 17:28:26 -0700285 var out = {};
286 out[$scope.queryBy || "$"] = $scope.queryTxt;
287 return out;
sisubram9ada8d72016-09-02 13:54:40 +0530288 }
289 });
290
Simon Hunt1002cd82015-04-23 14:44:03 -0700291 $log.log('OvFlowCtrl has been created');
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530292 }])
293
294 .directive('flowDetailsPanel',
295 ['$rootScope', '$window', '$timeout', 'KeyService',
296 function ($rootScope, $window, $timeout, ks) {
297 return function (scope) {
298 var unbindWatch;
299
300 function heightCalc() {
301 pStartY = fs.noPxStyle(d3.select('.tabular-header'), 'height')
302 + mast.mastHeight() + topPdg;
303 wSize = fs.windowSize(pStartY);
304 pHeight = wSize.height;
305 }
306
307 function initPanel() {
308 heightCalc();
309 createDetailsPane();
310 }
311
312 // Safari has a bug where it renders the fixed-layout table wrong
313 // if you ask for the window's size too early
314 if (scope.onos.browser === 'safari') {
315 $timeout(initPanel);
316 } else {
317 initPanel();
318 }
Viswanath KSP70e0d142016-10-28 21:58:32 +0530319 // create key bindings to handle panel
320 ks.keyBindings({
321 esc: [handleEscape, 'Close the details panel'],
322 _helpFormat: ['esc']
323 });
324 ks.gestureNotes([
325 ['click', 'Select a row to show cluster node details'],
326 ['scroll down', 'See available cluster nodes']
327 ]);
328 // if the panelData changes
329 scope.$watch('panelData', function () {
330 if (!fs.isEmptyObject(scope.panelData)) {
331 populateDetails(scope.panelData);
332 detailsPanel.show();
333 }
334 });
Viswanath KSP7bdc9172016-10-19 20:19:17 +0530335 // if the window size changes
336 unbindWatch = $rootScope.$watchCollection(
337 function () {
338 return {
339 h: $window.innerHeight,
340 w: $window.innerWidth
341 };
342 }, function () {
343 if (!fs.isEmptyObject(scope.panelData)) {
344 heightCalc();
345 populateDetails(scope.panelData);
346 }
347 }
348 );
349
350 scope.$on('$destroy', function () {
351 unbindWatch();
352 ps.destroyPanel(pName);
353 });
354 };
355 }]);
356
Simon Hunt1002cd82015-04-23 14:44:03 -0700357}());