Server device driver extensions

 * Additional behaviours implemented
    * BasicSystemOperations
    * DeviceHandshaker
    * InterfaceConfig
    * PortAdmin
    * QueueConfig
    * TableStatisticsDiscovery
    * DeviceSystemStatisticsQuery
 * New device abstractions on CPU cache and main memory
 * Additional statistics (main memory)
 * New UI with Memory statistics (based on the old gui)
 * Constants decoupled from implementations
 * More builders used for interface implementations
 * Style fixes and refactoring

Change-Id: Ie54ed0fb4760456cfd6339c74b36486dd3c20f87
Signed-off-by: Georgios Katsikas <katsikas.gp@gmail.com>
(cherry picked from commit 740d3281b09f2517c32a302cf12e16e3d98830fe)
diff --git a/drivers/server/src/main/resources/app/view/memory/memory.css b/drivers/server/src/main/resources/app/view/memory/memory.css
new file mode 100644
index 0000000..243f3e5
--- /dev/null
+++ b/drivers/server/src/main/resources/app/view/memory/memory.css
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Memory UI -- CSS file
+ */
+
+#ov-memory {
+    padding: 20px;
+    position: relative;
+}
+
+.light #ov-memory {
+    color: navy;
+}
+.dark #ov-memory {
+    color: #88f;
+}
+
+#ov-memory .button-panel {
+    margin: 10px;
+    width: 200px;
+}
+
+.light #ov-memory .button-panel {
+    background-color: #ccf;
+}
+.dark #ov-memory .button-panel {
+    background-color: #444;
+}
+
+#ov-memory #chart-loader {
+    position: absolute;
+    width: 200px;
+    height: 50px;
+    margin-left: -100px;
+    margin-top: -25px;
+    z-index: 900;
+    top: 50%;
+    text-align: center;
+    left: 50%;
+    font-size: 25px;
+    font-weight: bold;
+    color: #ccc;
+}
\ No newline at end of file
diff --git a/drivers/server/src/main/resources/app/view/memory/memory.html b/drivers/server/src/main/resources/app/view/memory/memory.html
new file mode 100644
index 0000000..398a9fa
--- /dev/null
+++ b/drivers/server/src/main/resources/app/view/memory/memory.html
@@ -0,0 +1,27 @@
+<!-- partial HTML -->
+<div id="ov-memory">
+    <div id="chart-loader" ng-show="!devId && showLoader">
+        No Servers
+    </div>
+    <div ng-show="!devId">
+        <canvas id="bar" class="chart chart-bar" chart-data="data"
+                chart-labels="labels" chart-legend="true" chart-click="onClick"
+                chart-series="series" chart-options="options" height="100%">
+        </canvas>
+    </div>
+    <div ng-show="devId">
+        <h2>
+            Chart for Device {{devId || "(No device selected)"}}
+        </h2>
+        <div class="ctrl-btns">
+            <select ng-options="deviceId as deviceId for deviceId in deviceIds"
+                    ng-model="selectedItem" ng-change="onChange(selectedItem)">
+                <option value="">-- select a device --</option>
+            </select>
+        </div>
+        <canvas id="line" class="chart chart-line" chart-data="data"
+                chart-labels="labels" chart-legend="true"
+                chart-series="series" chart-options="options" height="100%">
+        </canvas>
+    </div>
+</div>
diff --git a/drivers/server/src/main/resources/app/view/memory/memory.js b/drivers/server/src/main/resources/app/view/memory/memory.js
new file mode 100644
index 0000000..37c2eee
--- /dev/null
+++ b/drivers/server/src/main/resources/app/view/memory/memory.js
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Memory View Module
+ */
+(function () {
+    'use strict';
+
+    // injected references
+    var $log, $scope, $location, ks, fs, cbs, ns;
+
+    var hasDeviceId;
+    var barsNb = 3;
+
+    var labels = new Array(1);
+    var data = new Array(barsNb);
+    for (var i = 0; i < barsNb; i++) {
+        data[i] = new Array(1);
+        data[i][0] = 0;
+    }
+
+    angular.module('ovMemory', ["chart.js"])
+        .controller('OvMemoryCtrl',
+        ['$log', '$scope', '$location', 'FnService', 'ChartBuilderService', 'NavService',
+
+        function (_$log_, _$scope_, _$location_, _fs_, _cbs_, _ns_) {
+            var params;
+            $log = _$log_;
+            $scope = _$scope_;
+            $location = _$location_;
+            fs = _fs_;
+            cbs = _cbs_;
+            ns = _ns_;
+
+            params = $location.search();
+
+            if (params.hasOwnProperty('devId')) {
+                $scope.devId = params['devId'];
+                hasDeviceId = true;
+            } else {
+                hasDeviceId = false;
+            }
+
+            cbs.buildChart({
+                scope: $scope,
+                tag: 'memory',
+                query: params
+            });
+
+            $scope.$watch('chartData', function () {
+                if (!fs.isEmptyObject($scope.chartData)) {
+                    $scope.showLoader = false;
+                    var length = $scope.chartData.length;
+                    labels = new Array(length);
+                    for (var i = 0; i < barsNb; i++) {
+                        data[i] = new Array(length);
+                    }
+
+                    $scope.chartData.forEach(
+                        function (cm, idx) {
+                            data[0][idx]  = cm.memory_used;
+                            data[1][idx]  = cm.memory_free;
+                            data[2][idx]  = cm.memory_total;
+
+                            labels[idx] = cm.label;
+                        }
+                    );
+                }
+
+                $scope.labels = labels;
+                $scope.data = data;
+
+                $scope.options = {
+                    scales: {
+                        yAxes: [{
+                            type: 'linear',
+                            position: 'left',
+                            id: 'y-axis-memory',
+                            ticks: {
+                                beginAtZero: true,
+                                fontSize: 28,
+                            },
+                            scaleLabel: {
+                                display: true,
+                                labelString: 'Memory Utilization (GBytes)',
+                                fontSize: 28,
+                            }
+                        }],
+                        xAxes: [{
+                            id: 'x-axis-servers',
+                            ticks: {
+                                fontSize: 28,
+                            },
+                            scaleLabel: {
+                                display: false,
+                                fontSize: 28,
+                            }
+                        }]
+                    }
+                };
+
+                $scope.onClick = function (points, evt) {
+                    var label = labels[points[0]._index];
+                    if (label) {
+                        ns.navTo('memory', { devId: label });
+                        $log.log(label);
+                    }
+                };
+
+                if (!fs.isEmptyObject($scope.annots)) {
+                    $scope.deviceIds = JSON.parse($scope.annots.deviceIds);
+                }
+
+                $scope.onChange = function (deviceId) {
+                    ns.navTo('memory', { devId: deviceId });
+                };
+            });
+
+            $scope.series = new Array(barsNb);
+            $scope.series[0] = 'Memory - Used';
+            $scope.series[1] = 'Memory - Free';
+            $scope.series[2] = 'Memory - Total';
+
+            $scope.labels = labels;
+            $scope.data = data;
+
+            $scope.showLoader = true;
+
+            $log.log('OvMemoryCtrl has been created');
+        }]);
+
+}());
diff --git a/drivers/server/src/main/resources/gui/css.html b/drivers/server/src/main/resources/gui/css.html
index 8eca7d4..b1cf4e5 100644
--- a/drivers/server/src/main/resources/gui/css.html
+++ b/drivers/server/src/main/resources/gui/css.html
@@ -1,3 +1,4 @@
 <link rel="stylesheet" href="app/view/cpu/cpu.css">
