Converting tables in flow and troubleshoot to use datagrid.
[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         },
95         // TODO: Make these values configurable.
96         autoRefreshInterval: {
97             flows: 10000,
98             ports: 10000,
99             refreshRateInterval: 5000
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                     clearTimeout(one.f.troubleshooting.existingNodes.registry.refreshTimer);
123                     $.getJSON(one.main.constants.address.prefix + "/troubleshoot/flowStats?nodeId=" + nodeId, function(content) {
124                         $rightBottomDashlet = one.f.troubleshooting.rightBottomDashlet.get();
125                         one.f.troubleshooting.rightBottomDashlet.setDashletHeader("Flows");
126                         one.lib.dashlet.empty($rightBottomDashlet);
127                         $rightBottomDashlet.append(one.lib.dashlet.header("Flow Details"));
128
129                         var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.existingNodes.id.flowsDataGrid, {
130                             searchable: true,
131                             filterable: false,
132                             pagination: true,
133                             flexibleRowsPerPage: true
134                             }, "table-striped table-condensed");
135                         $rightBottomDashlet.append($gridHTML);
136                         var dataSource = one.f.troubleshooting.existingNodes.data.flowsGrid(content);
137                         $("#" + one.f.troubleshooting.existingNodes.id.flowsDataGrid).datagrid({dataSource: dataSource});
138
139                         var numberOfFlows = content.nodeData.length;
140                         var refreshRate = one.f.troubleshooting.existingNodes.autoRefreshInterval.flows;
141                         if (numberOfFlows > 0) {
142                             refreshRate += Math.floor(numberOfFlows / 500) *
143                                 one.f.troubleshooting.existingNodes.autoRefreshInterval.refreshRateInterval;
144                         }
145                         one.f.troubleshooting.existingNodes.registry.refreshTimer = setTimeout(
146                                 one.f.troubleshooting.existingNodes.load.flows,
147                                 refreshRate, nodeId);
148                     });
149                 } catch(e) {}
150             },
151             ports: function(nodeId) {
152                 try {
153                     clearTimeout(one.f.troubleshooting.existingNodes.registry.refreshTimer);
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
160                         var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.existingNodes.id.portsDataGrid, {
161                             searchable: true,
162                             filterable: false,
163                             pagination: true,
164                             flexibleRowsPerPage: true
165                             }, "table-striped table-condensed");
166                         $rightBottomDashlet.append($gridHTML);
167                         var dataSource = one.f.troubleshooting.existingNodes.data.portsGrid(content);
168                         $("#" + one.f.troubleshooting.existingNodes.id.portsDataGrid).datagrid({dataSource: dataSource});
169
170                         var numberOfPorts = content.nodeData.length;
171                         var refreshRate = one.f.troubleshooting.existingNodes.autoRefreshInterval.ports;
172                         if (numberOfPorts > 0) {
173                             refreshRate += Math.floor(numberOfPorts / 500) *
174                                 one.f.troubleshooting.existingNodes.autoRefreshInterval.refreshRateInterval;
175                         }
176                         one.f.troubleshooting.existingNodes.registry.refreshTimer = setTimeout(
177                                 one.f.troubleshooting.existingNodes.load.ports,
178                                 refreshRate, nodeId);
179                     });
180                 } catch(e) {}
181             } 
182         },
183         ajax : function(url, callback) {
184             $.getJSON(url, function(data) {
185                 callback(data);
186             });
187         },
188         registry: {},
189         modal : {
190         },
191         data : {
192             existingNodesGrid: function(data) {
193                 var source = new StaticDataSource({
194                     columns: [
195                         {
196                             property: 'nodeName',
197                             label: 'Name',
198                             sortable: true
199                         },
200                         {
201                             property: 'nodeId',
202                             label: 'Static Route',
203                             sortable: true
204                         },
205                         {
206                             property: 'statistics',
207                             label: 'Statistics',
208                             sortable: true
209                         }
210                     ],
211                     data: data.nodeData,
212                     formatter: function(items) {
213                         $.each(items, function(index, item) {
214                             item["statistics"] = "<a href=\"javascript:one.f.troubleshooting.existingNodes.load.flows('" + item["nodeId"] + "');\">Flows</a>" + 
215                             " <a href=\"javascript:one.f.troubleshooting.existingNodes.load.ports('" + item["nodeId"] + "');\">Ports</a>";
216                         });
217
218                     },
219                     delay: 0
220                 });
221                 return source;
222             },
223             portsGrid: function(data) {
224                 var source = new StaticDataSource({
225                     columns: [
226                         {
227                             property: 'nodeConnector',
228                             label: 'Node Connector',
229                             sortable: true
230                         },
231                         {
232                             property: 'rxPkts',
233                             label: 'Rx Pkts',
234                             sortable: true
235                         },
236                         {
237                             property: 'txPkts',
238                             label: 'Tx Pkts',
239                             sortable: true
240                         },
241                         {
242                             property: 'rxBytes',
243                             label: 'Rx Bytes',
244                             sortable: true
245                         },
246                         {
247                             property: 'txBytes',
248                             label: 'Tx Bytes',
249                             sortable: true
250                         },
251                         {
252                             property: 'rxDrops',
253                             label: 'Rx Drops',
254                             sortable: true
255                         },
256                         {
257                             property: 'txDrops',
258                             label: 'Tx Drops',
259                             sortable: true
260                         },
261                         {
262                             property: 'rxErrors',
263                             label: 'Rx Errs',
264                             sortable: true
265                         },
266                         {
267                             property: 'txErrors',
268                             label: 'Tx Errs',
269                             sortable: true
270                         },
271                         {
272                             property: 'rxFrameErrors',
273                             label: 'Rx Frame Errs',
274                             sortable: true
275                         },
276                         {
277                             property: 'rxOverRunErrors',
278                             label: 'Rx OverRun Errs',
279                             sortable: true
280                         },
281                         {
282                             property: 'rxCRCErrors',
283                             label: 'Rx CRC Errs',
284                             sortable: true
285                         },
286                         {
287                             property: 'collisions',
288                             label: 'Collisions',
289                             sortable: true
290                         }
291                     ],
292                     data: data.nodeData,
293                     delay: 200
294                 });
295                 return source;
296             },
297             ports: function(data) {
298                 var result = [];
299                 $.each(data.nodeData, function(key, value) {
300                     var tr = {};
301                     var entry = [];
302                     entry.push(value["nodeConnector"]);
303                     entry.push(value["rxPkts"]);
304                     entry.push(value["txPkts"]);
305                     entry.push(value["rxBytes"]);
306                     entry.push(value["txBytes"]);
307                     entry.push(value["rxDrops"]);
308                     entry.push(value["txDrops"]);
309                     entry.push(value["rxErrors"]);
310                     entry.push(value["txErrors"]);
311                     entry.push(value["rxFrameErrors"]);
312                     entry.push(value["rxOverRunErrors"]);
313                     entry.push(value["rxCRCErrors"]);
314                     entry.push(value["collisions"]);
315                     tr.entry = entry;
316                     result.push(tr);
317                 });
318                 return result;
319             },
320             flowsGrid: function(data) {
321                 var source = new StaticDataSource({
322                     columns: [
323                         {
324                             property: 'nodeName',
325                             label: 'Node',
326                             sortable: true
327                         },
328                         {
329                             property: 'inPort',
330                             label: 'In Port',
331                             sortable: true
332                         },
333                         {
334                             property: 'dlSrc',
335                             label: 'DL Src',
336                             sortable: true
337                         },
338                         {
339                             property: 'dlDst',
340                             label: 'DL Dst',
341                             sortable: true
342                         },
343                         {
344                             property: 'dlType',
345                             label: 'DL Type',
346                             sortable: true
347                         },
348                         {
349                             property: 'dlVlan',
350                             label: 'DL Vlan',
351                             sortable: true
352                         },
353                         {
354                             property: 'nwSrc',
355                             label: 'NW Src',
356                             sortable: true
357                         },
358                         {
359                             property: 'nwDst',
360                             label: 'NW Dst',
361                             sortable: true
362                         },
363                         {
364                             property: 'nwProto',
365                             label: 'NW Proto',
366                             sortable: true
367                         },
368                         {
369                             property: 'tpSrc',
370                             label: 'TP Src',
371                             sortable: true
372                         },
373                         {
374                             property: 'tpDst',
375                             label: 'TP Dst',
376                             sortable: true
377                         },
378                         {
379                             property: 'actions',
380                             label: 'Actions',
381                             sortable: true
382                         },
383                         {
384                             property: 'byteCount',
385                             label: 'Byte Count',
386                             sortable: true
387                         },
388                         {
389                             property: 'packetCount',
390                             label: 'Packet Count',
391                             sortable: true
392                         },
393                         {
394                             property: 'durationSeconds',
395                             label: 'Duration Seconds',
396                             sortable: true
397                         },
398                         {
399                             property: 'idleTimeout',
400                             label: 'Idle Timeout',
401                             sortable: true
402                         },
403                         {
404                             property: 'outPorts',
405                             label: 'Out Ports',
406                             sortable: true
407                         },
408                         {
409                             property: 'outVlanId',
410                             label: 'Out VlanId',
411                             sortable: true
412                         },
413                         {
414                             property: 'priority',
415                             label: 'Priority',
416                             sortable: true
417                         }
418                     ],
419                     data: data.nodeData,
420                     delay: 0
421                 });
422                 return source;
423             },
424             flows: function(data) {
425                 var result = [];
426                 $.each(data.nodeData, function(key, value) {
427                     var tr = {};
428                     var entry = [];
429                     entry.push(value["nodeName"]);
430                     entry.push(value["inPort"]);
431                     entry.push(value["dlSrc"]);
432                     entry.push(value["dlDst"]);
433                     entry.push(value["dlType"]);
434                     entry.push(value["dlVlan"]);
435                     entry.push(value["nwSrc"]);
436                     entry.push(value["nwDst"]);
437                     entry.push(value["nwProto"]);
438                     entry.push(value["tpSrc"]);
439                     entry.push(value["tpDst"]);
440                     entry.push(value["actions"]);
441                     entry.push(value["byteCount"]);
442                     entry.push(value["packetCount"]);
443                     entry.push(value["durationSeconds"]);
444                     entry.push(value["idleTimeout"]);
445                     entry.push(value["outPorts"]);
446                     entry.push(value["outVlanId"]);
447                     entry.push(value["priority"]);
448                     tr.entry = entry;
449                     result.push(tr);
450                 });
451                 return result;
452             }
453         }
454 };
455
456 one.f.troubleshooting.uptime = {
457     id: {
458         popout: "one_f_troubleshooting_uptime_id_popout",
459         modal: "one_f_troubleshooting_uptime_id_modal",
460         datagrid: "one_f_troubleshooting_uptime_id_datagrid"
461     },
462
463     dashlet: function($dashlet) {
464             one.lib.dashlet.empty($dashlet);
465             $dashlet.append(one.lib.dashlet.header(one.f.dashlet.uptime.name));
466             var url = one.f.troubleshooting.rootUrl + "/uptime";
467             one.f.troubleshooting.uptime.ajax.main(url , {} ,function(content) {
468                 var $gridHTML = one.lib.dashlet.datagrid.init(one.f.troubleshooting.uptime.id.datagrid, {
469                     searchable: true,
470                     filterable: false,
471                     pagination: true,
472                     flexibleRowsPerPage: true
473                     }, "table-striped table-condensed");
474                 $dashlet.append($gridHTML);
475                 var dataSource = one.f.troubleshooting.uptime.data.uptimeDataGrid(content);
476                 $("#" + one.f.troubleshooting.uptime.id.datagrid).datagrid({dataSource: dataSource});
477             });
478     },
479     
480     ajax : {
481         main : function(url, requestData, callback) {
482             $.getJSON(url, requestData, function(data) {
483                 callback(data);
484             });
485         }
486     },
487     
488     data: {
489         uptimeDataGrid: function(data) {
490             var source = new StaticDataSource({
491                 columns: [
492                     {
493                         property: 'nodeName',
494                         label: 'Node',
495                         sortable: true
496                     },
497                     {
498                         property: 'nodeId',
499                         label: 'Node ID',
500                         sortable: true
501                     },
502                     {
503                         property: 'connectedSince',
504                         label: 'Statistics',
505                         sortable: true
506                     }
507                 ],
508                 data: data.nodeData,
509                 delay: 0
510             });
511             return source;
512         },
513         uptime: function(data) {
514             var result = [];
515             $.each(data.nodeData, function(key, value) {
516                 var tr = {};
517                 var entry = [];
518                 entry.push(value["nodeName"]);
519                 entry.push(value["nodeId"]);
520                 entry.push(value["connectedSince"]);
521                 tr.entry = entry;
522                 result.push(tr);
523             });
524             return result;
525         }
526     },
527 };
528
529 one.f.troubleshooting.statistics = {
530     dashlet : function($dashlet) {
531         var $h4 = one.lib.dashlet.header("Statistics");
532         $dashlet.append($h4);
533         // empty
534         var $none = $(document.createElement('div'));
535         $none.addClass('none');
536         var $p = $(document.createElement('p'));
537         $p.text('Please select a Flow or Ports statistics');
538         $p.addClass('text-center').addClass('text-info');
539         
540         $dashlet.append($none)
541             .append($p);
542     }
543 };
544
545 // bind dashlet nav
546 $('.dash .nav a', '#main').click(function() {
547     // de/activation
548     var $li = $(this).parent();
549     var $ul = $li.parent();
550     one.lib.nav.unfocus($ul);
551     $li.addClass('active');
552     // clear respective dashlet
553     var $dashlet = $ul.parent().find('.dashlet');
554     one.lib.dashlet.empty($dashlet);
555     // callback based on menu
556     var id = $(this).attr('id');
557     var menu = one.f.dashlet;
558     switch (id) {
559         case menu.existingNodes.id:
560             one.f.troubleshooting.existingNodes.load.main($dashlet);
561             break;
562         case menu.uptime.id:
563             one.f.troubleshooting.uptime.dashlet($dashlet);
564             break;
565         case menu.flowsOrPorts.id:
566             one.f.troubleshooting.statistics.dashlet($dashlet);
567             break;
568     };
569 });
570
571 // activate first tab on each dashlet
572 $('.dash .nav').each(function(index, value) {
573     $($(value).find('li')[0]).find('a').click();
574 });