Make sure invokeOperation is set once
[controller.git] / opendaylight / adsal / 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             modal : {
97                 nodeInfo : "one_f_troubleshooting_existingNodes_id_modal_nodeInfo",
98                 cancelButton : "one_f_troubleshooting_existingNodes_id_modal_cancelButton",
99             }
100         },
101         load: {
102             main: function($dashlet) {
103                 one.lib.dashlet.empty($dashlet);
104                 $dashlet.append(one.lib.dashlet.header(one.f.dashlet.existingNodes.name));
105                 // TODO(l): Add a generic auto expand function to one.lib and replace custom height setting.
106                 //$('#left-top').height('100%');
107                 one.f.troubleshooting.existingNodes.ajax(one.f.troubleshooting.rootUrl + "/existingNodes" , function(content) {
108                     var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.existingNodes.id.existingNodesDataGrid, {
109                         searchable: true,
110                         filterable: false,
111                         pagination: true,
112                         flexibleRowsPerPage: true
113                         }, "table-striped table-condensed");
114                     $dashlet.append($gridHTML);
115                     var dataSource = one.f.troubleshooting.existingNodes.data.existingNodesGrid(content);
116                     $("#" + one.f.troubleshooting.existingNodes.id.existingNodesDataGrid).datagrid({dataSource: dataSource});
117
118                 });
119             },
120             flows: function(nodeId) {
121                 try {
122                     if(one.f.troubleshooting === undefined){
123                         return;
124                     }
125                     $.getJSON(one.main.constants.address.prefix + "/troubleshoot/flowStats?nodeId=" + nodeId, function(content) {
126                         $rightBottomDashlet = one.f.troubleshooting.rightBottomDashlet.get();
127                         one.f.troubleshooting.rightBottomDashlet.setDashletHeader("Flows");
128                         one.lib.dashlet.empty($rightBottomDashlet);
129                         $rightBottomDashlet.append(one.lib.dashlet.header("Flow Details"));
130                         var button = one.lib.dashlet.button.single("Refresh",
131                                 one.f.troubleshooting.existingNodes.id.refreshFlowsButton, "btn-primary", "btn-mini");
132                         var $button = one.lib.dashlet.button.button(button);
133                         $button.click(function() {
134                             one.f.troubleshooting.existingNodes.load.flows(nodeId);
135                         });
136                         $rightBottomDashlet.append($button);
137                         var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.existingNodes.id.flowsDataGrid, {
138                             searchable: true,
139                             filterable: false,
140                             pagination: true,
141                             flexibleRowsPerPage: true
142                             }, "table-striped table-condensed");
143                         $rightBottomDashlet.append($gridHTML);
144                         var dataSource = one.f.troubleshooting.existingNodes.data.flowsGrid(content);
145                         $("#" + one.f.troubleshooting.existingNodes.id.flowsDataGrid).datagrid({dataSource: dataSource});
146                     });
147                 } catch(e) {}
148             },
149             ports: function(nodeId) {
150                 try {
151                     if(one.f.troubleshooting === undefined){
152                         return;
153                     }
154                     $.getJSON(one.main.constants.address.prefix + "/troubleshoot/portStats?nodeId=" + nodeId, function(content) {
155                         $rightBottomDashlet = one.f.troubleshooting.rightBottomDashlet.get();
156                         one.f.troubleshooting.rightBottomDashlet.setDashletHeader("Ports");
157                         one.lib.dashlet.empty($rightBottomDashlet);
158                         $rightBottomDashlet.append(one.lib.dashlet.header("Port Details"));
159                         var button = one.lib.dashlet.button.single("Refresh",
160                                 one.f.troubleshooting.existingNodes.id.refreshPortsButton, "btn-primary", "btn-mini");
161                         var $button = one.lib.dashlet.button.button(button);
162                         $button.click(function() {
163                             one.f.troubleshooting.existingNodes.load.ports(nodeId);
164                         });
165                         $rightBottomDashlet.append($button);
166                         var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.existingNodes.id.portsDataGrid, {
167                             searchable: true,
168                             filterable: false,
169                             pagination: true,
170                             flexibleRowsPerPage: true
171                             }, "table-striped table-condensed");
172                         $rightBottomDashlet.append($gridHTML);
173                         var dataSource = one.f.troubleshooting.existingNodes.data.portsGrid(content);
174                         $("#" + one.f.troubleshooting.existingNodes.id.portsDataGrid).datagrid({dataSource: dataSource});
175                     });
176                 } catch(e) {}
177             }
178         },
179         ajax : function(url, callback) {
180             $.getJSON(url, function(data) {
181                 callback(data);
182             });
183         },
184         registry: {},
185         modal : {
186         },
187         data : {
188             existingNodesGrid: function(data) {
189                 var source = new StaticDataSource({
190                     columns: [
191                         {
192                             property: 'nodeName',
193                             label: 'Name',
194                             sortable: true
195                         },
196                         {
197                             property: 'nodeId',
198                             label: 'Node ID',
199                             sortable: true
200                         },
201                         {
202                             property: 'statistics',
203                             label: 'Statistics',
204                             sortable: true
205                         }
206                     ],
207                     data: data.nodeData,
208                     formatter: function(items) {
209                         $.each(items, function(index, item) {
210                             item.nodeName = "<a href=\"javascript:one.f.troubleshooting.existingNodes.data.nodeInfo('"
211                                 + item.nodeId + "');\">" + item.nodeName + "</a>"
212                             item["statistics"] = "<a href=\"javascript:one.f.troubleshooting.existingNodes.load.flows('" + item["nodeId"] + "');\">Flows</a>" +
213                             " <a href=\"javascript:one.f.troubleshooting.existingNodes.load.ports('" + item["nodeId"] + "');\">Ports</a>";
214                         });
215                     },
216                     delay: 0
217                 });
218                 return source;
219             },
220             portsGrid: function(data) {
221                 $.each(data.nodeData, function(index, item) {
222                     item.rxPkts = one.lib.helper.parseInt(item.rxPkts);
223                     item.txPkts = one.lib.helper.parseInt(item.txPkts);
224                     item.rxBytes = one.lib.helper.parseInt(item.rxBytes);
225                     item.txBytes = one.lib.helper.parseInt(item.txBytes);
226                     item.rxDrops = one.lib.helper.parseInt(item.rxDrops);
227                     item.txDrops = one.lib.helper.parseInt(item.txDrops);
228                     item.rxErrors = one.lib.helper.parseInt(item.rxErrors);
229                     item.txErrors = one.lib.helper.parseInt(item.txErrors);
230                     item.rxFrameErrors = one.lib.helper.parseInt(item.rxFrameErrors);
231                     item.rxOverRunErrors = one.lib.helper.parseInt(item.rxOverRunErrors);
232                     item.rxCRCErrors = one.lib.helper.parseInt(item.rxCRCErrors);
233                     item.collisions = one.lib.helper.parseInt(item.collisions);
234                 });
235                 var source = new StaticDataSource({
236                     columns: [
237                         {
238                             property: 'nodeConnector',
239                             label: 'Node Connector',
240                             sortable: true
241                         },
242                         {
243                             property: 'rxPkts',
244                             label: 'Rx Pkts',
245                             sortable: true
246                         },
247                         {
248                             property: 'txPkts',
249                             label: 'Tx Pkts',
250                             sortable: true
251                         },
252                         {
253                             property: 'rxBytes',
254                             label: 'Rx Bytes',
255                             sortable: true
256                         },
257                         {
258                             property: 'txBytes',
259                             label: 'Tx Bytes',
260                             sortable: true
261                         },
262                         {
263                             property: 'rxDrops',
264                             label: 'Rx Drops',
265                             sortable: true
266                         },
267                         {
268                             property: 'txDrops',
269                             label: 'Tx Drops',
270                             sortable: true
271                         },
272                         {
273                             property: 'rxErrors',
274                             label: 'Rx Errs',
275                             sortable: true
276                         },
277                         {
278                             property: 'txErrors',
279                             label: 'Tx Errs',
280                             sortable: true
281                         },
282                         {
283                             property: 'rxFrameErrors',
284                             label: 'Rx Frame Errs',
285                             sortable: true
286                         },
287                         {
288                             property: 'rxOverRunErrors',
289                             label: 'Rx OverRun Errs',
290                             sortable: true
291                         },
292                         {
293                             property: 'rxCRCErrors',
294                             label: 'Rx CRC Errs',
295                             sortable: true
296                         },
297                         {
298                             property: 'collisions',
299                             label: 'Collisions',
300                             sortable: true
301                         }
302                     ],
303                     data: data.nodeData,
304                     delay: 0
305                 });
306                 return source;
307             },
308             ports: function(data) {
309                 var result = [];
310                 $.each(data.nodeData, function(key, value) {
311                     var tr = {};
312                     var entry = [];
313                     entry.push(value["nodeConnector"]);
314                     entry.push(value["rxPkts"]);
315                     entry.push(value["txPkts"]);
316                     entry.push(value["rxBytes"]);
317                     entry.push(value["txBytes"]);
318                     entry.push(value["rxDrops"]);
319                     entry.push(value["txDrops"]);
320                     entry.push(value["rxErrors"]);
321                     entry.push(value["txErrors"]);
322                     entry.push(value["rxFrameErrors"]);
323                     entry.push(value["rxOverRunErrors"]);
324                     entry.push(value["rxCRCErrors"]);
325                     entry.push(value["collisions"]);
326                     tr.entry = entry;
327                     result.push(tr);
328                 });
329                 return result;
330             },
331             flowsGrid: function(data) {
332                 $.each(data.nodeData, function(index, item) {
333                     item.byteCount = one.lib.helper.parseInt(item.byteCount);
334                     item.packetCount = one.lib.helper.parseInt(item.packetCount);
335                     item.durationSeconds = one.lib.helper.parseInt(item.durationSeconds);
336                     item.idleTimeout = one.lib.helper.parseInt(item.idleTimeout);
337                     item.priority = one.lib.helper.parseInt(item.priority);
338                 });
339                 var source = new StaticDataSource({
340                     columns: [
341                         {
342                             property: 'nodeName',
343                             label: 'Node',
344                             sortable: true
345                         },
346                         {
347                             property: 'inPort',
348                             label: 'In Port',
349                             sortable: true
350                         },
351                         {
352                             property: 'dlSrc',
353                             label: 'DL Src',
354                             sortable: true
355                         },
356                         {
357                             property: 'dlDst',
358                             label: 'DL Dst',
359                             sortable: true
360                         },
361                         {
362                             property: 'dlType',
363                             label: 'DL Type',
364                             sortable: true
365                         },
366                         {
367                             property: 'dlVlan',
368                             label: 'DL Vlan',
369                             sortable: true
370                         },
371                         {
372                             property: 'dlVlanPriority',
373                             label: 'Vlan PCP',
374                             sortable: true
375                         },
376                         {
377                             property: 'nwSrc',
378                             label: 'NW Src',
379                             sortable: true
380                         },
381                         {
382                             property: 'nwDst',
383                             label: 'NW Dst',
384                             sortable: true
385                         },
386                         {
387                             property: 'nwTOS',
388                             label: 'ToS Bits',
389                             sortable: true
390                         },
391                         {
392                             property: 'nwProto',
393                             label: 'NW Proto',
394                             sortable: true
395                         },
396                         {
397                             property: 'tpSrc',
398                             label: 'TP Src',
399                             sortable: true
400                         },
401                         {
402                             property: 'tpDst',
403                             label: 'TP Dst',
404                             sortable: true
405                         },
406                         {
407                             property: 'actions',
408                             label: 'Actions',
409                             sortable: true
410                         },
411                         {
412                             property: 'byteCount',
413                             label: 'Byte Count',
414                             sortable: true
415                         },
416                         {
417                             property: 'packetCount',
418                             label: 'Packet Count',
419                             sortable: true
420                         },
421                         {
422                             property: 'durationSeconds',
423                             label: 'Duration Seconds',
424                             sortable: true
425                         },
426                         {
427                             property: 'idleTimeout',
428                             label: 'Idle Timeout',
429                             sortable: true
430                         },
431                         {
432                             property: 'priority',
433                             label: 'Priority',
434                             sortable: true
435                         }
436                     ],
437                     data: data.nodeData,
438                     delay: 0
439                 });
440                 return source;
441             },
442             flows: function(data) {
443                 var result = [];
444                 $.each(data.nodeData, function(key, value) {
445                     var tr = {};
446                     var entry = [];
447                     entry.push(value["nodeName"]);
448                     entry.push(value["inPort"]);
449                     entry.push(value["dlSrc"]);
450                     entry.push(value["dlDst"]);
451                     entry.push(value["dlType"]);
452                     entry.push(value["dlVlan"]);
453                     entry.push(value["nwSrc"]);
454                     entry.push(value["nwDst"]);
455                     entry.push(value["nwTOS"]);
456                     entry.push(value["nwProto"]);
457                     entry.push(value["tpSrc"]);
458                     entry.push(value["tpDst"]);
459                     entry.push(value["actions"]);
460                     entry.push(value["byteCount"]);
461                     entry.push(value["packetCount"]);
462                     entry.push(value["durationSeconds"]);
463                     entry.push(value["idleTimeout"]);
464                     entry.push(value["priority"]);
465                     tr.entry = entry;
466                     result.push(tr);
467                 });
468                 return result;
469             },
470             nodeInfo : function(nodeId){
471                 $.getJSON(one.main.constants.address.prefix + "/troubleshoot/nodeInfo?nodeId=" + nodeId, function(content) {
472                     var h3 = 'Node Information'
473
474                     var headers = [ 'Description','Specification'];
475
476                     var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
477                     var $table = one.lib.dashlet.table.table(attributes);
478                     var $thead = one.lib.dashlet.table.header(headers);
479                     $table.append($thead);
480
481                     var footer = [];
482
483                     var cancelButton = one.lib.dashlet.button.single("Cancel",
484                             one.f.troubleshooting.existingNodes.id.modal.nodeInfo, "", "");
485                     var $cancelButton = one.lib.dashlet.button.button(cancelButton);
486                     footer.push($cancelButton);
487
488                     var body = []
489                     $.each(content, function(key, value) {
490                         var tr = {};
491                         var entry = [];
492
493                         entry.push(key);
494                         entry.push(value);
495
496                         tr.entry = entry;
497                         body.push(tr);
498                     });
499                     var $tbody = one.lib.dashlet.table.body(body);
500                     $table.append($tbody);
501
502                     var $modal = one.lib.modal.spawn(one.f.troubleshooting.existingNodes.id.modal.nodeInfo, h3, $table , footer);
503                     $modal.modal();
504
505                     $('#'+one.f.troubleshooting.existingNodes.id.modal.nodeInfo, $modal).click(function() {
506                         $modal.modal('hide');
507                     });
508                 });
509             }
510         }
511 };
512
513 one.f.troubleshooting.uptime = {
514     id: {
515         popout: "one_f_troubleshooting_uptime_id_popout",
516         modal: "one_f_troubleshooting_uptime_id_modal",
517         datagrid: "one_f_troubleshooting_uptime_id_datagrid"
518     },
519
520     dashlet: function($dashlet) {
521             one.lib.dashlet.empty($dashlet);
522             $dashlet.append(one.lib.dashlet.header(one.f.dashlet.uptime.name));
523             var url = one.f.troubleshooting.rootUrl + "/uptime";
524             one.f.troubleshooting.uptime.ajax.main(url , {} ,function(content) {
525                 var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.uptime.id.datagrid, {
526                     searchable: true,
527                     filterable: false,
528                     pagination: true,
529                     flexibleRowsPerPage: true
530                     }, "table-striped table-condensed");
531                 $dashlet.append($gridHTML);
532                 var dataSource = one.f.troubleshooting.uptime.data.uptimeDataGrid(content);
533                 $("#" + one.f.troubleshooting.uptime.id.datagrid).datagrid({dataSource: dataSource});
534             });
535     },
536
537     ajax : {
538         main : function(url, requestData, callback) {
539             $.getJSON(url, requestData, function(data) {
540                 callback(data);
541             });
542         }
543     },
544
545     data: {
546         uptimeDataGrid: function(data) {
547             var source = new StaticDataSource({
548                 columns: [
549                     {
550                         property: 'nodeName',
551                         label: 'Node',
552                         sortable: true
553                     },
554                     {
555                         property: 'nodeId',
556                         label: 'Node ID',
557                         sortable: true
558                     },
559                     {
560                         property: 'connectedSince',
561                         label: 'Statistics',
562                         sortable: true
563                     }
564                 ],
565                 data: data.nodeData,
566                 delay: 0
567             });
568             return source;
569         },
570         uptime: function(data) {
571             var result = [];
572             $.each(data.nodeData, function(key, value) {
573                 var tr = {};
574                 var entry = [];
575                 entry.push(value["nodeName"]);
576                 entry.push(value["nodeId"]);
577                 entry.push(value["connectedSince"]);
578                 tr.entry = entry;
579                 result.push(tr);
580             });
581             return result;
582         }
583     },
584 };
585
586 one.f.troubleshooting.statistics = {
587     dashlet : function($dashlet) {
588         var $h4 = one.lib.dashlet.header("Statistics");
589         $dashlet.append($h4);
590         // empty
591         var $none = $(document.createElement('div'));
592         $none.addClass('none');
593         var $p = $(document.createElement('p'));
594         $p.text('Please select a Flow or Ports statistics');
595         $p.addClass('text-center').addClass('text-info');
596
597         $dashlet.append($none)
598             .append($p);
599     }
600 };
601
602 // bind dashlet nav
603 $('.dash .nav a', '#main').click(function() {
604     // de/activation
605     var $li = $(this).parent();
606     var $ul = $li.parent();
607     one.lib.nav.unfocus($ul);
608     $li.addClass('active');
609     // clear respective dashlet
610     var $dashlet = $ul.parent().find('.dashlet');
611     one.lib.dashlet.empty($dashlet);
612     // callback based on menu
613     var id = $(this).attr('id');
614     var menu = one.f.dashlet;
615     switch (id) {
616         case menu.existingNodes.id:
617             one.f.troubleshooting.existingNodes.load.main($dashlet);
618             break;
619         case menu.uptime.id:
620             one.f.troubleshooting.uptime.dashlet($dashlet);
621             break;
622         case menu.flowsOrPorts.id:
623             one.f.troubleshooting.statistics.dashlet($dashlet);
624             break;
625     };
626 });
627
628 // activate first tab on each dashlet
629 $('.dash .nav').each(function(index, value) {
630     $($(value).find('li')[0]).find('a').click();
631 });