+<link rel="stylesheet" href="app/view/memory/memory.css">
 <link rel="stylesheet" href="app/view/latency/latency.css">
 <link rel="stylesheet" href="app/view/throughput/throughput.css">
diff --git a/drivers/server/src/main/resources/gui/js.html b/drivers/server/src/main/resources/gui/js.html
index 99a84e8..94ec76b 100644
--- a/drivers/server/src/main/resources/gui/js.html
+++ b/drivers/server/src/main/resources/gui/js.html
@@ -1,3 +1,4 @@
 <script src="app/view/cpu/cpu.js"></script>
+<script src="app/view/memory/memory.js"></script>
 <script src="app/view/latency/latency.js"></script>
 <script src="app/view/throughput/throughput.js"></script>
diff --git a/drivers/server/src/main/resources/server-drivers.xml b/drivers/server/src/main/resources/server-drivers.xml
index 11c75d1..a8a07cd 100644
--- a/drivers/server/src/main/resources/server-drivers.xml
+++ b/drivers/server/src/main/resources/server-drivers.xml
@@ -15,7 +15,13 @@
   ~ limitations under the License.
   -->
 <drivers>
-    <driver name="restServer" extends="default" manufacturer="GenuineIntel" hwVersion="Intel(R) Xeon(R) CPU E5-2667 v3 @ 3.20GHz" swVersion="Click 2.1">
+    <driver name="rest-server" manufacturer="Unknown" hwVersion="Unknown" swVersion="Unknown" extends="default">
+        <behaviour api="org.onosproject.net.behaviour.BasicSystemOperations"
+                   impl="org.onosproject.drivers.server.ServerBasicSystemOperations"/>
+
+        <behaviour api="org.onosproject.net.device.DeviceHandshaker"
+                   impl="org.onosproject.drivers.server.ServerHandshaker"/>
+
         <behaviour api="org.onosproject.net.behaviour.DevicesDiscovery"
                    impl="org.onosproject.drivers.server.ServerDevicesDiscovery"/>
 
