[onos-6337] Adding first set of changes ( server side with client side stub )
[onos-6337] Patchset-2 with changes addressing review comments
[onos-6337] Patchset-3 with changes addressing review comments

Change-Id: I37011ad7b8d2fbb01082736b1d787331aaad0a42
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/PortViewMessageHandler.java b/web/gui/src/main/java/org/onosproject/ui/impl/PortViewMessageHandler.java
index 7ec0805..080a972 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/PortViewMessageHandler.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/PortViewMessageHandler.java
@@ -29,6 +29,7 @@
 import org.onosproject.ui.table.cell.NumberFormatter;
 
 import java.util.Collection;
+import java.util.List;
 
 
 /**
@@ -39,6 +40,8 @@
     private static final String PORT_DATA_REQ = "portDataRequest";
     private static final String PORT_DATA_RESP = "portDataResponse";
     private static final String PORTS = "ports";
+    private static final String DELTA = "showDelta";
+    private static final String NZ = "nzFilter";
 
     private static final String ID = "id";
     private static final String PKT_RX = "pkt_rx";
@@ -93,10 +96,18 @@
         @Override
         protected void populateTable(TableModel tm, ObjectNode payload) {
             String uri = string(payload, "devId");
+            boolean nz = bool(payload, NZ);
+            boolean delta = bool(payload, DELTA);
             if (!Strings.isNullOrEmpty(uri)) {
                 DeviceId deviceId = DeviceId.deviceId(uri);
                 DeviceService ds = get(DeviceService.class);
-                for (PortStatistics stat : ds.getPortStatistics(deviceId)) {
+                List<PortStatistics> stats = delta ?
+                        ds.getPortDeltaStatistics(deviceId) :
+                        ds.getPortStatistics(deviceId);
+                for (PortStatistics stat : stats) {
+                    if (nz && stat.isZero()) {
+                        continue;
+                    }
                     populateRow(tm.addRow(), stat);
                 }
             }
diff --git a/web/gui/src/main/webapp/app/fw/widget/tableBuilder.js b/web/gui/src/main/webapp/app/fw/widget/tableBuilder.js
index f36d1a8..cab5c8e 100644
--- a/web/gui/src/main/webapp/app/fw/widget/tableBuilder.js
+++ b/web/gui/src/main/webapp/app/fw/widget/tableBuilder.js
@@ -152,6 +152,10 @@
 
         requestTableData();
         startRefresh();
+
+        return {
+            forceRefesh : requestTableData
+        };
     }
 
     angular.module('onosWidget')
diff --git a/web/gui/src/main/webapp/app/view/port/port.css b/web/gui/src/main/webapp/app/view/port/port.css
index dd4b878..44c0abe 100644
--- a/web/gui/src/main/webapp/app/view/port/port.css
+++ b/web/gui/src/main/webapp/app/view/port/port.css
@@ -28,10 +28,20 @@
 #ov-port td {
     text-align: center;
 }
+
 #ov-port td.right {
     text-align: right;
 }
 
+#ov-port td.delta {
+    text-align: right;
+    font-weight: bold;
+}
+
+#ov-port td.delta:before {
+    content: "+";
+}
+
 #ov-port tr.no-data td {
     text-align: center;
 }
diff --git a/web/gui/src/main/webapp/app/view/port/port.html b/web/gui/src/main/webapp/app/view/port/port.html
index 8408718..5f077e0 100644
--- a/web/gui/src/main/webapp/app/view/port/port.html
+++ b/web/gui/src/main/webapp/app/view/port/port.html
@@ -14,6 +14,18 @@
 
             <div class="separator"></div>
 
+            <div class="refresh" ng-class="{active: isNZ()}"
+                 icon icon-size="42" icon-id="plus"
+                 tooltip tt-msg="toggleNZTip"
+                 ng-click="toggleNZ()"></div>
+
+            <div class="refresh" ng-class="{active: isDelta()}"
+                 icon icon-size="42" icon-id="triangleUp"
+                 tooltip tt-msg="toggleDeltaTip"
+                 ng-click="toggleDelta()"></div>
+
+            <div class="separator"></div>
+
             <div class="active"
                  icon icon-id="deviceTable" icon-size="42"
                  tooltip tt-msg="deviceTip"
@@ -82,13 +94,13 @@
                 <tr ng-repeat="port in tableData | filter:queryFilter track by $index"
                     ng-repeat-complete row-id="{{port.id}}">
                     <td>{{port.id}}</td>
-                    <td class="right">{{port.pkt_rx}}</td>
-                    <td class="right">{{port.pkt_tx}}</td>
-                    <td class="right">{{port.bytes_rx}}</td>
-                    <td class="right">{{port.bytes_tx}}</td>
-                    <td class="right">{{port.pkt_rx_drp}}</td>
-                    <td class="right">{{port.pkt_tx_drp}}</td>
-                    <td class="right">{{port.duration}}</td>
+                    <td ng-class="(isDelta() ? 'delta' : 'right')">{{port.pkt_rx}}</td>
+                    <td ng-class="(isDelta() ? 'delta' : 'right')">{{port.pkt_tx}}</td>
+                    <td ng-class="(isDelta() ? 'delta' : 'right')">{{port.bytes_rx}}</td>
+                    <td ng-class="(isDelta() ? 'delta' : 'right')">{{port.bytes_tx}}</td>
+                    <td ng-class="(isDelta() ? 'delta' : 'right')">{{port.pkt_rx_drp}}</td>
+                    <td ng-class="(isDelta() ? 'delta' : 'right')">{{port.pkt_tx_drp}}</td>
+                    <td ng-class="(isDelta() ? 'delta' : 'right')">{{port.duration}}</td>
                 </tr>
             </table>
         </div>
diff --git a/web/gui/src/main/webapp/app/view/port/port.js b/web/gui/src/main/webapp/app/view/port/port.js
index 6d6645a..5453b78 100644
--- a/web/gui/src/main/webapp/app/view/port/port.js
+++ b/web/gui/src/main/webapp/app/view/port/port.js
@@ -22,33 +22,79 @@
     'use strict';
 
     // injected references
-    var $log, $scope, $location, fs, tbs, ns;
+    var $log, $scope, $location, fs, tbs, wss, ns, ps;
+
+    var nz = 'nzFilter',
+        del = 'showDelta';
 
     // internal state
     var nzFilter = true,
         showDelta = false;
 
-    // TODO: (1) init nzFilter and showDelta from user preferences service
-    // TODO: (2) track nzFilter and showDelta state from toggle buttons
-    //             (also setting new state in user preference service)
+    var defaultPortPrefsState = {
+        nzFilter :  1,
+        showDelta : 0,
+    };
+
+    var prefsState = {};
+
+    function updatePrefsState(what, b) {
+        prefsState[what] = b ? 1 : 0;
+        ps.setPrefs('port_prefs', prefsState);
+    }
+
+    function toggleNZState(b) {
+        if (b === undefined) {
+            nzFilter = !nzFilter;
+        } else {
+            nzFilter = b;
+        }
+        updatePrefsState(nz, nzFilter);
+    }
+
+    function toggleDeltaState(b) {
+        if (b === undefined) {
+            showDelta = !showDelta;
+        } else {
+            showDelta = b;
+        }
+        updatePrefsState(del, b);
+    }
+
+    function restoreConfigFromPrefs() {
+        prefsState = ps.asNumbers(
+            ps.getPrefs('port_prefs', defaultPortPrefsState)
+        );
+
+        $log.debug('Port - Prefs State:', prefsState);
+        toggleDeltaState(prefsState.showDelta);
+        toggleNZState(prefsState.nzFilter);
+    }
 
     angular.module('ovPort', [])
     .controller('OvPortCtrl',
         ['$log', '$scope', '$location',
-            'FnService', 'TableBuilderService', 'NavService',
+            'FnService', 'TableBuilderService', 'WebSocketService', 'NavService',
+            'PrefsService',
 
-        function (_$log_, _$scope_, _$location_, _fs_, _tbs_, _ns_) {
+        function (_$log_, _$scope_, _$location_, _fs_, _tbs_, _wss_, _ns_, _ps_) {
             var params;
+            var tableApi;
             $log = _$log_;
             $scope = _$scope_;
             $location = _$location_;
             fs = _fs_;
             tbs = _tbs_;
+            wss = _wss_;
             ns = _ns_;
+            ps = _ps_;
+
             $scope.deviceTip = 'Show device table';
             $scope.flowTip = 'Show flow view for this device';
             $scope.groupTip = 'Show group view for this device';
             $scope.meterTip = 'Show meter view for selected device';
+            $scope.toggleDeltaTip = 'Toggle port delta statistics';
+            $scope.toggleNZTip = 'Toggle non zero port statistics';
 
             params = $location.search();
             if (params.hasOwnProperty('devId')) {
@@ -60,18 +106,45 @@
                 showDelta: showDelta
             };
 
-            tbs.buildTable({
+            tableApi = tbs.buildTable({
                 scope: $scope,
                 tag: 'port',
                 query: params
             });
 
+            function filterToggleState() {
+                return {
+                    nzFilter: nzFilter,
+                    showDelta: showDelta
+                };
+            }
+
             $scope.nav = function (path) {
                 if ($scope.devId) {
                     ns.navTo(path, { devId: $scope.devId });
                 }
             };
 
+            $scope.toggleNZ = function () {
+                toggleNZState();
+                $scope.payloadParams = filterToggleState();
+                tableApi.forceRefesh();
+            };
+
+            $scope.toggleDelta = function () {
+                toggleDeltaState();
+                $scope.payloadParams = filterToggleState();
+                tableApi.forceRefesh();
+            };
+
+            $scope.isDelta = function() {
+                return showDelta;
+            };
+
+            $scope.isNZ = function() {
+                return nzFilter;
+            };
+
              Object.defineProperty($scope, "queryFilter", {
                  get: function() {
                      var out = {};
@@ -80,6 +153,7 @@
                  }
              });
 
+            restoreConfigFromPrefs();
             $log.log('OvPortCtrl has been created');
         }]);
 }());