Moving meter store implementation to use map events

Change-Id: I338473b7286d7b9e5cdfb938f16c7b6155d4cbb5
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/DefaultMeter.java b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/DefaultMeter.java
index 138bb18..177688c 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/DefaultMeter.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/DefaultMeter.java
@@ -20,7 +20,6 @@
 
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Optional;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -37,7 +36,6 @@
     private final boolean burst;
     private final Collection<Band> bands;
     private final DeviceId deviceId;
-    private final Optional<MeterContext> context;
 
     private MeterState state;
     private long life;
@@ -47,14 +45,13 @@
 
     private DefaultMeter(DeviceId deviceId, MeterId id, ApplicationId appId,
                         Unit unit, boolean burst,
-                        Collection<Band> bands, Optional<MeterContext> context) {
+                        Collection<Band> bands) {
         this.deviceId = deviceId;
         this.id = id;
         this.appId = appId;
         this.unit = unit;
         this.burst = burst;
         this.bands = bands;
-        this.context = context;
     }
 
     @Override
@@ -88,11 +85,6 @@
     }
 
     @Override
-    public Optional<MeterContext> context() {
-        return null;
-    }
-
-    @Override
     public MeterState state() {
         return state;
     }
@@ -154,7 +146,6 @@
         private boolean burst = false;
         private Collection<Band> bands;
         private DeviceId deviceId;
-        private Optional<MeterContext> context;
 
 
         @Override
@@ -194,19 +185,13 @@
         }
 
         @Override
-        public Meter.Builder withContext(MeterContext context) {
-            this.context = Optional.<MeterContext>ofNullable(context);
-            return this;
-        }
-
-        @Override
         public DefaultMeter build() {
             checkNotNull(deviceId, "Must specify a device");
             checkNotNull(bands, "Must have bands.");
             checkArgument(bands.size() > 0, "Must have at least one band.");
             checkNotNull(appId, "Must have an application id");
             checkNotNull(id, "Must specify a meter id");
-            return new DefaultMeter(deviceId, id, appId, unit, burst, bands, context);
+            return new DefaultMeter(deviceId, id, appId, unit, burst, bands);
         }
 
 
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/Meter.java b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/Meter.java
index 14593df..37c1105 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/Meter.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/Meter.java
@@ -19,7 +19,6 @@
 import org.onosproject.net.DeviceId;
 
 import java.util.Collection;
-import java.util.Optional;
 
 /**
  * Represents a generalized meter to be deployed on a device.
@@ -81,14 +80,6 @@
     Collection<Band> bands();
 
     /**
-     * Obtains an optional context.
-     *
-     * @return optional; which will be empty if there is no context.
-     * Otherwise it will return the context.
-     */
-    Optional<MeterContext> context();
-
-    /**
      * Fetches the state of this meter.
      *
      * @return a meter state
@@ -177,8 +168,6 @@
          */
         Builder withBands(Collection<Band> bands);
 
-        Builder withContext(MeterContext context);
-
         /**
          * Builds the meter based on the specified parameters.
          *
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterContext.java b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterContext.java
index 919cf63..b112b9a 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterContext.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterContext.java
@@ -16,23 +16,23 @@
 package org.onosproject.incubator.net.meter;
 
 /**
- * Created by ash on 01/08/15.
+ * A context permitting the application to be notified when the
+ * meter installation has been successful.
  */
 public interface MeterContext {
 
     /**
      * Invoked on successful installation of the meter.
      *
-     * @param op a meter operation
+     * @param op a meter
      */
-    default void onSuccess(MeterOperation op) {
-    }
+    default void onSuccess(Meter op) {}
 
     /**
      * Invoked when error is encountered while installing a meter.
      *
-     * @param op a meter operation
+     * @param op a meter
      * @param reason the reason why it failed
      */
-    default void onError(MeterOperation op, MeterFailReason reason) {}
+    default void onError(Meter op, MeterFailReason reason) {}
 }
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterEvent.java b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterEvent.java
index 9439145..808a3e8 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterEvent.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterEvent.java
@@ -20,28 +20,19 @@
 /**
  * Entity that represents Meter events.
  */