@@ -28,16 +34,38 @@
         <behaviour api="org.onosproject.net.device.PortStatisticsDiscovery"
                    impl="org.onosproject.drivers.server.ServerDevicesDiscovery"/>
 
+        <behaviour api="org.onosproject.net.behaviour.PortAdmin"
+                   impl="org.onosproject.drivers.server.ServerPortAdmin"/>
+
+        <behaviour api="org.onosproject.net.behaviour.InterfaceConfig"
+                   impl="org.onosproject.drivers.server.ServerInterfaceConfig"/>
+
         <behaviour api="org.onosproject.drivers.server.behavior.CpuStatisticsDiscovery"
                    impl="org.onosproject.drivers.server.ServerDevicesDiscovery"/>
 
         <behaviour api="org.onosproject.drivers.server.behavior.MonitoringStatisticsDiscovery"
                    impl="org.onosproject.drivers.server.ServerDevicesDiscovery"/>
 
+        <behaviour api="org.onosproject.net.behaviour.DeviceSystemStatisticsQuery"
+                   impl="org.onosproject.drivers.server.ServerDevicesDiscovery"/>
+
         <behaviour api="org.onosproject.net.flow.FlowRuleProgrammable"
                    impl="org.onosproject.drivers.server.FlowRuleProgrammableServerImpl"/>
+
+        <behaviour api="org.onosproject.net.behaviour.TableStatisticsDiscovery"
+                   impl="org.onosproject.drivers.server.ServerTableStatisticsDiscovery"/>
+
+        <behaviour api="org.onosproject.net.behaviour.QueueConfigBehaviour"
+                   impl="org.onosproject.drivers.server.ServerQueueConfig"/>
+
         <property name="ruleDeleteBatchSize">500</property>
     </driver>
+
+    <driver name="rest-server-intel" manufacturer="GenuineIntel" hwVersion="Unknown" swVersion="Click 2.1" extends="rest-server">
+    </driver>
+
+    <driver name="rest-server-amd" manufacturer="AuthenticAMD" hwVersion="Unknown" swVersion="Click 2.1" extends="rest-server">
+    </driver>
 </drivers>