Bug 380 SwitchManager.getHardwareMAC() does not handle empty string case
[controller.git] / opendaylight / web / troubleshoot / src / main / resources / js / page.js
1 /* 
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved. 
3  * 
4  * This program and the accompanying materials are made available under the 
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution, 
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  *
8  */
9
10 //PAGE troubleshoot
11 one.f = {};
12
13 // specify dashlets and layouts
14 one.f.dashlet = {
15     existingNodes : {
16         id : 'existingNodes',
17         name : 'Existing Nodes'
18     },
19     uptime: {
20         id: 'uptime',
21         name: 'Uptime'
22     },
23     flowsOrPorts: {
24         id: "flowsOrPorts",
25         name: "Statistics"
26     }
27 };
28
29 one.f.menu = {
30     left : {
31         top : [
32             one.f.dashlet.existingNodes
33         ],
34         bottom : [
35             one.f.dashlet.uptime
36         ]
37     },
38     right : {
39         top : [],
40         bottom : [
41             one.f.dashlet.flowsOrPorts
42         ]
43     }
44 };
45
46 /** INIT **/
47 // populate nav tabs
48 $(one.f.menu.left.top).each(function(index, value) {
49     var $nav = $(".nav", "#left-top");
50     one.main.page.dashlet($nav, value);
51 });
52
53 $(one.f.menu.left.bottom).each(function(index, value) {
54     var $nav = $(".nav", "#left-bottom");
55     one.main.page.dashlet($nav, value);
56 });
57
58 $(one.f.menu.right.bottom).each(function(index, value) {
59     var $nav = $(".nav", "#right-bottom");
60     one.main.page.dashlet($nav, value);
61 });
62
63 /**Troubleshoot modules*/
64 one.f.troubleshooting = {
65     rootUrl: "/controller/web/troubleshoot",
66     rightBottomDashlet: { 
67         get: function() {
68             var $rightBottomDashlet = $("#right-bottom").find(".dashlet");
69             return $rightBottomDashlet;
70         },
71         setDashletHeader: function(label) {
72             $("#right-bottom li a")[0].innerHTML = label; 
73         }
74     },
75     createTable: function(columnNames, body) {
76         var tableAttributes = ["table-striped", "table-bordered", "table-condensed"];
77         var $table = one.lib.dashlet.table.table(tableAttributes);
78         var tableHeaders = columnNames;
79         var $thead = one.lib.dashlet.table.header(tableHeaders);
80         var $tbody = one.lib.dashlet.table.body(body, tableHeaders);
81         $table.append($thead)
82             .append($tbody);
83         return $table;
84     }
85 };
86
87 one.f.troubleshooting.existingNodes = {
88         id: {
89             popout: "one_f_troubleshooting_existingNodes_id_popout",
90             modal: "one_f_troubleshooting_existingNodes_id_modal",
91             existingNodesDataGrid: "one_f_troubleshooting_existingNodes_id_datagrid",
92             portsDataGrid: "one_f_troubleshooting_existingNodes_id_portsDataGrid",
93             flowsDataGrid: "one_f_troubleshooting_existingNodes_id_flowsDataGrid",
94             refreshFlowsButton:"one_f_troubleshooting_existingNodes_id_refreshFlowsButton",
95             refreshPortsButton:"one_f_troubleshooting_existingNodes_id_refreshPortsButton"
96
97         },
98         load: {
99             main: function($dashlet) {
100                 one.lib.dashlet.empty($dashlet);
101                 $dashlet.append(one.lib.dashlet.header(one.f.dashlet.existingNodes.name));
102                 // TODO(l): Add a generic auto expand function to one.lib and replace custom height setting.
103                 //$('#left-top').height('100%');
104                 one.f.troubleshooting.existingNodes.ajax(one.f.troubleshooting.rootUrl + "/existingNodes" , function(content) {
105                     var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.existingNodes.id.existingNodesDataGrid, {
106                         searchable: true,
107                         filterable: false,
108                         pagination: true,
109                         flexibleRowsPerPage: true
110                         }, "table-striped table-condensed");
111                     $dashlet.append($gridHTML);
112                     var dataSource = one.f.troubleshooting.existingNodes.data.existingNodesGrid(content);
113                     $("#" + one.f.troubleshooting.existingNodes.id.existingNodesDataGrid).datagrid({dataSource: dataSource});
114
115                 });
116             },
117             flows: function(nodeId) {
118                 try {
119                     if(one.f.troubleshooting === undefined){
120                         return;
121                     }
122                     $.getJSON(one.main.constants.address.prefix + "/troubleshoot/flowStats?nodeId=" + nodeId, function(content) {
123                         $rightBottomDashlet = one.f.troubleshooting.rightBottomDashlet.get();
124                         one.f.troubleshooting.rightBottomDashlet.setDashletHeader("Flows");
125                         one.lib.dashlet.empty($rightBottomDashlet);
126                         $rightBottomDashlet.append(one.lib.dashlet.header("Flow Details"));
127                         var button = one.lib.dashlet.button.single("Refresh",
128                                 one.f.troubleshooting.existingNodes.id.refreshFlowsButton, "btn-primary", "btn-mini");
129                         var $button = one.lib.dashlet.button.button(button);
130                         $button.click(function() {
131                             one.f.troubleshooting.existingNodes.load.flows(nodeId);
132                         });
133                         $rightBottomDashlet.append($button);
134                         var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.existingNodes.id.flowsDataGrid, {
135                             searchable: true,
136                             filterable: false,
137                             pagination: true,
138                             flexibleRowsPerPage: true
139                             }, "table-striped table-condensed");
140                         $rightBottomDashlet.append($gridHTML);
141                         var dataSource = one.f.troubleshooting.existingNodes.data.flowsGrid(content);
142                         $("#" + one.f.troubleshooting.existingNodes.id.flowsDataGrid).datagrid({dataSource: dataSource});
143                     });
144                 } catch(e) {}
145             },
146             ports: function(nodeId) {
147                 try {
148                     if(one.f.troubleshooting === undefined){
149                         return;
150                     }
151                     $.getJSON(one.main.constants.address.prefix + "/troubleshoot/portStats?nodeId=" + nodeId, function(content) {
152                         $rightBottomDashlet = one.f.troubleshooting.rightBottomDashlet.get();
153                         one.f.troubleshooting.rightBottomDashlet.setDashletHeader("Ports");
154                         one.lib.dashlet.empty($rightBottomDashlet);
155                         $rightBottomDashlet.append(one.lib.dashlet.header("Port Details"));
156                         var button = one.lib.dashlet.button.single("Refresh",
157                                 one.f.troubleshooting.existingNodes.id.refreshPortsButton, "btn-primary", "btn-mini");
158                         var $button = one.lib.dashlet.button.button(button);
159                         $button.click(function() {
160                             one.f.troubleshooting.existingNodes.load.ports(nodeId);
161                         });
162                         $rightBottomDashlet.append($button);
163                         var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.existingNodes.id.portsDataGrid, {
164                             searchable: true,
165                             filterable: false,
166                             pagination: true,
167                             flexibleRowsPerPage: true
168                             }, "table-striped table-condensed");
169                         $rightBottomDashlet.append($gridHTML);
170                         var dataSource = one.f.troubleshooting.existingNodes.data.portsGrid(content);
171                         $("#" + one.f.troubleshooting.existingNodes.id.portsDataGrid).datagrid({dataSource: dataSource});
172                     });
173                 } catch(e) {}
174             } 
175         },
176         ajax : function(url, callback) {
177             $.getJSON(url, function(data) {
178                 callback(data);
179             });
180         },
181         registry: {},
182         modal : {
183         },
184         data : {
185             existingNodesGrid: function(data) {
186                 var source = new StaticDataSource({
187                     columns: [
188                         {
189                             property: 'nodeName',
190                             label: 'Name',
191                             sortable: true
192                         },
193                         {
194                             property: 'nodeId',
195                             label: 'Node ID',
196                             sortable: true
197                         },
198                         {
199                             property: 'statistics',
200                             label: 'Statistics',
201                             sortable: true
202                         }
203                     ],
204                     data: data.nodeData,
205                     formatter: function(items) {
206                         $.each(items, function(index, item) {
207                             item["statistics"] = "<a href=\"javascript:one.f.troubleshooting.existingNodes.load.flows('" + item["nodeId"] + "');\">Flows</a>" + 
208                             " <a href=\"javascript:one.f.troubleshooting.existingNodes.load.ports('" + item["nodeId"] + "');\">Ports</a>";
209                         });
210
211                     },
212                     delay: 0
213                 });
214                 return source;
215             },
216             portsGrid: function(data) {
217                 var source = new StaticDataSource({
218                     columns: [
219                         {
220                             property: 'nodeConnector',
221                             label: 'Node Connector',
222                             sortable: true
223                         },
224                         {
225                             property: 'rxPkts',
226                             label: 'Rx Pkts',
227                             sortable: true
228                         },
229                         {
230                             property: 'txPkts',
231                             label: 'Tx Pkts',
232                             sortable: true
233                         },
234                         {
235                             property: 'rxBytes',
236                             label: 'Rx Bytes',
237                             sortable: true
238                         },
239                         {
240                             property: 'txBytes',
241                             label: 'Tx Bytes',
242                             sortable: true
243                         },
244                         {
245                             property: 'rxDrops',
246                             label: 'Rx Drops',
247                             sortable: true
248                         },
249                         {
250                             property: 'txDrops',
251                             label: 'Tx Drops',
252                             sortable: true
253                         },
254                         {
255                             property: 'rxErrors',
256                             label: 'Rx Errs',
257                             sortable: true
258                         },
259                         {
260                             property: 'txErrors',
261                             label: 'Tx Errs',
262                             sortable: true
263                         },
264                         {
265                             property: 'rxFrameErrors',
266                             label: 'Rx Frame Errs',
267                             sortable: true
268                         },
269                         {
270                             property: 'rxOverRunErrors',
271                             label: 'Rx OverRun Errs',
272                             sortable: true
273                         },
274                         {
275                             property: 'rxCRCErrors',
276                             label: 'Rx CRC Errs',
277                             sortable: true
278                         },
279                         {
280                             property: 'collisions',
281                             label: 'Collisions',
282                             sortable: true
283                         }
284                     ],
285                     data: data.nodeData,
286                     delay: 0
287                 });
288                 return source;
289             },
290             ports: function(data) {
291                 var result = [];
292                 $.each(data.nodeData, function(key, value) {
293                     var tr = {};
294                     var entry = [];
295                     entry.push(value["nodeConnector"]);
296                     entry.push(value["rxPkts"]);
297                     entry.push(value["txPkts"]);
298                     entry.push(value["rxBytes"]);
299                     entry.push(value["txBytes"]);
300                     entry.push(value["rxDrops"]);
301                     entry.push(value["txDrops"]);
302                     entry.push(value["rxErrors"]);
303                     entry.push(value["txErrors"]);
304                     entry.push(value["rxFrameErrors"]);
305                     entry.push(value["rxOverRunErrors"]);
306                     entry.push(value["rxCRCErrors"]);
307                     entry.push(value["collisions"]);
308                     tr.entry = entry;
309                     result.push(tr);
310                 });
311                 return result;
312             },
313             flowsGrid: function(data) {
314                 var source = new StaticDataSource({
315                     columns: [
316                         {
317                             property: 'nodeName',
318                             label: 'Node',
319                             sortable: true
320                         },
321                         {
322                             property: 'inPort',
323                             label: 'In Port',
324                             sortable: true
325                         },
326                         {
327                             property: 'dlSrc',
328                             label: 'DL Src',
329                             sortable: true
330                         },
331                         {
332                             property: 'dlDst',
333                             label: 'DL Dst',
334                             sortable: true
335                         },
336                         {
337                             property: 'dlType',
338                             label: 'DL Type',
339                             sortable: true
340                         },
341                         {
342                             property: 'dlVlan',
343                             label: 'DL Vlan',
344                             sortable: true
345                         },
346                         {
347                             property: 'nwSrc',
348                             label: 'NW Src',
349                             sortable: true
350                         },
351                         {
352                             property: 'nwDst',
353                             label: 'NW Dst',
354                             sortable: true
355                         },
356                         {
357                             property: 'nwProto',
358                             label: 'NW Proto',
359                             sortable: true
360                         },
361                         {
362                             property: 'tpSrc',
363                             label: 'TP Src',
364                             sortable: true
365                         },
366                         {
367                             property: 'tpDst',
368                             label: 'TP Dst',
369                             sortable: true
370                         },
371                         {
372                             property: 'actions',
373                             label: 'Actions',
374                             sortable: true
375                         },
376                         {
377                             property: 'byteCount',
378                             label: 'Byte Count',
379                             sortable: true
380                         },
381                         {
382                             property: 'packetCount',
383                             label: 'Packet Count',
384                             sortable: true
385                         },
386                         {
387                             property: 'durationSeconds',
388                             label: 'Duration Seconds',
389                             sortable: true
390                         },
391                         {
392                             property: 'idleTimeout',
393                             label: 'Idle Timeout',
394                             sortable: true
395                         },
396                         {
397                             property: 'priority',
398                             label: 'Priority',
399                             sortable: true
400                         }
401                     ],
402                     data: data.nodeData,
403                     delay: 0
404                 });
405                 return source;
406             },
407             flows: function(data) {
408                 var result = [];
409                 $.each(data.nodeData, function(key, value) {
410                     var tr = {};
411                     var entry = [];
412                     entry.push(value["nodeName"]);
413                     entry.push(value["inPort"]);
414                     entry.push(value["dlSrc"]);
415                     entry.push(value["dlDst"]);
416                     entry.push(value["dlType"]);
417                     entry.push(value["dlVlan"]);
418                     entry.push(value["nwSrc"]);
419                     entry.push(value["nwDst"]);
420                     entry.push(value["nwProto"]);
421                     entry.push(value["tpSrc"]);
422                     entry.push(value["tpDst"]);
423                     entry.push(value["actions"]);
424                     entry.push(value["byteCount"]);
425                     entry.push(value["packetCount"]);
426                     entry.push(value["durationSeconds"]);
427                     entry.push(value["idleTimeout"]);
428                     entry.push(value["priority"]);
429                     tr.entry = entry;
430                     result.push(tr);
431                 });
432                 return result;
433             }
434         }
435 };
436
437 one.f.troubleshooting.uptime = {
438     id: {
439         popout: "one_f_troubleshooting_uptime_id_popout",
440         modal: "one_f_troubleshooting_uptime_id_modal",
441         datagrid: "one_f_troubleshooting_uptime_id_datagrid"
442     },
443
444     dashlet: function($dashlet) {
445             one.lib.dashlet.empty($dashlet);
446             $dashlet.append(one.lib.dashlet.header(one.f.dashlet.uptime.name));
447             var url = one.f.troubleshooting.rootUrl + "/uptime";
448             one.f.troubleshooting.uptime.ajax.main(url , {} ,function(content) {
449                 var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.uptime.id.datagrid, {
450                     searchable: true,
451                     filterable: false,
452                     pagination: true,
453                     flexibleRowsPerPage: true
454                     }, "table-striped table-condensed");
455                 $dashlet.append($gridHTML);
456                 var dataSource = one.f.troubleshooting.uptime.data.uptimeDataGrid(content);
457                 $("#" + one.f.troubleshooting.uptime.id.datagrid).datagrid({dataSource: dataSource});
458             });
459     },
460     
461     ajax : {
462         main : function(url, requestData, callback) {
463             $.getJSON(url, requestData, function(data) {
464                 callback(data);
465             });
466         }
467     },
468     
469     data: {
470         uptimeDataGrid: function(data) {
471             var source = new StaticDataSource({
472                 columns: [
473                     {
474                         property: 'nodeName',
475                         label: 'Node',
476                         sortable: true
477                     },
478                     {
479                         property: 'nodeId',
480                         label: 'Node ID',
481                         sortable: true
482                     },
483                     {
484                         property: 'connectedSince',
485                         label: 'Statistics',
486                         sortable: true
487                     }
488                 ],
489                 data: data.nodeData,
490                 delay: 0
491             });
492             return source;
493         },
494         uptime: function(data) {
495             var result = [];
496             $.each(data.nodeData, function(key, value) {
497                 var tr = {};
498                 var entry = [];
499                 entry.push(value["nodeName"]);
500                 entry.push(value["nodeId"]);
501                 entry.push(value["connectedSince"]);
502                 tr.entry = entry;
503                 result.push(tr);
504             });
505             return result;
506         }
507     },
508 };
509
510 one.f.troubleshooting.statistics = {
511     dashlet : function($dashlet) {
512         var $h4 = one.lib.dashlet.header("Statistics");
513         $dashlet.append($h4);
514         // empty
515         var $none = $(document.createElement('div'));
516         $none.addClass('none');
517         var $p = $(document.createElement('p'));
518         $p.text('Please select a Flow or Ports statistics');
519         $p.addClass('text-center').addClass('text-info');
520         
521         $dashlet.append($none)
522             .append($p);
523     }
524 };
525
526 // bind dashlet nav
527 $('.dash .nav a', '#main').click(function() {
528     // de/activation
529     var $li = $(this).parent();
530     var $ul = $li.parent();
531     one.lib.nav.unfocus($ul);
532     $li.addClass('active');
533     // clear respective dashlet
534     var $dashlet = $ul.parent().find('.dashlet');
535     one.lib.dashlet.empty($dashlet);
536     // callback based on menu
537     var id = $(this).attr('id');
538     var menu = one.f.dashlet;
539     switch (id) {
540         case menu.existingNodes.id:
541             one.f.troubleshooting.existingNodes.load.main($dashlet);
542             break;
543         case menu.uptime.id:
544             one.f.troubleshooting.uptime.dashlet($dashlet);
545             break;
546         case menu.flowsOrPorts.id:
547             one.f.troubleshooting.statistics.dashlet($dashlet);
548             break;
549     };
550 });
551
552 // activate first tab on each dashlet
553 $('.dash .nav').each(function(index, value) {
554     $($(value).find('li')[0]).find('a').click();
555 });