-public class MeterEvent extends AbstractEvent<MeterEvent.Type, MeterOperation> {
+public class MeterEvent extends AbstractEvent<MeterEvent.Type, Meter> {
 
 
-    private final MeterFailReason reason;
-
     public enum Type {
+        /**
+         * A meter addition was requested.
+         */
+        METER_ADD_REQ,
 
         /**
-         * Signals that a meter has been added.
+         * A meter removal was requested.
          */
-        METER_UPDATED,
-
-        /**
-         * Signals that a meter update failed.
-         */
-        METER_OP_FAILED,
-
-        /**
-         * A meter operation was requested.
-         */
-        METER_OP_REQ,
-
+        METER_REM_REQ
     }
 
 
@@ -50,32 +41,22 @@
      * current time.
      *
      * @param type  meter event type
-     * @param op event subject
+     * @param meter event subject
      */
-    public MeterEvent(Type type, MeterOperation op) {
-        super(type, op);
-        this.reason = null;
+    public MeterEvent(Type type, Meter meter) {
+        super(type, meter);
     }
 
     /**
      * Creates an event of a given type and for the specified meter and time.
      *
      * @param type  meter event type
-     * @param op event subject
+     * @param meter event subject
      * @param time  occurrence time
      */
-    public MeterEvent(Type type, MeterOperation op, long time) {
-        super(type, op, time);
-        this.reason = null;
+    public MeterEvent(Type type, Meter meter, long time) {
+        super(type, meter, time);
     }
 
-    public MeterEvent(Type type, MeterOperation op, MeterFailReason reason) {
-        super(type, op);
-        this.reason = reason;
-    }
-
-    public MeterFailReason reason() {
-        return reason;
-    }
 
 }
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterOperation.java b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterOperation.java
index ff7e988..8354888 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterOperation.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterOperation.java
@@ -17,11 +17,15 @@
 
 import com.google.common.base.MoreObjects;
 
+import java.util.Optional;
+
 /**
  * Representation of an operation on the meter table.
  */
 public class MeterOperation {
 
+    private final Optional<MeterContext> context;
+
     /**
      * Tyoe of meter operation.
      */
@@ -35,9 +39,10 @@
     private final Type type;
 
 
-    public MeterOperation(Meter meter, Type type) {
+    public MeterOperation(Meter meter, Type type, MeterContext context) {
         this.meter = meter;
         this.type = type;
+        this.context = Optional.ofNullable(context);
     }
 
     /**
@@ -58,6 +63,16 @@
         return meter;
     }
 
+    /**
+     * Returns a context which allows application to
+     * be notified on the success value of this operation.
+     *
+     * @return a meter context
+     */
+    public Optional<MeterContext> context() {
+        return this.context;
+    }
+
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(this)
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterService.java
index b8702dd..c7eb93a 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterService.java
@@ -30,28 +30,21 @@
      *
      * @param meter a meter.
      */
-    void addMeter(Meter meter);
+    void addMeter(MeterOperation meter);
 
     /**
      * Updates a meter by adding statistic information to the meter.
      *
      * @param meter an updated meter
      */
-    void updateMeter(Meter meter);
+    void updateMeter(MeterOperation meter);
 
     /**
      * Remove a meter from the system and the dataplane.
      *
      * @param meter a meter to remove
      */
-    void removeMeter(Meter meter);
-
-    /**
-     * Remove a meter from the system and the dataplane by meter id.
-     *
-     * @param id a meter id
-     */
-    void removeMeter(MeterId id);
+    void removeMeter(MeterOperation meter);
 
     /**
      * Fetch the meter by the meter id.
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterStore.java b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterStore.java
index 232eedd..54e5658 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterStore.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterStore.java
@@ -18,6 +18,7 @@
 import org.onosproject.store.Store;
 
 import java.util.Collection;
+import java.util.concurrent.CompletableFuture;
 
 /**
  * Entity that stores and distributed meter objects.
@@ -28,25 +29,29 @@
      * Adds a meter to the store.
      *
      * @param meter a meter
+     * @return a future indicating the result of the store operation
      */
-    void storeMeter(Meter meter);
+    CompletableFuture<MeterStoreResult> storeMeter(Meter meter);
 
     /**
      * Deletes a meter from the store.
      *
      * @param meter a meter
+     * @return a future indicating the result of the store operation
      */
-    void deleteMeter(Meter meter);
+    CompletableFuture<MeterStoreResult> deleteMeter(Meter meter);
 
     /**
      * Updates a meter whose meter id is the same as the passed meter.
      *
      * @param meter a new meter
+     * @return a future indicating the result of the store operation
      */
-    void updateMeter(Meter meter);
+    CompletableFuture<MeterStoreResult> updateMeter(Meter meter);
 
     /**
      * Updates a given meter's state with the provided state.
+     *
      * @param meter a meter
      */
     void updateMeterState(Meter meter);
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterStoreResult.java b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterStoreResult.java
new file mode 100644
index 0000000..8ad5aa6
--- /dev/null
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/meter/MeterStoreResult.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 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.incubator.net.meter;
+
+import java.util.Optional;
+
+/**
+ * An entity used to indicate whether the store operation passed.
+ */
+public final class MeterStoreResult {
+
+
+    private final Type type;
+    private final Optional<MeterFailReason> reason;
+
+    public enum Type {
+        SUCCESS,
+        FAIL
+    }
+
+    private MeterStoreResult(Type type, MeterFailReason reason) {
+        this.type = type;
+        this.reason = Optional.ofNullable(reason);
+    }
+
+    public Type type() {
+        return type;
+    }
+
+    public Optional<MeterFailReason> reason() {
+        return reason;
+    }
+
+    /**
+     * A successful store opertion.
+     *
+     * @return a meter store result
+     */
+    public static MeterStoreResult success() {
+        return new MeterStoreResult(Type.SUCCESS, null);
+    }
+
+    /**
+     * A failed store operation.
+     *
+     * @param reason a failure reason
+     * @return a meter store result
+     */
+    public static MeterStoreResult fail(MeterFailReason reason) {
+        return new MeterStoreResult(Type.FAIL, reason);
+    }
+
+}