[SDFAB-502] Improve P4RuntimeMeterProgrammable reconciliation

This is achieved by implementing device specific methods to verify if
ONOS store meters and values read from the devices are similar

Change-Id: I95b6a2c728536f08b47ce9d0d30d1b8888a353d7
diff --git a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMeterProgrammable.java b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMeterProgrammable.java
index 9a04a35..5165783 100644
--- a/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMeterProgrammable.java
+++ b/drivers/p4runtime/src/main/java/org/onosproject/drivers/p4runtime/P4RuntimeMeterProgrammable.java
@@ -227,7 +227,7 @@
         }
 
         // The config is not consistent
-        if (!translatedEntity.get().translated().equals(config)) {
+        if (!isSimilar(translatedEntity.get().translated(), config)) {
             log.warn("Meter Cell Config obtained from device {} is different from " +
                              "one in in translation store: device={}, store={}",
                      deviceId, config, translatedEntity.get().translated());
@@ -245,10 +245,10 @@
         // Forge a meter with MeterCellId, Bands and DeviceId using the original value.
         // Other values are not required because we cannot retrieve them from the south
         DefaultMeter meter = (DefaultMeter) DefaultMeter.builder()
-                            .withBands(original.bands())
-                            .withCellId(original.meterCellId())
-                            .forDevice(deviceId)
-                            .build();
+                .withBands(original.bands())
+                .withCellId(original.meterCellId())
+                .forDevice(deviceId)
+                .build();
         meter.setState(MeterState.ADDED);
         return meter;
     }
@@ -271,6 +271,21 @@
     }
 
     /**
+     * Returns true if the given PiMeterCellConfigs are similar enough to be deemed equal
+     * for reconciliation purposes. This is required to handle read/write asymmetry in devices
+     * that allow variations in the meter rate/burst. E.g., devices that implement metering
+     * with a rate or burst size that is slightly higher/lower than the configured ones,
+     * so the values written by ONOS will be different than those read from the device.
+     *
+     * @param onosMeter the ONOS meter
+     * @param deviceMeter the meter in the device
+     * @return true if the meters are similar, false otherwise
+     */
+    protected boolean isSimilar(PiMeterCellConfig onosMeter, PiMeterCellConfig deviceMeter) {
+        return onosMeter.equals(deviceMeter);
+    }
+
+    /**
      * P4 meter features builder.
      */
     public static class P4RuntimeMeterFeaturesBuilder {