[ONOS-6188] Notify to MeterListeners meter installation and removal on device.

Using the MeterStats entries and the actual MeterStore state of the meters notify
just before MeterStore converts the state to ADDED. Remove case is different since
the PENDING_REMOVE state in meter store corresponds to MeterStats meter missing.

Change-Id: I0fe46e1618312b816534c6a7bda7d9e618ca1f7e
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterEvent.java b/core/api/src/main/java/org/onosproject/net/meter/MeterEvent.java
index abf5151..7a5af46 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/MeterEvent.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterEvent.java
@@ -32,7 +32,17 @@
         /**
          * A meter removal was requested.
          */
-        METER_REM_REQ
+        METER_REM_REQ,
+
+        /**
+         * A meter was finally added to device.
+         */
+        METER_ADDED,
+
+        /**
+         * A meter was finally removed from device.
+         */
+        METER_REMOVED
     }
 
 
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java
index 30adaa9..64230db 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java
@@ -310,6 +310,12 @@
                     p.performMeterOperation(deviceId, new MeterOperation(event.subject(),
                                                                          MeterOperation.Type.REMOVE));
                     break;
+                case METER_ADDED:
+                    log.info("Meter added {}", event.subject());
+                    break;
+                case METER_REMOVED:
+                    log.info("Meter removed {}", event.subject());
+                    break;
                 default:
                     log.warn("Unknown meter event {}", event.type());
             }
diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java b/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java
index 8306288..4be984a 100644
--- a/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java
+++ b/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java
@@ -285,6 +285,7 @@
         MeterKey key = MeterKey.key(m.deviceId(), m.id());
         futures.remove(key);
         meters.remove(key);
+        notifyDelegate(new MeterEvent(MeterEvent.Type.METER_REMOVED, m));
     }
 
     @Override
@@ -317,8 +318,14 @@
                                 }
                                 break;
                             case ADDED:
-                                if (local.equals(data.origin()) && data.meter().state() == MeterState.PENDING_ADD) {
-                                    futures.remove(key).complete(MeterStoreResult.success());
+                                if (local.equals(data.origin()) &&
+                                        (data.meter().state() == MeterState.PENDING_ADD
+                                                || data.meter().state() == MeterState.ADDED)) {
+                                    futures.computeIfPresent(key, (k, v) -> {
+                                        notifyDelegate(
+                                                new MeterEvent(MeterEvent.Type.METER_ADDED, data.meter()));
+                                        return null;
+                                    });
                                 }
                                 break;
                             case REMOVED: