New SB driver for commodity servers

Monitoring enhanced with timing stats

Copy constructors for Rx filter values

Driver is updated to provide port statistics to the REST SB controller

Drastic changes to make the driver ONOS compliant. NIC statistics have become 100% compliant with PortStatistics

CPU statistics also compatible with the ONOS approach

Separated timing statistics

Style fix

NIC is included

Proper representation of a CPU. Also some refactoring

Removed unused import and added important comment

CPU vendor has become a class and the servers are now reporting more detailed CPU info

Fixed port statistics' counters for servers

Various fixes that lead to more stable behavior

Additional checks to avoid null pointer exception

Fixed potential casting issues

Updated pom with affiliation information

Updated pom with URL

Bumped rivers to version 1.12

Updated BUCK for version 1.12

NIC speed has become long and NICs are retrieved in a sorted fashion

Fixed warning

Timing statistics contain autoscale measurements

Fixed CPU vendor ID for Intel

Bumped Metron's drivers to version 1.13. Fixed origin and URL in pom.xml

Updated RestServerSBDevice to comply with the extended ONOS RestSBDevice

Total refactoring of the driver to become more generic (NFV -> Server).
Also properly separated the statistics API from implementation.

Refactored server driver and bug fix that occured when port statistics
were called before a device is properly discovered.
Statistics API and implementation are grouped again.

Removed unnecessary stuff from pom and BUCK files

Fixed checkstyle warning

Added short readme to pom.xml

New ControllerConfig behavior added

This patch adds an new ControllerConfig behavior to the server
driver, allowing external applications to get, set, and remove
a server's controller configuration.
Common functions and variables are also shared between the
two basic modules of the driver.

Fixed checkstyle warnings

Refactored controller configuration module

Consistent values returned by the methods of the driver

Unit tests for ServerControllerConfig behavior

Fixed preconditions for NULL and arguments

Improved documentation

Updated pom and BUCK

Addressed comments about sharing some more methods

Refactored the Common.java to become a base class
that extends AbstractHandlerBehaviour and can share
a unique instance of the RestSBController with child
classes. Also, after the removal of some deprecated
methods of the HTTP SB controller, I had to perform
some compatibility changes in the respective methods
of this driver.
The only problem is that my tests are now broken(??)
and I had to remove their code for now until I fix
the issues.

Expose some members and methods of BasicDriver

Renamed BasicDriver to BasicServerDriver

