[SDFAB-453] Add a field check to MeterEntryCodec

Change-Id: I4c59c9d45f3128a7d75661fa432bfb33336965aa
diff --git a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/DirectMeterEntryCodec.java b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/DirectMeterEntryCodec.java
index 0f32417..3be0244 100644
--- a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/DirectMeterEntryCodec.java
+++ b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/DirectMeterEntryCodec.java
@@ -17,7 +17,6 @@
 package org.onosproject.p4runtime.ctl.codec;
 
 import org.onosproject.net.pi.model.PiPipeconf;
-import org.onosproject.net.pi.runtime.PiMeterBand;
 import org.onosproject.net.pi.runtime.PiMeterCellConfig;
 import org.onosproject.net.pi.runtime.PiMeterCellHandle;
 import org.onosproject.net.pi.runtime.PiMeterCellId;
@@ -79,14 +78,17 @@
             P4RuntimeOuterClass.DirectMeterEntry message, Object ignored,
             PiPipeconf pipeconf, P4InfoBrowser browser)
             throws CodecException {
-        return PiMeterCellConfig.builder()
-                .withMeterCellId(PiMeterCellId.ofDirect(
-                        CODECS.tableEntry().decode(
-                                message.getTableEntry(), null, pipeconf)))
-                .withMeterBand(new PiMeterBand(message.getConfig().getCir(),
-                                               message.getConfig().getCburst()))
-                .withMeterBand(new PiMeterBand(message.getConfig().getPir(),
-                                               message.getConfig().getPburst()))
-                .build();
+        PiMeterCellId cellId =
+            PiMeterCellId.ofDirect(
+                CODECS.tableEntry().decode(
+                    message.getTableEntry(), null, pipeconf));
+        // When a field is unset, gRPC (P4RT) will return a default value
+        // So, if the meter config is unset, the value of rate and burst will be 0,
+        // while 0 is a meaningful value and not equals to UNSET in P4RT.
+        // We cannot extract the values directly.
+        P4RuntimeOuterClass.MeterConfig p4Config =
+            message.hasConfig() ? message.getConfig() : null;
+
+        return MeterEntryCodec.getPiMeterCellConfig(cellId, p4Config);
     }
 }
diff --git a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/MeterEntryCodec.java b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/MeterEntryCodec.java
index f5e0f41..88f0639 100644
--- a/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/MeterEntryCodec.java
+++ b/protocols/p4runtime/utils/src/main/java/org/onosproject/p4runtime/ctl/codec/MeterEntryCodec.java
@@ -122,13 +122,27 @@
                 .getById(message.getMeterId())
                 .getPreamble()
                 .getName();
-        return PiMeterCellConfig.builder()
-                .withMeterCellId(PiMeterCellId.ofIndirect(
-                        PiMeterId.of(meterName), message.getIndex().getIndex()))
-                .withMeterBand(new PiMeterBand(message.getConfig().getCir(),
-                                               message.getConfig().getCburst()))
-                .withMeterBand(new PiMeterBand(message.getConfig().getPir(),
-                                               message.getConfig().getPburst()))
-                .build();
+        PiMeterCellId cellId =
+            PiMeterCellId.ofIndirect(PiMeterId.of(meterName), message.getIndex().getIndex());
+        // When a field is unset, gRPC (P4RT) will return a default value
+        // So, if the meter config is unset, the value of rate and burst will be 0,
+        // while 0 is a meaningful value and not equals to UNSET in P4RT.
+        // We cannot extract the values directly.
+        P4RuntimeOuterClass.MeterConfig p4Config =
+            message.hasConfig() ? message.getConfig() : null;
+
+        return getPiMeterCellConfig(cellId, p4Config);
+    }
+
+    public static PiMeterCellConfig getPiMeterCellConfig(
+            PiMeterCellId cellId, P4RuntimeOuterClass.MeterConfig p4Config) {
+        PiMeterCellConfig.Builder builder =
+            PiMeterCellConfig.builder().withMeterCellId(cellId);
+        if (p4Config != null) {
+            builder = builder
+                .withMeterBand(new PiMeterBand(p4Config.getCir(), p4Config.getCburst()))
+                .withMeterBand(new PiMeterBand(p4Config.getPir(), p4Config.getPburst()));
+        }
+        return builder.build();
     }
 }