[SDFAB-352][SDFAB-353] Retrieve MeterFeatures from the P4RT southbound, Extend MeterProviderService and revisit MeterStore

Change-Id: If0dae53643988cb551ff5020abd792cb6d33ff6b
diff --git a/core/net/src/main/java/org/onosproject/net/meter/impl/MeterDriverProvider.java b/core/net/src/main/java/org/onosproject/net/meter/impl/MeterDriverProvider.java
index e6151b0..cf7d198 100644
--- a/core/net/src/main/java/org/onosproject/net/meter/impl/MeterDriverProvider.java
+++ b/core/net/src/main/java/org/onosproject/net/meter/impl/MeterDriverProvider.java
@@ -24,6 +24,7 @@
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterFeatures;
 import org.onosproject.net.meter.MeterOperation;
 import org.onosproject.net.meter.MeterOperations;
 import org.onosproject.net.meter.MeterProgrammable;
@@ -36,6 +37,7 @@
 import org.slf4j.LoggerFactory;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ScheduledExecutorService;
@@ -147,6 +149,17 @@
         meterProviderService.pushMeterMetrics(deviceId, meters);
     }
 
+    private void getMeterFeatures(DeviceId deviceId) {
+        Collection<MeterFeatures> meterFeatures = Collections.emptySet();
+        try {
+            meterFeatures = getMeterProgrammable(deviceId).getMeterFeatures().get(pollFrequency, TimeUnit.SECONDS);
+        } catch (Exception e) {
+            log.warn("Unable to get the Meter Features from {}, error: {}", deviceId, e.getMessage());
+            log.debug("Exception: ", e);
+        }
+        meterProviderService.pushMeterFeatures(deviceId, meterFeatures);
+    }
+
     private MeterProgrammable getMeterProgrammable(DeviceId deviceId) {
         Device device = deviceService.getDevice(deviceId);
         if (device.is(MeterProgrammable.class)) {
@@ -173,6 +186,19 @@
 
         private void handleEvent(DeviceEvent event) {
             Device device = event.subject();
+
+            switch (event.type()) {
+                case DEVICE_ADDED:
+                    getMeterFeatures(device.id());
+                    break;
+                case DEVICE_REMOVED:
+                case DEVICE_SUSPENDED:
+                    meterProviderService.deleteMeterFeatures(device.id());
+                    break;
+                default:
+                    break;
+            }
+
             boolean isRelevant = mastershipService.isLocalMaster(device.id()) &&
                     deviceService.isAvailable(device.id());
 
diff --git a/core/net/src/main/java/org/onosproject/net/meter/impl/MeterManager.java b/core/net/src/main/java/org/onosproject/net/meter/impl/MeterManager.java
index 363876c..03bb5ca 100644
--- a/core/net/src/main/java/org/onosproject/net/meter/impl/MeterManager.java
+++ b/core/net/src/main/java/org/onosproject/net/meter/impl/MeterManager.java
@@ -417,7 +417,7 @@
                 // and we purge the meter from the store
                 } else if (m.state() == MeterState.PENDING_REMOVE) {
                     log.debug("Delete meter {} now in store", m.id());
-                    store.deleteMeterNow(m);
+                    store.purgeMeter(m);
                 }
             });
         }
@@ -428,6 +428,11 @@
         }
 
         @Override
+        public void pushMeterFeatures(DeviceId deviceId, Collection<MeterFeatures> meterfeatures) {
+            meterfeatures.forEach(mf -> store.storeMeterFeatures(mf));
+        }
+
+        @Override
         public void deleteMeterFeatures(DeviceId deviceId) {
             store.deleteMeterFeatures(deviceId);
         }
diff --git a/core/net/src/test/java/org/onosproject/net/meter/impl/MeterManagerTest.java b/core/net/src/test/java/org/onosproject/net/meter/impl/MeterManagerTest.java
index 52970dd..09e9774 100644
--- a/core/net/src/test/java/org/onosproject/net/meter/impl/MeterManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/meter/impl/MeterManagerTest.java
@@ -575,6 +575,12 @@
             mProgrammableAdded.setState(MeterState.ADDED);
             return CompletableFuture.completedFuture(ImmutableList.of(mProgrammableAdded));
         }
+
+        @Override
+        public CompletableFuture<Collection<MeterFeatures>> getMeterFeatures() {
+            //Currently unused.
+            return CompletableFuture.completedFuture(Collections.emptySet());
+        }
     }
 
     private class TestProvider extends AbstractProvider implements MeterProvider {