Augment metrics model to monitor more # of control metrics

Existing implementation only monitors OpenFlow messages.
This commit augments the metrics model in a way to monitor more
number of control metrics including
- CPU Load, total CPU time, sys CPU time, user CPU time, etc.
- Used memory percentage, free memory percentage
- Disk read/write bytes
- Network incoming/outgoing bytes/packets

Change-Id: I9e8eee163c3033132eb202f3c75bad246c87f133
diff --git a/apps/cpman/pom.xml b/apps/cpman/pom.xml
index 5b89e01..f79b9ff 100644
--- a/apps/cpman/pom.xml
+++ b/apps/cpman/pom.xml
@@ -34,8 +34,7 @@
         <onos.app.name>org.onosproject.cpman</onos.app.name>
         <onos.app.category>default</onos.app.category>
         <onos.app.url>http://onosproject.org</onos.app.url>
-        <onos.app.readme>Control plane management application.
-        </onos.app.readme>
+        <onos.app.readme>Control plane management application.</onos.app.readme>
     </properties>
 
     <dependencies>
diff --git a/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java b/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java
index ab67918..a5dc81c 100644
--- a/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java
+++ b/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2015-2016 Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,27 +20,78 @@
  */
 public enum ControlMetricType {
 
-    /** Mapped to PACKET-IN message of OpenFlow. */
+    /* Mapped to PACKET-IN message of OpenFlow. */
     INBOUND_PACKET,
 
-    /** Mapped to PACKET-OUT message of OpenFlow. */
+    /* Mapped to PACKET-OUT message of OpenFlow. */
     OUTBOUND_PACKET,
 
-    /** Mapped to FLOW-MOD message of OpenFlow. */
+    /* Mapped to FLOW-MOD message of OpenFlow. */
     FLOW_MOD_PACKET,
 
-    /** Mapped to FLOW-REMOVED message of OpenFlow. */
+    /* Mapped to FLOW-REMOVED message of OpenFlow. */
     FLOW_REMOVED_PACKET,
 
-    /** Mapped to STATS-REQUEST message of OpenFlow. */
+    /* Mapped to STATS-REQUEST message of OpenFlow. */
     REQUEST_PACKET,
 
-    /** Mapped to STATS-REPLY message of OpenFlow. */
+    /* Mapped to STATS-REPLY message of OpenFlow. */
     REPLY_PACKET,
 
-    /** Cpu Utilization. */
-    CPU_INFO,
+    /* Number of CPU cores. */
+    NUM_OF_CORES,
 
-    /** Memory Utilization. */
-    MEMORY_INFO
+    /* Number of CPUs. **/
+    NUM_OF_CPUS,
+
+    /* CPU Speed. **/
+    CPU_SPEED,
+
+    /* CPU Load. **/
+    CPU_LOAD,
+
+    /* Total Amount of CPU Up Time. **/
+    TOTAL_CPU_TIME,
+
+    /* System CPU Up Time. **/
+    SYS_CPU_TIME,
+
+    /* User CPU Up Time. **/
+    USER_CPU_TIME,
+
+    /* CPU Idle Time. **/
+    CPU_IDLE_TIME,
+
+    /* Percentage of Used Memory Amount. */
+    MEMORY_USED_PERCENTAGE,
+
+    /* Percentage of Free Memory Amount. **/
+    MEMORY_FREE_PERCENTAGE,
+
+    /* Used Memory Amount. **/
+    MEMORY_USED,
+
+    /* Free Memory Amount. **/
+    MEMORY_FREE,
+
+    /* Total Amount of Memory. **/
+    MEMORY_TOTAL,
+
+    /* Disk Read Bytes. **/
+    DISK_READ_BYTES,
+
+    /* Disk Write Bytes. **/
+    DISK_WRITE_BYTES,
+
+    /* Network Incoming Bytes. **/
+    NW_INCOMING_BYTES,
+
+    /* Network Outgoing Bytes. **/
+    NW_OUTGOING_BYTES,
+
+    /* Network Incoming Packets. **/
+    NW_INCOMING_PACKETS,
+
+    /* Network Outgoing Packets. **/
+    NW_OUTGOING_PACKETS
 }
diff --git a/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsFactory.java b/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsFactory.java
index 65bcb8d..8a48d15 100644
--- a/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsFactory.java
+++ b/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2015-2016 Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -15,11 +15,13 @@
  */
 package org.onosproject.cpman;
 
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
 import org.onlab.metrics.MetricsService;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.device.DeviceService;
 
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
@@ -34,16 +36,35 @@
     private MetricsService metricsService;
     private boolean enableMonitor = false;
 