Change-Id: I0126adcb714f7e32695d546cf40a9de342722083
Signed-off-by: Georgios Katsikas <katsikas.gp@gmail.com>
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultCpuDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultCpuDevice.java
new file mode 100644
index 0000000..79712fc
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultCpuDevice.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2017-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.
+ */
+
+package org.onosproject.drivers.server.impl.devices;
+
+import org.onosproject.drivers.server.devices.CpuDevice;
+import org.onosproject.drivers.server.devices.CpuVendor;
+
+import org.onosproject.drivers.server.impl.stats.DefaultCpuStatistics;
+
+import com.google.common.base.MoreObjects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.util.Objects;
+
+/**
+ * Default implementation for CPU core devices.
+ */
+public class DefaultCpuDevice implements CpuDevice {
+
+    private final int       id;
+    private final CpuVendor vendor;
+    private final long      frequency;
+
+    // Maximum CPU core frequency in MHz
+    public static final long MAX_FREQUENCY_MHZ = 4500;
+
+    public DefaultCpuDevice(int id, CpuVendor vendor, long frequency) {
+        checkArgument(
+            (id >= 0) && (id < DefaultCpuStatistics.MAX_CPU_NB),
+            "CPU core ID must be in [0, " +
+            String.valueOf(DefaultCpuStatistics.MAX_CPU_NB - 1) + "]"
+        );
+        checkNotNull(
+            vendor,
+            "CPU core vendor cannot be null"
+        );
+        checkArgument(
+            (frequency > 0) && (frequency <= MAX_FREQUENCY_MHZ),
+            "CPU core frequency (MHz) must be positive and less or equal than " +
+            MAX_FREQUENCY_MHZ + " MHz"
+        );
+
+        this.id        = id;
+        this.vendor    = vendor;
+        this.frequency = frequency;
+    }
+
+    @Override
+    public int id() {
+        return this.id;
+    }
+
+    @Override
+    public CpuVendor vendor() {
+        return this.vendor;
+    }
+
+    @Override
+    public long frequency() {
+        return this.frequency;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .omitNullValues()
+                .add("id",        id())
+                .add("vendor",    vendor())
+                .add("frequency", frequency())
+                .toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof CpuDevice)) {
+            return false;
+        }
+        CpuDevice device = (CpuDevice) obj;
+        return  this.id() ==  device.id() &&
+                this.vendor() == device.vendor() &&
+                this.frequency() == device.frequency();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, vendor, frequency);
+    }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultNicDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultNicDevice.java
new file mode 100644
index 0000000..d69ff23
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultNicDevice.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2017-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.
+ */
+
+package org.onosproject.drivers.server.impl.devices;
+
+import org.onosproject.drivers.server.devices.NicDevice;
+import org.onosproject.drivers.server.devices.NicRxFilter;
+
+import org.onlab.packet.MacAddress;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+import static org.onosproject.net.Port.Type;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Default implementation for NIC devices.
+ */
+public class DefaultNicDevice implements NicDevice, Comparable {
+
+    private final String     id;
+    private final int        port;
+    private final long       speed;
+    private final Type       portType;
+    private boolean          status;
+    private final MacAddress macAddress;
+    private NicRxFilter      rxFilterMechanisms;
+
+    // 200 Gbps or 200.000 Mbps
+    public static final long MAX_SPEED = 200000;
+
+    public DefaultNicDevice(
+            String      id,
+            int         port,
+            Type        portType,
+            long        speed,
+            boolean     status,
+            String      macStr,
+            NicRxFilter rxFilterMechanisms) {
+        checkNotNull(id, "NIC ID cannot be null");
+        checkArgument(!id.isEmpty(), "NIC ID cannot be empty");
+        checkArgument(port >= 0, "NIC port number must be non-negative");
+        checkNotNull(portType, "NIC port type cannot be null");
+        checkArgument(
+            (speed >= 0) && (speed <= MAX_SPEED),
+            "NIC speed must be positive and less or equal than " + MAX_SPEED + " Mbps"
+        );
+        checkNotNull(macStr, "NIC MAC address cannot be null");
+        checkNotNull(rxFilterMechanisms, "NIC Rx filter mechanisms cannot be null");
+
+        // Implies a problem
+        if (speed == 0) {
+            status = false;
+        }
+
+        this.id         = id;
+        this.port       = port;
+        this.speed      = speed;
+        this.portType   = portType;
+        this.status     = status;
+        this.macAddress = MacAddress.valueOf(macStr);
+        this.rxFilterMechanisms  = rxFilterMechanisms;
+    }
+
+    @Override
+    public String id() {
+        return this.id;
+    }
+
+    @Override
+    public int port() {
+        return this.port;
+    }
+
+    @Override
+    public Type portType() {
+        return this.portType;
+    }
+
+    @Override
+    public long speed() {
+        return this.speed;
+    }
+
+    @Override
+    public boolean status() {
+        return this.status;
+    }
+
+    @Override
+    public void setStatus(boolean status) {
+        this.status = status;
+    }
+
+    @Override
+    public MacAddress macAddress() {
+        return this.macAddress;
+    }
+
+    @Override
+    public NicRxFilter rxFilterMechanisms() {
+        return this.rxFilterMechanisms;
+    }
+
+    @Override
+    public void setRxFilterMechanisms(NicRxFilter rxFilterMechanisms) {
+        checkNotNull(rxFilterMechanisms, "NIC Rx filter mechanisms cannot be null");
+        this.rxFilterMechanisms = rxFilterMechanisms;
+    }
+
+    @Override
+    public void addRxFilterMechanism(NicRxFilter.RxFilter rxFilter) {
+        this.rxFilterMechanisms.addRxFilter(rxFilter);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .omitNullValues()
+                .add("id",        id())
+                .add("port",      port())
+                .add("mac",       macAddress.toString())
+                .add("portType",  portType())
+                .add("speed",     speed())
+                .add("status",    status ? "active" : "inactive")
+                .add("rxFilters", rxFilterMechanisms())
+                .toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof NicDevice)) {
+            return false;
+        }
+        NicDevice device = (NicDevice) obj;
+        return  this.id().equals(device.id()) &&
+                this.port() ==  device.port() &&
+                this.speed  == device.speed() &&
+                this.macAddress.equals(device.macAddress());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, port, speed, macAddress);
+    }
+
+    @Override
+    public int compareTo(Object other) {
+        if (this == other) {
+            return 0;
+        }
+
+        if (other == null) {
+            return -1;
+        }
+
+        if (other instanceof NicDevice) {
+            NicDevice otherNic = (NicDevice) other;
+
+            if (this.port() == otherNic.port()) {
+                return 0;
+            } else if (this.port() > otherNic.port()) {
+                return 1;
+            } else {
+                return -1;
+            }
+        }
+
+        return -1;
+    }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultRestServerSBDevice.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultRestServerSBDevice.java
new file mode 100644
index 0000000..7232ed5
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultRestServerSBDevice.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2017-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.
+ */
+
+package org.onosproject.drivers.server.impl.devices;
+
+import org.onosproject.drivers.server.devices.CpuDevice;
+import org.onosproject.drivers.server.devices.NicDevice;
+import org.onosproject.drivers.server.devices.RestServerSBDevice;
+
+import org.onosproject.protocol.rest.DefaultRestSBDevice;
+import org.onosproject.protocol.rest.RestSBDevice.AuthenticationScheme;
+import org.onlab.packet.IpAddress;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Lists;
+
+import java.util.Objects;
+import java.util.Collection;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Default implementation for REST server devices.
+ */
+public class DefaultRestServerSBDevice
+        extends DefaultRestSBDevice implements RestServerSBDevice {
+
+    private Collection<CpuDevice> cpus = Lists.newArrayList();
+    private Collection<NicDevice> nics = Lists.newArrayList();
+
+    public DefaultRestServerSBDevice(
+            IpAddress ip, int port, String name, String password,
+            String protocol, String url, boolean isActive,
+            Collection<CpuDevice> cpus, Collection<NicDevice> nics) {
+        this(
+            ip, port, name, password, protocol, url, isActive,
+            "", "", "", "", AuthenticationScheme.BASIC, "", cpus, nics
+        );
+    }
+
+    public DefaultRestServerSBDevice(
+            IpAddress ip, int port, String name, String password,
+            String protocol, String url, boolean isActive, String testUrl,
+            String manufacturer, String hwVersion, String swVersion,
+            AuthenticationScheme authenticationScheme, String token,
+            Collection<CpuDevice> cpus, Collection<NicDevice> nics) {
+        super(
+            ip, port, name, password, protocol, url, isActive,
+            testUrl, manufacturer, hwVersion, swVersion,
+            authenticationScheme, token
+        );
+
+        checkNotNull(cpus, "Device's set of CPUs cannot be null");
+        checkNotNull(nics, "Device's set of NICs cannot be null");
+
+        this.cpus = cpus;
+        this.nics = nics;
+    }
+
+    @Override
+    public Collection<CpuDevice> cpus() {
+        return this.cpus;
+    }
+
+    @Override
+    public int numberOfCpus() {
+        return this.cpus.size();
+    }
+
+    @Override
+    public Collection<NicDevice> nics() {
+        return this.nics;
+    }
+
+    @Override
+    public int numberOfNics() {
+        return this.nics.size();
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .omitNullValues()
+                .add("url", url())
+                .add("testUrl", testUrl())
+                .add("protocol", protocol())
+                .add("username", username())
+                .add("port", port())
+                .add("ip", ip())
+                .add("manufacturer", manufacturer().orElse(null))
+                .add("hwVersion", hwVersion().orElse(null))
+                .add("swVersion", swVersion().orElse(null))
+                .add("cpus", cpus())
+                .add("nics", nics())
+                .toString();
+
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (!(obj instanceof RestServerSBDevice)) {
+            return false;
+        }
+        RestServerSBDevice device = (RestServerSBDevice) obj;
+
+        return  this.username().equals(device.username()) &&
+                this.ip().equals(device.ip()) &&
+                this.port() == device.port();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ip(), port(), cpus(), nics());
+    }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultServerDeviceDescription.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultServerDeviceDescription.java
new file mode 100644
index 0000000..50aeb02
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/DefaultServerDeviceDescription.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2014-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.
+ */
+
+package org.onosproject.drivers.server.impl.devices;
+
+import org.onosproject.drivers.server.devices.CpuDevice;
+import org.onosproject.drivers.server.devices.NicDevice;
+import org.onosproject.drivers.server.devices.ServerDeviceDescription;
+
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.SparseAnnotations;
+import org.onlab.packet.ChassisId;
+
+import com.google.common.base.Objects;
+
+import java.net.URI;
+import java.util.Collection;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.Device.Type;
+
+/**
+ * Default implementation of immutable server device description entity.
+ */
+public class DefaultServerDeviceDescription extends DefaultDeviceDescription
+        implements ServerDeviceDescription {
+
+    private final Collection<CpuDevice> cpus;
+    private final Collection<NicDevice> nics;
+
+    /**
+     * Creates a server device description using the supplied information.
+     *
+     * @param uri          device URI
+     * @param type         device type
+     * @param manufacturer device manufacturer
+     * @param hwVersion    device HW version
+     * @param swVersion    device SW version
+     * @param serialNumber device serial number
+     * @param chassis      chassis id
+     * @param cpus         set of CPUs
+     * @param nics         set of network interface cards (NICs)
+     * @param annotations  optional key/value annotations map
+     */
+    public DefaultServerDeviceDescription(
+            URI uri, Type type, String manufacturer,
+            String hwVersion, String swVersion,
+            String serialNumber, ChassisId chassis,
+            Collection<CpuDevice> cpus, Collection<NicDevice> nics,
+            SparseAnnotations... annotations) {
+        this(uri, type, manufacturer, hwVersion, swVersion, serialNumber,
+             chassis, true, cpus, nics, annotations);
+    }
+
+    /**
+     * Creates a server device description using the supplied information.
+     *
+     * @param uri              device URI
+     * @param type             device type
+     * @param manufacturer     device manufacturer
+     * @param hwVersion        device HW version
+     * @param swVersion        device SW version
+     * @param serialNumber     device serial number
+     * @param chassis          chassis id
+     * @param cpus             set of CPUs
+     * @param nics             set of network interface cards (NICs)
+     * @param defaultAvailable optional whether device is by default available
+     * @param annotations      optional key/value annotations map
+     */
+    public DefaultServerDeviceDescription(
+            URI uri, Type type, String manufacturer,
+            String hwVersion, String swVersion,
+            String serialNumber, ChassisId chassis,
+            boolean defaultAvailable,
+            Collection<CpuDevice> cpus, Collection<NicDevice> nics,
+            SparseAnnotations... annotations) {
+        super(
+            uri, type, manufacturer, hwVersion, swVersion,
+            serialNumber, chassis, defaultAvailable, annotations
+        );
+
+        checkNotNull(cpus, "Device's set of CPUs cannot be null");
+        checkNotNull(nics, "Device's set of NICs cannot be null");
+
+        this.cpus = cpus;
+        this.nics = nics;
+    }
+
+    /**
+     * Creates a server device description using the supplied information.
+     * @param base ServerDeviceDescription to basic information
+     * @param annotations Annotations to use.
+     */
+    public DefaultServerDeviceDescription(ServerDeviceDescription base,
+                                    SparseAnnotations... annotations) {
+        this(base.deviceUri(), base.type(), base.manufacturer(),
+             base.hwVersion(), base.swVersion(), base.serialNumber(),
+             base.chassisId(), base.isDefaultAvailable(),
+             base.cpus(), base.nics(),
+             annotations);
+    }
+
+    /**
+     * Creates a device description using the supplied information.
+     * @param base ServerDeviceDescription to basic information (except for type)
+     * @param type device type
+     * @param annotations Annotations to use.
+     */
+    public DefaultServerDeviceDescription(
+            ServerDeviceDescription base, Type type,
+            SparseAnnotations... annotations) {
+        this(base.deviceUri(), type, base.manufacturer(),
+             base.hwVersion(), base.swVersion(), base.serialNumber(),
+             base.chassisId(), base.isDefaultAvailable(),
+             base.cpus(), base.nics(),
+             annotations);
+    }
+
+    /**
+     * Creates a device description using the supplied information.
+     *
+     * @param base ServerDeviceDescription to basic information (except for defaultAvailable)
+     * @param defaultAvailable whether device should be made available by default
+     * @param annotations Annotations to use.
+     */
+    public DefaultServerDeviceDescription(
+            ServerDeviceDescription base,
+            boolean defaultAvailable,
+            SparseAnnotations... annotations) {
+        this(base.deviceUri(), base.type(), base.manufacturer(),
+             base.hwVersion(), base.swVersion(), base.serialNumber(),
+             base.chassisId(), defaultAvailable,
+             base.cpus(), base.nics(),
+             annotations);
+    }
+
+    @Override
+    public Collection<CpuDevice> cpus() {
+        return this.cpus;
+    }
+
+    @Override
+    public Collection<NicDevice> nics() {
+        return this.nics;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("uri",          deviceUri())
+                .add("type",         type())
+                .add("manufacturer", manufacturer())
+                .add("hwVersion",    hwVersion())
+                .add("swVersion",    swVersion())
+                .add("serial",       serialNumber())
+                .add("cpus",         cpus)
+                .add("nics",         nics)
+                .add("annotations",  annotations())
+                .toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(super.hashCode(), cpus, nics);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (object instanceof DefaultServerDeviceDescription) {
+            if (!super.equals(object)) {
+                return false;
+            }
+            DefaultServerDeviceDescription that = (DefaultServerDeviceDescription) object;
+            return Objects.equal(this.deviceUri(),          that.deviceUri())
+                && Objects.equal(this.type(),               that.type())
+                && Objects.equal(this.manufacturer(),       that.manufacturer())
+                && Objects.equal(this.hwVersion(),          that.hwVersion())
+                && Objects.equal(this.swVersion(),          that.swVersion())
+                && Objects.equal(this.serialNumber(),       that.serialNumber())
+                && Objects.equal(this.chassisId(),          that.chassisId())
+                && Objects.equal(this.cpus(),               that.cpus())
+                && Objects.equal(this.nics(),               that.nics())
+                && Objects.equal(this.isDefaultAvailable(), that.isDefaultAvailable());
+        }
+        return false;
+    }
+
+    // Default constructor for serialization
+    DefaultServerDeviceDescription() {
+        super(null, null, null, null, null, null, null, (SparseAnnotations[]) null);
+        this.cpus = null;
+        this.nics = null;
+    }
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/package-info.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/package-info.java
new file mode 100644
index 0000000..c0ba64b
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/devices/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Implementation of server devices.
+ */
+package org.onosproject.drivers.server.impl.devices;
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/package-info.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/package-info.java
new file mode 100644
index 0000000..26be5bf
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Implementation of server device drivers.
+ */
+package org.onosproject.drivers.server.impl;
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
new file mode 100644
index 0000000..43b7273
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2017-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.
+ */
+
+package org.onosproject.drivers.server.impl.stats;
+
+import org.onosproject.drivers.server.stats.CpuStatistics;
+
+import org.onosproject.net.DeviceId;
+import com.google.common.base.MoreObjects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Default implementation for CPU statistics.
+ */
+public final class DefaultCpuStatistics implements CpuStatistics {
+
+    private static final float MIN_CPU_LOAD = (float) 0.0;
+    private static final float MAX_CPU_LOAD = (float) 1.0;
+
+    // Upper limit of CPU cores in one machine
+    public static final int MAX_CPU_NB = 512;
+
+    private final DeviceId deviceId;
+
+    private final int id;
+    private final float load;
+    private final boolean isBusy;
+
+    private DefaultCpuStatistics(
+            DeviceId deviceId,
+            int      id,
+            float    load,
+            boolean  isBusy) {
+        checkNotNull(deviceId, "Device ID is NULL");
+        checkArgument(
+            (id >= 0) && (id < MAX_CPU_NB),
+            "CPU core ID must be in [0, " + String.valueOf(MAX_CPU_NB - 1) + "]"
+        );
+        checkArgument(
+            (load >= MIN_CPU_LOAD) && (load <= MAX_CPU_LOAD),
+            "CPU load must be in [" + MIN_CPU_LOAD + ", " + MAX_CPU_LOAD + "]"
+        );
+
+        this.deviceId = deviceId;
+        this.id       = id;
+        this.load     = load;
+        this.isBusy   = isBusy;
+    }
+
+    // Constructor for serializer
+    private DefaultCpuStatistics() {
+        this.deviceId = null;
+        this.id       = 0;
+        this.load     = 0;
+        this.isBusy   = false;
+    }
+
+    /**
+     * Creates a builder for DefaultCpuStatistics object.
+     *
+     * @return builder object for DefaultCpuStatistics object
+     */
+    public static DefaultCpuStatistics.Builder builder() {
+        return new Builder();
+    }
+
+    @Override
+    public int id() {
+        return this.id;
+    }
+
+    @Override
+    public float load() {
+        return this.load;
+    }
+
+    @Override
+    public boolean busy() {
+        return this.isBusy;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .omitNullValues()
+                .add("device", deviceId)
+                .add("id",     id())
+                .add("load",   load())
+                .add("isBusy", busy())
+                .toString();
+    }
+
+    public static final class Builder {
+
+        DeviceId deviceId;
+        int      id;
+        float    load;
+        boolean  isBusy;
+
+        private Builder() {
+
+        }
+
+        /**
+         * Sets the device identifier.
+         *
+         * @param deviceId device identifier
+         * @return builder object
+         */
+        public Builder setDeviceId(DeviceId deviceId) {
+            this.deviceId = deviceId;
+
+            return this;
+        }
+
+        /**
+         * Sets the CPU ID.
+         *
+         * @param id the CPU ID
+         * @return builder object
+         */
+        public Builder setId(int id) {
+            this.id = id;
+
+            return this;
+        }
+
+        /**
+         * Sets the CPU load.
+         *
+         * @param load CPU load
+         * @return builder object
+         */
+        public Builder setLoad(float load) {
+            this.load = load;
+
+            return this;
+        }
+
+        /**
+         * Sets the CPU status (free or busy).
+         *
+         * @param isBusy CPU status
+         * @return builder object
+         */
+        public Builder setIsBusy(boolean isBusy) {
+            this.isBusy = isBusy;
+
+            return this;
+        }
+
+        /**
+         * Creates a DefaultCpuStatistics object.
+         *
+         * @return DefaultCpuStatistics object
+         */
+        public DefaultCpuStatistics build() {
+            return new DefaultCpuStatistics(
+                deviceId,
+                id,
+                load,
+                isBusy
+            );
+        }
+    }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultMonitoringStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultMonitoringStatistics.java
new file mode 100644
index 0000000..5c1ba99
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultMonitoringStatistics.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2017-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.
+ */
+
+package org.onosproject.drivers.server.impl.stats;
+
+import org.onosproject.drivers.server.stats.CpuStatistics;
+import org.onosproject.drivers.server.stats.MonitoringStatistics;
+import org.onosproject.drivers.server.stats.TimingStatistics;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.PortStatistics;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Collection;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Default monitoring statistics for server devices.
+ * Includes CPU, NIC, and timing statistics.
+ */
+public final class DefaultMonitoringStatistics implements MonitoringStatistics {
+
+    private final DeviceId deviceId;
+
+    private final TimingStatistics           timingStatistics;
+    private final Collection<CpuStatistics>  cpuStatistics;
+    private final Collection<PortStatistics> nicStatistics;
+
+    private DefaultMonitoringStatistics(
+            DeviceId                   deviceId,
+            TimingStatistics           timingStatistics,
+            Collection<CpuStatistics>  cpuStatistics,
+            Collection<PortStatistics> nicStatistics) {
+        checkNotNull(deviceId,         "Device ID is NULL");
+        checkNotNull(timingStatistics, "Timing statistics are NULL");
+        checkNotNull(cpuStatistics,    "CPU statistics are NULL");
+        checkNotNull(nicStatistics,    "NIC statistics are NULL");
+
+        this.deviceId         = deviceId;
+        this.timingStatistics = timingStatistics;
+        this.cpuStatistics    = cpuStatistics;
+        this.nicStatistics    = nicStatistics;
+    }
+
+    // Constructor for serializer
+    private DefaultMonitoringStatistics() {
+        this.deviceId         = null;
+        this.timingStatistics = null;
+        this.cpuStatistics    = null;
+        this.nicStatistics    = null;
+    }
+
+    /**
+     * Creates a builder for DefaultMonitoringStatistics object.
+     *
+     * @return builder object for DefaultMonitoringStatistics object
+     */
+    public static DefaultMonitoringStatistics.Builder builder() {
+        return new Builder();
+    }
+
+    @Override
+    public TimingStatistics timingStatistics() {
+        return this.timingStatistics;
+    }
+
+    @Override
+    public Collection<CpuStatistics> cpuStatisticsAll() {
+        return this.cpuStatistics;
+    }
+
+    @Override
+    public CpuStatistics cpuStatistics(int cpuId) {
+        checkArgument(
+            (cpuId >= 0) && (cpuId < DefaultCpuStatistics.MAX_CPU_NB),
+            "CPU core ID must be in [0, " +
+            String.valueOf(DefaultCpuStatistics.MAX_CPU_NB - 1) + "]"
+        );
+        for (CpuStatistics cs : this.cpuStatistics) {
+            if (cs.id() == cpuId) {
+                return cs;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Collection<PortStatistics> nicStatisticsAll() {
+        return this.nicStatistics;
+    }
+
+    @Override
+    public PortStatistics nicStatistics(int nicId) {
+        checkArgument(nicId >= 0, "NIC ID must be a non-negative integer");
+        for (PortStatistics ns : this.nicStatistics) {
+            if (ns.port() == nicId) {
+                return ns;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public int numberOfNics() {
+        return this.nicStatistics.size();
+    }
+
+    @Override
+    public int numberOfCpus() {
+        return this.cpuStatistics.size();
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .omitNullValues()
+                .add("timingStatistics", timingStatistics())
+                .add("cpuStatistics",    cpuStatisticsAll())
+                .add("nicStatistics",    nicStatisticsAll())
+                .toString();
+    }
+
+    public static final class Builder {
+
+        DeviceId                   deviceId;
+        TimingStatistics           timingStatistics;
+        Collection<CpuStatistics>  cpuStatistics;
+        Collection<PortStatistics> nicStatistics;
+
+        private Builder() {
+
+        }
+
+        /**
+         * Sets the device identifier.
+         *
+         * @param deviceId device identifier
+         * @return builder object
+         */
+        public Builder setDeviceId(DeviceId deviceId) {
+            this.deviceId = deviceId;
+
+            return this;
+        }
+
+        /**
+         * Sets timing statistics.
+         *
+         * @param timingStatistics timing statistics
+         * @return builder object
+         */
+        public Builder setTimingStatistics(TimingStatistics timingStatistics) {
+            this.timingStatistics = timingStatistics;
+
+            return this;
+        }
+
+        /**
+         * Sets CPU statistics.
+         *
+         * @param cpuStatistics CPU statistics
+         * @return builder object
+         */
+        public Builder setCpuStatistics(Collection<CpuStatistics> cpuStatistics) {
+            this.cpuStatistics = cpuStatistics;
+
+            return this;
+        }
+
+        /**
+         * Sets NIC statistics.
+         *
+         * @param nicStatistics NIC statistics
+         * @return builder object
+         */
+        public Builder setNicStatistics(Collection<PortStatistics> nicStatistics) {
+            this.nicStatistics = nicStatistics;
+
+            return this;
+        }
+
+        /**
+         * Creates a MonitoringStatistics object.
+         *
+         * @return DefaultMonitoringStatistics object
+         */
+        public DefaultMonitoringStatistics build() {
+            return new DefaultMonitoringStatistics(
+                deviceId,
+                timingStatistics,
+                cpuStatistics,
+                nicStatistics
+            );
+        }
+
+    }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java
new file mode 100644
index 0000000..8256c5f
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultTimingStatistics.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2017-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.
+ */
+
+package org.onosproject.drivers.server.impl.stats;
+
+import org.onosproject.drivers.server.stats.TimingStatistics;
+
+import com.google.common.base.MoreObjects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Default implementation for timing statistics.
+ */
+public final class DefaultTimingStatistics implements TimingStatistics {
+
+    private final long deployCommandParsingTime;
+    private final long deployCommandLaunchingTime;
+    private long autoscaleTime;
+
+    private DefaultTimingStatistics(
+            long parsingTime,
+            long launchingTime,
+            long autoscaleTime) {
+        checkArgument(parsingTime   >= 0, "Parsing time is negative");
+        checkArgument(launchingTime >= 0, "Launching time is negative");
+        checkArgument(autoscaleTime >= 0, "Autoscale time is negative");
+
+        this.deployCommandParsingTime   = parsingTime;
+        this.deployCommandLaunchingTime = launchingTime;
+        this.autoscaleTime = autoscaleTime;
+    }
+
+    // Constructor for serializer
+    private DefaultTimingStatistics() {
+        this.deployCommandParsingTime   = 0;
+        this.deployCommandLaunchingTime = 0;
+        this.autoscaleTime = 0;
+    }
+
+    /**
+     * Creates a builder for DefaultTimingStatistics object.
+     *
+     * @return builder object for DefaultTimingStatistics object
+     */
+    public static DefaultTimingStatistics.Builder builder() {
+        return new Builder();
+    }
+
+    @Override
+    public long deployCommandParsingTime() {
+        return this.deployCommandParsingTime;
+    }
+
+    @Override
+    public long deployCommandLaunchingTime() {
+        return this.deployCommandLaunchingTime;
+    }
+
+    @Override
+    public long totalDeploymentTime() {
+        return this.deployCommandParsingTime + this.deployCommandLaunchingTime;
+    }
+
+    @Override
+    public long autoscaleTime() {
+        return this.autoscaleTime;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .omitNullValues()
+                .add("parsing",   this.deployCommandParsingTime())
+                .add("launching", this.deployCommandLaunchingTime())
+                .add("total",     this.totalDeploymentTime())
+                .add("autoscale", this.autoscaleTime())
+                .toString();
+    }
+
+    public static final class Builder {
+
+        long deployCommandParsingTime;
+        long deployCommandLaunchingTime;
+        long autoscaleTime;
+
+        private Builder() {
+
+        }
+
+        /**
+         * Sets parsing time.
+         *
+         * @param parsingTime parsing time
+         * @return builder object
+         */
+        public Builder setParsingTime(long parsingTime) {
+            this.deployCommandParsingTime = parsingTime;
+
+            return this;
+        }
+
+        /**
+         * Sets launching time.
+         *
+         * @param launchingTime launching time
+         * @return builder object
+         */
+        public Builder setLaunchingTime(long launchingTime) {
+            this.deployCommandLaunchingTime = launchingTime;
+
+            return this;
+        }
+
+        /**
+         * Sets autoscale time.
+         *
+         * @param autoscaleTime time required to autoscale
+         * @return builder object
+         */
+        public Builder setAutoscaleTime(long autoscaleTime) {
+            this.autoscaleTime = autoscaleTime;
+
+            return this;
+        }
+
+        /**
+         * Creates a DefaultTimingStatistics object.
+         *
+         * @return DefaultTimingStatistics object
+         */
+        public DefaultTimingStatistics build() {
+            return new DefaultTimingStatistics(
+                deployCommandParsingTime,
+                deployCommandLaunchingTime,
+                autoscaleTime
+            );
+        }
+    }
+
+}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/package-info.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/package-info.java
new file mode 100644
index 0000000..92c0e7d
--- /dev/null
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-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.
+ */
+
+/**
+ * Implementation of server device statistics.
+ */
+package org.onosproject.drivers.server.impl.stats;