Implement DefaultControlLoad, add lastUpdate for MetricsDatabase

Change-Id: Ice2ba793927117245c3fd12f32da239b60240c90
diff --git a/apps/cpman/api/src/main/java/org/onosproject/cpman/ControlLoad.java b/apps/cpman/api/src/main/java/org/onosproject/cpman/ControlLoad.java
index b783aa6..f0c4e63 100644
--- a/apps/cpman/api/src/main/java/org/onosproject/cpman/ControlLoad.java
+++ b/apps/cpman/api/src/main/java/org/onosproject/cpman/ControlLoad.java
@@ -39,4 +39,20 @@
      * @return average control plane metric value
      */
     long average();
+
+    /**
+     * Obtains the most recent metric values of the specified time duration.
+     *
+     * @param duration time duration
+     * @param unit time unit
+     * @return a collection of the most recent metric values
+     */
+    long[] recent(int duration, TimeUnit unit);
+
+    /**
+     * Obtains all metrics.
+     *
+     * @return a collection of the all metric values
+     */
+    long[] all();
 }
diff --git a/apps/cpman/api/src/main/java/org/onosproject/cpman/MetricsDatabase.java b/apps/cpman/api/src/main/java/org/onosproject/cpman/MetricsDatabase.java
index a0e3679..da9e2ea 100644
--- a/apps/cpman/api/src/main/java/org/onosproject/cpman/MetricsDatabase.java
+++ b/apps/cpman/api/src/main/java/org/onosproject/cpman/MetricsDatabase.java
@@ -117,6 +117,14 @@
     double[] metrics(String metricType, long startTime, long endTime);
 
     /**
+     * Returns the latest metric update time.
+     *
+     * @param metricType metric type
+     * @return timestamp
+     */
+    long lastUpdate(String metricType);
+
+    /**
      * A builder of MetricsDatabase.
      */
     interface Builder {
diff --git a/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultControlLoad.java b/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultControlLoad.java
new file mode 100644
index 0000000..ef32cab
--- /dev/null
+++ b/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultControlLoad.java
@@ -0,0 +1,90 @@
+/*
+ * 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.impl;
+
+import org.onosproject.cpman.ControlLoad;
+import org.onosproject.cpman.ControlMetricType;
+import org.onosproject.cpman.MetricsDatabase;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+/**
+ * An implementation of control plane load.
+ */
+public class DefaultControlLoad implements ControlLoad {
+
+    private final MetricsDatabase mdb;
+    private final ControlMetricType type;
+
+    public DefaultControlLoad(MetricsDatabase mdb, ControlMetricType type) {
+        this.mdb = mdb;
+        this.type = type;
+    }
+
+    @Override
+    public long average(int duration, TimeUnit unit) {
+        return (long) Arrays.stream(recent(duration, unit)).average().getAsDouble();
+    }
+
+    @Override
+    public long average() {
+        return (long) Arrays.stream(all()).average().getAsDouble();
+    }
+
+    @Override
+    public long rate() {
+        return 0;
+    }
+
+    @Override
+    public long latest() {
+        return (long) mdb.recentMetric(type.toString());
+    }
+
+    @Override
+    public boolean isValid() {
+        return true;
+    }
+
+    @Override
+    public long time() {
+        return mdb.lastUpdate(type.toString());
+    }
+
+    @Override
+    public long[] recent(int duration, TimeUnit unit) {
+        return doubleToLong(mdb.recentMetrics(type.toString(), duration, unit));
+    }
+
+    @Override
+    public long[] all() {
+        return doubleToLong(mdb.metrics(type.toString()));
+    }
+
+    private double nanToZero(double d) {
+        return Double.isNaN(d) ? 0D : d;
+    }
+
+    private long[] doubleToLong(double[] array) {
+        final long[] longArray = new long[array.length];
+        IntStream.range(0, array.length).forEach(i ->
+                longArray[i] = (long) nanToZero(array[i]));
+
+        return longArray;
+    }
+}
diff --git a/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultMetricsDatabase.java b/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultMetricsDatabase.java
index 7c71410..f387dbf 100644
--- a/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultMetricsDatabase.java
+++ b/apps/cpman/app/src/main/java/org/onosproject/cpman/impl/DefaultMetricsDatabase.java
@@ -183,6 +183,17 @@
         return new double[0];
     }
 
+    @Override
+    public long lastUpdate(String metricType) {
+        try {
+            checkArgument(rrdDb.containsDs(metricType), NON_EXIST_METRIC);
+            rrdDb.getLastUpdateTime();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return 0L;
+    }
+
     // try to check whether projected time range is within a day
     private boolean checkTimeRange(long startTime, long endTime) {
         // check whether the given startTime and endTime larger than 1 minute