+    // define a ControlMetricsSystemSpec
+    private ControlMetricsSystemSpec cmss;
+
     // define a set of MetricsAggregators
-    private MetricsAggregator cpuInfoMetric;
-    private MetricsAggregator memoryInfoMetric;
-    private Map<DeviceId, MetricsAggregator> inboundPacketMetrics;
-    private Map<DeviceId, MetricsAggregator> outboundPacketMetrics;
-    private Map<DeviceId, MetricsAggregator> flowmodPacketMetrics;
-    private Map<DeviceId, MetricsAggregator> flowrmvPacketMetrics;
-    private Map<DeviceId, MetricsAggregator> requestPacketMetrics;
-    private Map<DeviceId, MetricsAggregator> replyPacketMetrics;
-    private Set<DeviceId> deviceIds = new HashSet<>();
+    private MetricsAggregator cpuLoad;
+    private MetricsAggregator totalCpuTime;
+    private MetricsAggregator sysCpuTime;
+    private MetricsAggregator userCpuTime;
+    private MetricsAggregator cpuIdleTime;
+    private MetricsAggregator memoryUsed;
+    private MetricsAggregator memoryFree;
+    private MetricsAggregator memoryUsedPercentage;
+    private MetricsAggregator memoryFreePercentage;
+    private Map<String, MetricsAggregator> diskReadBytes;
+    private Map<String, MetricsAggregator> diskWriteBytes;
+    private Map<String, MetricsAggregator> nwIncomingBytes;
+    private Map<String, MetricsAggregator> nwOutgoingBytes;
+    private Map<String, MetricsAggregator> nwIncomingPackets;
+    private Map<String, MetricsAggregator> nwOutgoingPackets;
+
+    private Map<DeviceId, MetricsAggregator> inboundPacket;
+    private Map<DeviceId, MetricsAggregator> outboundPacket;
+    private Map<DeviceId, MetricsAggregator> flowmodPacket;
+    private Map<DeviceId, MetricsAggregator> flowrmvPacket;
+    private Map<DeviceId, MetricsAggregator> requestPacket;
+    private Map<DeviceId, MetricsAggregator> replyPacket;
+    private Set<DeviceId> deviceIds = Sets.newConcurrentHashSet();
+    private Set<String> diskPartitions = Sets.newConcurrentHashSet();
+    private Set<String> nwInterfaces = Sets.newConcurrentHashSet();
 
     private ControlMetricsFactory(MetricsService metricsService, DeviceService deviceService) {
         this.metricsService = metricsService;
@@ -51,7 +72,7 @@
 
         deviceService.getDevices().forEach(d->deviceIds.add(d.id()));
 
-        addAllDeviceMetrics(deviceIds);
+        addAllControlMessageMetrics(deviceIds);
     }
 
     public static ControlMetricsFactory getInstance(MetricsService metricsService,
@@ -67,11 +88,22 @@
     }
 
     /**
+     * Sets system specification.
+     *
+     * @param cmss ControlMetricsSystemSpec object
+     */
+    public void setSystemSpec(ControlMetricsSystemSpec cmss) {
+        if (this.cmss == null) {
+            this.cmss = cmss;
+        }
+    }
+
+    /**
      * Adds control metrics of a new device.
      *
      * @param deviceId {@link org.onosproject.net.DeviceId}
      */
-    public void addMetricsByDeviceId(DeviceId deviceId) {
+    public void addControlMessageMetricsByDeviceId(DeviceId deviceId) {
         MetricsAggregator inbound = new MetricsAggregator(metricsService,
                         ControlMetricType.INBOUND_PACKET, Optional.of(deviceId));
         MetricsAggregator outbound = new MetricsAggregator(metricsService,
@@ -85,34 +117,123 @@
         MetricsAggregator reply = new MetricsAggregator(metricsService,
                         ControlMetricType.REPLY_PACKET, Optional.of(deviceId));
 
-        inboundPacketMetrics.putIfAbsent(deviceId, inbound);
-        outboundPacketMetrics.putIfAbsent(deviceId, outbound);
-        flowmodPacketMetrics.putIfAbsent(deviceId, flowmod);
-        flowrmvPacketMetrics.putIfAbsent(deviceId, flowrmv);
-        requestPacketMetrics.putIfAbsent(deviceId, request);
-        replyPacketMetrics.putIfAbsent(deviceId, reply);
+        inboundPacket.putIfAbsent(deviceId, inbound);
+        outboundPacket.putIfAbsent(deviceId, outbound);
+        flowmodPacket.putIfAbsent(deviceId, flowmod);
+        flowrmvPacket.putIfAbsent(deviceId, flowrmv);
+        requestPacket.putIfAbsent(deviceId, request);
+        replyPacket.putIfAbsent(deviceId, reply);
 
         deviceIds.add(deviceId);
     }
 
     /**
+     * Adds control metrics of a disk.
+     *
+     * @param partitionName disk partition name
+     */
+    public void addDiskMetricsByPartition(String partitionName) {
+        MetricsAggregator readBytes = new MetricsAggregator(metricsService,
+                        ControlMetricType.DISK_READ_BYTES, partitionName);
+        MetricsAggregator writeBytes = new MetricsAggregator(metricsService,
+                ControlMetricType.DISK_WRITE_BYTES, partitionName);
+
+        diskReadBytes.putIfAbsent(partitionName, readBytes);
+        diskWriteBytes.putIfAbsent(partitionName, writeBytes);
+
+        diskPartitions.add(partitionName);
+    }
+
+    /**
+     * Adds control metrics of a ethernet interface.
+     *
+     * @param interfaceName network interface name
+     */
+    public void addNetworkMetricsByInterface(String interfaceName) {
+        MetricsAggregator incomingBytes = new MetricsAggregator(metricsService,
+                        ControlMetricType.NW_INCOMING_BYTES, interfaceName);
+        MetricsAggregator outgoingBytes = new MetricsAggregator(metricsService,
+                ControlMetricType.NW_OUTGOING_BYTES, interfaceName);
+        MetricsAggregator incomingPackets = new MetricsAggregator(metricsService,
+                ControlMetricType.NW_INCOMING_PACKETS, interfaceName);
+        MetricsAggregator outgoingPackets = new MetricsAggregator(metricsService,
+                ControlMetricType.NW_OUTGOING_PACKETS, interfaceName);
+
+        nwIncomingBytes.putIfAbsent(interfaceName, incomingBytes);
+        nwOutgoingBytes.putIfAbsent(interfaceName, outgoingBytes);
+        nwIncomingPackets.putIfAbsent(interfaceName, incomingPackets);
+        nwOutgoingPackets.putIfAbsent(interfaceName, outgoingPackets);
+
+        nwInterfaces.add(interfaceName);
+    }
+
+    /**
      * Removes control metrics of an existing device.
      *
      * @param deviceId {@link org.onosproject.net.DeviceId}
      */
-    public void removeMetricsByDeviceId(DeviceId deviceId) {
-        inboundPacketMetrics.remove(deviceId);
-        outboundPacketMetrics.remove(deviceId);
-        flowmodPacketMetrics.remove(deviceId);
-        flowrmvPacketMetrics.remove(deviceId);
-        requestPacketMetrics.remove(deviceId);
-        replyPacketMetrics.remove(deviceId);
+    public void removeControlMessageMetricsByDeviceId(DeviceId deviceId) {
+        inboundPacket.remove(deviceId);
+        outboundPacket.remove(deviceId);
+        flowmodPacket.remove(deviceId);
+        flowrmvPacket.remove(deviceId);
+        requestPacket.remove(deviceId);
+        replyPacket.remove(deviceId);
 
         deviceIds.remove(deviceId);
     }
 
+    /**
+     * Removes control metrics of a disk.
+     *
+     * @param partitionName disk partition name
+     */
+    public void removeDiskMetricsByResourceName(String partitionName) {
+        diskReadBytes.remove(partitionName);
+        diskWriteBytes.remove(partitionName);
+
+        diskPartitions.remove(partitionName);
+    }
+
+    /**
+     * Removes control metrics of a network interface.
+     *
+     * @param interfaceName network interface name
+     */
+    public void removeNetworkInterfacesByResourceName(String interfaceName) {
+        nwIncomingBytes.remove(interfaceName);
+        nwOutgoingBytes.remove(interfaceName);
+        nwIncomingPackets.remove(interfaceName);
+        nwOutgoingPackets.remove(interfaceName);
+
+        nwInterfaces.remove(interfaceName);
+    }
+
+    /**
+     * Returns all device ids.
+     *
+     * @return a collection of device id
+     */
     public Set<DeviceId> getDeviceIds() {
-        return this.deviceIds;
+        return ImmutableSet.copyOf(this.deviceIds);
+    }
+
+    /**
+     * Returns all disk partition names.
+     *
+     * @return a collection of disk partition.
+     */
+    public Set<String> getDiskPartitions() {
+        return ImmutableSet.copyOf(this.diskPartitions);
+    }
+
+    /**
+     * Returns all network interface names.
+     *
+     * @return a collection of network interface.
+     */
+    public Set<String> getNetworkInterfaces() {
+        return ImmutableSet.copyOf(this.nwInterfaces);
     }
 
     /**
@@ -120,8 +241,8 @@
      *
      * @param deviceIds a set of deviceIds
      */
-    public void addAllDeviceMetrics(Set<DeviceId> deviceIds) {
-        deviceIds.forEach(v -> addMetricsByDeviceId(v));
+    public void addAllControlMessageMetrics(Set<DeviceId> deviceIds) {
+        deviceIds.forEach(v -> addControlMessageMetricsByDeviceId(v));
     }
 
     /**
@@ -151,87 +272,160 @@
      * Registers new control metrics.
      */
     protected void registerMetrics() {
-        cpuInfoMetric = new MetricsAggregator(metricsService,
-                        ControlMetricType.CPU_INFO, Optional.ofNullable(null));
-        memoryInfoMetric = new MetricsAggregator(metricsService,
-                        ControlMetricType.MEMORY_INFO, Optional.ofNullable(null));
+        /* CPU */
+        cpuLoad = new MetricsAggregator(metricsService, ControlMetricType.CPU_LOAD);
+        totalCpuTime = new MetricsAggregator(metricsService, ControlMetricType.TOTAL_CPU_TIME);
+        sysCpuTime = new MetricsAggregator(metricsService, ControlMetricType.SYS_CPU_TIME);
+        userCpuTime = new MetricsAggregator(metricsService, ControlMetricType.USER_CPU_TIME);
+        cpuIdleTime = new MetricsAggregator(metricsService, ControlMetricType.CPU_IDLE_TIME);
 
-        inboundPacketMetrics = new ConcurrentHashMap<>();
-        outboundPacketMetrics = new ConcurrentHashMap<>();
-        flowmodPacketMetrics = new ConcurrentHashMap<>();
-        flowrmvPacketMetrics = new ConcurrentHashMap<>();
-        requestPacketMetrics = new ConcurrentHashMap<>();
-        replyPacketMetrics = new ConcurrentHashMap<>();
+        /* Memory */
+        memoryFree = new MetricsAggregator(metricsService, ControlMetricType.MEMORY_FREE);
+        memoryUsed = new MetricsAggregator(metricsService, ControlMetricType.MEMORY_USED);
+        memoryFreePercentage = new MetricsAggregator(metricsService,
+                                        ControlMetricType.MEMORY_FREE_PERCENTAGE);
+        memoryUsedPercentage = new MetricsAggregator(metricsService,
+                                        ControlMetricType.MEMORY_USED_PERCENTAGE);
+
+        /* Disk I/O */
+        diskReadBytes = new ConcurrentHashMap<>();
+        diskWriteBytes = new ConcurrentHashMap<>();
+
+        /* Network I/O */
+        nwIncomingBytes = new ConcurrentHashMap<>();
+        nwOutgoingBytes = new ConcurrentHashMap<>();
+        nwIncomingPackets = new ConcurrentHashMap<>();
+        nwOutgoingPackets = new ConcurrentHashMap<>();
+
+        /* OpenFlow Messages */
+        inboundPacket = new ConcurrentHashMap<>();
+        outboundPacket = new ConcurrentHashMap<>();
+        flowmodPacket = new ConcurrentHashMap<>();
+        flowrmvPacket = new ConcurrentHashMap<>();
+        requestPacket = new ConcurrentHashMap<>();
+        replyPacket = new ConcurrentHashMap<>();
     }
 
     /**
      * Unregisters all control metrics.
      */
     protected void unregisterMetrics() {
-        cpuInfoMetric.removeMetrics();
-        memoryInfoMetric.removeMetrics();
+        /* Disk I/O */
+        diskReadBytes.clear();
+        diskWriteBytes.clear();
 
-        inboundPacketMetrics.clear();
-        outboundPacketMetrics.clear();
-        flowmodPacketMetrics.clear();
-        flowrmvPacketMetrics.clear();
-        requestPacketMetrics.clear();
-        replyPacketMetrics.clear();
+        /* Network I/O */
+        nwIncomingBytes.clear();
+        nwOutgoingBytes.clear();
+        nwIncomingPackets.clear();
+        nwOutgoingPackets.clear();
+
+        /* OpenFlow Message */
+        inboundPacket.clear();
+        outboundPacket.clear();
+        flowmodPacket.clear();
+        flowrmvPacket.clear();
+        requestPacket.clear();
+        replyPacket.clear();
     }
 
-    public MetricsAggregator cpuInfoMetric() {
-        return cpuInfoMetric;
+    public MetricsAggregator cpuLoadMetric() {
+        return cpuLoad;
     }
 
-    public MetricsAggregator memoryInfoMetric() {
-        return memoryInfoMetric;
+    public MetricsAggregator totalCpuTimeMetric() {
+        return totalCpuTime;
     }
 
-    public Map<DeviceId, MetricsAggregator> inboundPacketMetrics() {
-        return inboundPacketMetrics;
+    public MetricsAggregator sysCpuTimeMetric() {
+        return sysCpuTime;
     }
 
-    public Map<DeviceId, MetricsAggregator> outboundPacketMetrics() {
-        return outboundPacketMetrics;
+    public MetricsAggregator userCpuTime() {
+        return userCpuTime;
     }
 
-    public Map<DeviceId, MetricsAggregator> flowmodPacketMetrics() {
-        return flowmodPacketMetrics;
+    public MetricsAggregator cpuIdleTime() {
+        return cpuIdleTime;
     }
 
-    public Map<DeviceId, MetricsAggregator> flowrmvPacketMetrics() {
-        return flowrmvPacketMetrics;
+    public MetricsAggregator memoryFreePercentage() {
+        return memoryFreePercentage;
     }
 
-    public Map<DeviceId, MetricsAggregator> requestPacketMetrics() {
-        return requestPacketMetrics;
+    public MetricsAggregator memoryUsedPercentage() {
+        return memoryUsedPercentage;
     }
 
-    public Map<DeviceId, MetricsAggregator> replyPacketMetrics() {
-        return replyPacketMetrics;
+    public MetricsAggregator diskReadBytes(String partitionName) {
+        return diskReadBytes.get(partitionName);
     }
 
-    public MetricsAggregator inboundPacketMetrics(DeviceId deviceId) {
-        return inboundPacketMetrics.get(deviceId);
+    public MetricsAggregator diskWriteBytes(String partitionName) {
+        return diskWriteBytes.get(partitionName);
     }
 
-    public MetricsAggregator outboundPacketMetrics(DeviceId deviceId) {
-        return outboundPacketMetrics.get(deviceId);
+    public MetricsAggregator nwIncomingBytes(String interfaceName) {
+        return nwIncomingBytes.get(interfaceName);
     }
 
-    public MetricsAggregator flowmodPacketMetrics(DeviceId deviceId) {
-        return flowmodPacketMetrics.get(deviceId);
+    public MetricsAggregator nwOutgoingBytes(String interfaceName) {
+        return nwOutgoingBytes.get(interfaceName);
     }
 
-    public MetricsAggregator flowrmvPacketMetrics(DeviceId deviceId) {
-        return flowrmvPacketMetrics.get(deviceId);
+    public MetricsAggregator nwIncomingPackets(String interfaceName) {
+        return nwIncomingPackets.get(interfaceName);
     }
 
-    public MetricsAggregator requestPacketMetrics(DeviceId deviceId) {
-        return requestPacketMetrics.get(deviceId);
+    public MetricsAggregator nwOutgoingPackets(String interfaceName) {
+        return nwOutgoingPackets.get(interfaceName);
     }
 
-    public MetricsAggregator replyPacketMetrics(DeviceId deviceId) {
-        return replyPacketMetrics.get(deviceId);
+    public Map<DeviceId, MetricsAggregator> inboundPacket() {
+        return ImmutableMap.copyOf(inboundPacket);
+    }
+
+    public Map<DeviceId, MetricsAggregator> outboundPacket() {
+        return ImmutableMap.copyOf(outboundPacket);
+    }
+
+    public Map<DeviceId, MetricsAggregator> flowmodPacket() {
+        return ImmutableMap.copyOf(flowmodPacket);
+    }
+
+    public Map<DeviceId, MetricsAggregator> flowrmvPacket() {
+        return ImmutableMap.copyOf(flowrmvPacket);
+    }
+
+    public Map<DeviceId, MetricsAggregator> requestPacket() {
+        return ImmutableMap.copyOf(requestPacket);
+    }
+
+    public Map<DeviceId, MetricsAggregator> replyPacket() {
+        return ImmutableMap.copyOf(replyPacket);
+    }
+
+    public MetricsAggregator inboundPacket(DeviceId deviceId) {
+        return inboundPacket.get(deviceId);
+    }
+
+    public MetricsAggregator outboundPacket(DeviceId deviceId) {
+        return outboundPacket.get(deviceId);
+    }
+
+    public MetricsAggregator flowmodPacket(DeviceId deviceId) {
+        return flowmodPacket.get(deviceId);
+    }
+
+    public MetricsAggregator flowrmvPacket(DeviceId deviceId) {
+        return flowrmvPacket.get(deviceId);
+    }
+
+    public MetricsAggregator requestPacket(DeviceId deviceId) {
+        return requestPacket.get(deviceId);
+    }
+
+    public MetricsAggregator replyPacket(DeviceId deviceId) {
+        return replyPacket.get(deviceId);
     }
 }
\ No newline at end of file
diff --git a/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsObserver.java b/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsObserver.java
index dae5b0f..4cbe4a1 100644
--- a/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsObserver.java
+++ b/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsObserver.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2015-2016 Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,4 +31,12 @@
      * @param deviceId          device id {@link org.onosproject.net.DeviceId}
      */
     void feedMetrics(MetricsAggregator metricsAggregator, Optional<DeviceId> deviceId);
+
+    /**
+     * Feeds the extracted value from MetricAggregator to back-end storage.
+     *
+     * @param metricsAggregator metric aggregator
+     * @param resourceName      resource name
+     */
+    void feedMetrics(MetricsAggregator metricsAggregator, String resourceName);
 }
diff --git a/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsSystemSpec.java b/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsSystemSpec.java
new file mode 100644
index 0000000..bc2c214
--- /dev/null
+++ b/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricsSystemSpec.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * 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.cpman;
+
+/**
+ * Control metrics class for storing system specification.
+ */
+public final class ControlMetricsSystemSpec {
+    private int numOfCores;
+    private int numOfCpus;
+    private int cpuSpeed;               // in MHz
+    private long totalMemory;           // in bytes
+
+    private ControlMetricsSystemSpec(int numOfCores, int numOfCpus,
+                                     int cpuSpeed, long totalMemory) {
+        this.numOfCores = numOfCores;
+        this.numOfCpus = numOfCpus;
+        this.cpuSpeed = cpuSpeed;
+        this.totalMemory = totalMemory;
+    }
+
+    /**
+     * Returns number of CPU cores.
+     *
+     * @return number of CPU cores
+     */
+    public int numOfCores() {
+        return this.numOfCores;
+    }
+
+    /**
+     * Returns number of CPUs.
+     *
+     * @return number of CPUs
+     */
+    public int numOfCpus() {
+        return this.numOfCpus;
+    }
+
+    /**
+     * Returns CPU speed in MHz.
+     *
+     * @return CPU speed
+     */
+    public int cpuSpeed() {
+        return this.cpuSpeed;
+    }
+
+    /**
+     * Returns the total amount of memory.
+     *
+     * @return memory size
+     */
+    public long totalMemory() {
+        return this.totalMemory;
+    }
+
+    /**
+     * ControlMetricsSystemSpec builder class.
+     */
+    public static final class Builder {
+        private int numOfCores;
+        private int numOfCpus;
+        private int cpuSpeed;               // in MHz
+        private long totalMemory;           // in bytes
+
+        /**
+         * Sets number of CPU cores.
+         *
+         * @param numOfCores number of CPU cores
+         * @return Builder object
+         */
+        public Builder numOfCores(int numOfCores) {
+            this.numOfCores = numOfCores;
+            return this;
+        }
+
+        /**
+         * Sets number of CPUs.
+         * @param numOfCpus number of CPUs
+         * @return Builder object
+         */
+        public Builder numOfCpus(int numOfCpus) {
+            this.numOfCpus = numOfCpus;
+            return this;
+        }
+
+        /**
+         * Sets CPU speed.
+         *
+         * @param cpuSpeed CPU speed
+         * @return Builder object
+         */
+        public Builder cpuSpeed(int cpuSpeed) {
+            this.cpuSpeed = cpuSpeed;
+            return this;
+        }
+
+        /**
+         * Sets total amount of memory.
+         *
+         * @param totalMemory memory size
+         * @return Builder object
+         */
+        public Builder totalMemory(long totalMemory) {
+            this.totalMemory = totalMemory;
+            return this;
+        }
+
+        /**
+         * Builds a ControlMetricsSystemSpec object.
+         *
+         * @return ControlMetricsSystemSpec object
+         */
+        public ControlMetricsSystemSpec build() {
+            return new ControlMetricsSystemSpec(numOfCores, numOfCpus, cpuSpeed, totalMemory);
+        }
+    }
+}
diff --git a/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java b/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java
index c01fabd..3305297 100644
--- a/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java
+++ b/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2015-2016 Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -95,18 +95,18 @@
         if (cmf.isMonitor()) {
             controlMetricsObservers.forEach(observer -> {
 
-                // try to feed the CPU and memory stats
-                observer.feedMetrics(cmf.cpuInfoMetric(), Optional.ofNullable(null));
-                observer.feedMetrics(cmf.memoryInfoMetric(), Optional.ofNullable(null));
+                // only OpenFlow messages are spontaneously monitored with
+                // 1 minute period. Other system metrics will be pushed from
+                // external monitoring agent through REST API
 
-                // try to feed the control message stats
+                // feed the control message stats
                 cmf.getDeviceIds().forEach(v -> {
-                    observer.feedMetrics(cmf.inboundPacketMetrics(v), Optional.of(v));
-                    observer.feedMetrics(cmf.outboundPacketMetrics(v), Optional.of(v));
-                    observer.feedMetrics(cmf.flowmodPacketMetrics(v), Optional.of(v));
-                    observer.feedMetrics(cmf.flowrmvPacketMetrics(v), Optional.of(v));
-                    observer.feedMetrics(cmf.requestPacketMetrics(v), Optional.of(v));
-                    observer.feedMetrics(cmf.replyPacketMetrics(v), Optional.of(v));
+                    observer.feedMetrics(cmf.inboundPacket(v), Optional.of(v));
+                    observer.feedMetrics(cmf.outboundPacket(v), Optional.of(v));
+                    observer.feedMetrics(cmf.flowmodPacket(v), Optional.of(v));
+                    observer.feedMetrics(cmf.flowrmvPacket(v), Optional.of(v));
+                    observer.feedMetrics(cmf.requestPacket(v), Optional.of(v));
+                    observer.feedMetrics(cmf.replyPacket(v), Optional.of(v));
                 });
             });
         }
diff --git a/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMonitor.java b/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMonitor.java
index 2d8442b..2144f46 100644
--- a/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMonitor.java
+++ b/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMonitor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2015-2016 Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -57,6 +57,12 @@
     }
 
     @Override
+    public void updateMetric(ControlMetric controlMetric, int updateInterval,
+                             String resourceName) {
+
+    }
+
+    @Override
     public ControlLoad getLoad(NodeId nodeId, ControlMetricType type,
                                Optional<DeviceId> deviceId) {
         return null;
diff --git a/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMonitorService.java b/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMonitorService.java
index 24f7717..d35f24f 100644
--- a/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMonitorService.java
+++ b/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMonitorService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2015-2016 Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,6 +36,15 @@
     void updateMetric(ControlMetric controlMetric, int updateInterval, Optional<DeviceId> deviceId);
 
     /**
+     * Adds a new control metric value with a certain update interval.
+     *
+     * @param controlMetric     control plane metric (e.g., disk and network metrics)
+     * @param updateInterval    value update interval (time unit will be in minute)
+     * @param resourceName      resource name
+     */
+    void updateMetric(ControlMetric controlMetric, int updateInterval, String resourceName);
+
+    /**
      * Obtains the control plane load of a specific device.
      *
      * @param nodeId   node id {@link org.onosproject.cluster.NodeId}
diff --git a/apps/cpman/src/main/java/org/onosproject/cpman/DefaultControlMetricsObserver.java b/apps/cpman/src/main/java/org/onosproject/cpman/DefaultControlMetricsObserver.java
index 79921d5..434c165 100644
--- a/apps/cpman/src/main/java/org/onosproject/cpman/DefaultControlMetricsObserver.java
+++ b/apps/cpman/src/main/java/org/onosproject/cpman/DefaultControlMetricsObserver.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2015-2016 Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,7 +32,14 @@
     @Override
     public void feedMetrics(MetricsAggregator ma, Optional<DeviceId> deviceId) {
         MetricValue mv = new MetricValue((long) ma.getRate(), (long) ma.getLoad(), (long) ma.getCount());
-        ControlMetric cpm = new ControlMetric(ma.getMetricsType(), mv);
-        controlPlaneMonitorService.updateMetric(cpm, 1, deviceId);
+        ControlMetric cm = new ControlMetric(ma.getMetricsType(), mv);
+        controlPlaneMonitorService.updateMetric(cm, 1, deviceId);
+    }
+
+    @Override
+    public void feedMetrics(MetricsAggregator ma, String resourceName) {
+        MetricValue mv = new MetricValue((long) ma.getRate(), (long) ma.getLoad(), (long) ma.getCount());
+        ControlMetric cm = new ControlMetric(ma.getMetricsType(), mv);
+        controlPlaneMonitorService.updateMetric(cm, 1, resourceName);
     }
 }
\ No newline at end of file
diff --git a/apps/cpman/src/main/java/org/onosproject/cpman/MetricsAggregator.java b/apps/cpman/src/main/java/org/onosproject/cpman/MetricsAggregator.java
index abd5b1c..139a9a4 100644
--- a/apps/cpman/src/main/java/org/onosproject/cpman/MetricsAggregator.java
+++ b/apps/cpman/src/main/java/org/onosproject/cpman/MetricsAggregator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * Copyright 2015-2016 Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
 package org.onosproject.cpman;
 
 import com.codahale.metrics.Meter;
+import org.apache.commons.lang3.StringUtils;
 import org.onlab.metrics.MetricsComponent;
 import org.onlab.metrics.MetricsFeature;
 import org.onlab.metrics.MetricsService;
@@ -49,13 +50,58 @@
      * @param type           Control metric type
      * @param deviceId       DeviceId
      */
-    MetricsAggregator(MetricsService metricsService, ControlMetricType type, Optional<DeviceId> deviceId) {
+    MetricsAggregator(MetricsService metricsService, ControlMetricType type,
+                      Optional<DeviceId> deviceId) {
+        init(metricsService, type, deviceId, null);
+    }
+
+    /**
+     * Constructs a new MetricAggregator for aggregating a metric.
+     * Instantiates the metrics service
+     * Initializes all the general metrics for that object
+     *
+     * @param metricsService MetricsService reference
+     * @param type           Control metric type
+     * @param resourceName   resource name (e.g., ethernet interface name)
+     */
+    MetricsAggregator(MetricsService metricsService, ControlMetricType type,
+                      String resourceName) {
+        init(metricsService, type, Optional.ofNullable(null), resourceName);
+
+    }
+
+    /**
+     * Constructs a new MetricAggregator for aggregating a metric.
+     * Instantiates the metrics service
+     * Initializes all the general metrics for that object
+     *
+     * @param metricsService MetricsService reference
+     * @param type           Control metric type
+     */
+    MetricsAggregator(MetricsService metricsService, ControlMetricType type) {
+        init(metricsService, type, Optional.ofNullable(null), null);
+    }
+
+    /**
+     * Base method of the constructor of this class.
+     *
+     * @param metricsService MetricsService reference
+     * @param type           Control metric type
+     * @param deviceId       DeviceId
+     * @param resourceName   resource name
+     */
+    private void init(MetricsService metricsService, ControlMetricType type,
+                      Optional<DeviceId> deviceId, String resourceName) {
         String primitiveName = type.toString();
         String objName = "all";
         if (deviceId.isPresent()) {
             objName = deviceId.toString();
         }
 
+        if (StringUtils.isNotEmpty(resourceName)) {
+            objName = resourceName;
+        }
+
         checkNotNull(primitiveName, "Component name cannot be null");
         checkNotNull(objName, "Feature name cannot be null");
 
@@ -74,14 +120,6 @@
     }
 
     /**
-     * Removes both rate and count metrics.
-     */
-    protected void removeMetrics() {
-        metricsService.removeMetric(metricsComponent, metricsFeature, RATE_NAME);
-        metricsService.removeMetric(metricsComponent, metricsFeature, COUNT_NAME);
-    }
-
-    /**
      * Increments the meter rate by {@code n}, and the meter counter by 1.
      *
      * @param n Increment the meter rate by {@code n}.