New P4RuntimeClient implementation that supports batching and error reporting

The new client API supports batching and provides detailed response for
write requests (e.g. if entity already exists when inserting), which was
not possible with the old one.

This patch includes:
- New more efficient implementation of P4RuntimeClient (no more locking,
use native gRPC executor, use stub deadlines)
- Ported all codecs to new AbstractCodec-based implementation (needed to
implement codec cache in the future)
- Uses batching in P4RuntimeFlowRuleProgrammable and
P4RuntimeGroupActionProgrammable
- Minor changes to PI framework runtime classes

Change-Id: I3fac42057bb4e1389d761006a32600c786598683
diff --git a/core/store/dist/src/main/java/org/onosproject/store/pi/impl/AbstractDistributedPiTranslationStore.java b/core/store/dist/src/main/java/org/onosproject/store/pi/impl/AbstractDistributedPiTranslationStore.java
index 36d87b5..21a39bf 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/pi/impl/AbstractDistributedPiTranslationStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/pi/impl/AbstractDistributedPiTranslationStore.java
@@ -56,11 +56,11 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected StorageService storageService;
 
-    private EventuallyConsistentMap<PiHandle<E>, PiTranslatedEntity<T, E>>
+    private EventuallyConsistentMap<PiHandle, PiTranslatedEntity<T, E>>
             translatedEntities;
 
     private final EventuallyConsistentMapListener
-            <PiHandle<E>, PiTranslatedEntity<T, E>> entityMapListener =
+            <PiHandle, PiTranslatedEntity<T, E>> entityMapListener =
             new InternalEntityMapListener();
 
     /**
@@ -75,7 +75,7 @@
     public void activate() {
         final String fullMapName = format(MAP_NAME_TEMPLATE, mapSimpleName());
         translatedEntities = storageService
-                .<PiHandle<E>, PiTranslatedEntity<T, E>>eventuallyConsistentMapBuilder()
+                .<PiHandle, PiTranslatedEntity<T, E>>eventuallyConsistentMapBuilder()
                 .withName(fullMapName)
                 .withSerializer(KryoNamespaces.API)
                 .withTimestampProvider((k, v) -> new WallClockTimestamp())
@@ -92,7 +92,7 @@
     }
 
     @Override
-    public void addOrUpdate(PiHandle<E> handle, PiTranslatedEntity<T, E> entity) {
+    public void addOrUpdate(PiHandle handle, PiTranslatedEntity<T, E> entity) {
         checkNotNull(handle);
         checkNotNull(entity);
         checkArgument(handle.entityType().equals(entity.entityType()),
@@ -101,13 +101,13 @@
     }
 
     @Override
-    public void remove(PiHandle<E> handle) {
+    public void remove(PiHandle handle) {
         checkNotNull(handle);
         translatedEntities.remove(handle);
     }
 
     @Override
-    public PiTranslatedEntity<T, E> get(PiHandle<E> handle) {
+    public PiTranslatedEntity<T, E> get(PiHandle handle) {
         checkNotNull(handle);
         return translatedEntities.get(handle);
     }
@@ -118,10 +118,10 @@
 
     private class InternalEntityMapListener
             implements EventuallyConsistentMapListener
-                               <PiHandle<E>, PiTranslatedEntity<T, E>> {
+                               <PiHandle, PiTranslatedEntity<T, E>> {
 
         @Override
-        public void event(EventuallyConsistentMapEvent<PiHandle<E>,
+        public void event(EventuallyConsistentMapEvent<PiHandle,
                 PiTranslatedEntity<T, E>> event) {
             final PiTranslationEvent.Type type;
             switch (event.type()) {
diff --git a/core/store/dist/src/test/java/org/onosproject/store/pi/impl/DistributedPiTranslationStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/pi/impl/DistributedPiTranslationStoreTest.java
index acfce12..fea7392 100644
--- a/core/store/dist/src/test/java/org/onosproject/store/pi/impl/DistributedPiTranslationStoreTest.java
+++ b/core/store/dist/src/test/java/org/onosproject/store/pi/impl/DistributedPiTranslationStoreTest.java
@@ -43,9 +43,8 @@
     private static final PiTranslatable PI_TRANSLATABLE =
             new PiTranslatable() {
             };
-    private static final PiEntity PI_ENTITY = () -> PiEntityType.TABLE_ENTRY;
-    private static final PiHandle<PiEntity> PI_HANDLE =
-            new PiHandle<PiEntity>(DeviceId.NONE) {
+    private static final PiHandle PI_HANDLE =
+            new PiHandle(DeviceId.NONE) {
                 @Override
                 public PiEntityType entityType() {
                     return PI_ENTITY.piEntityType();
@@ -66,6 +65,17 @@
                     return String.valueOf(HANDLE_HASH);
                 }
             };
+    private static final PiEntity PI_ENTITY = new PiEntity() {
+        @Override
+        public PiEntityType piEntityType() {
+            return PiEntityType.TABLE_ENTRY;
+        }
+
+        @Override
+        public PiHandle handle(DeviceId deviceId) {
+            return PI_HANDLE;
+        }
+    };
     private static final PiTranslatedEntity<PiTranslatable, PiEntity> TRANSLATED_ENTITY =
             new PiTranslatedEntity<>(PI_TRANSLATABLE, PI_ENTITY, PI_HANDLE);
 
diff --git a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
index 03bf350..5437a4c 100644
--- a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
+++ b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
@@ -213,7 +213,7 @@
 import org.onosproject.net.pi.model.PiActionId;
 import org.onosproject.net.pi.model.PiActionParamId;
 import org.onosproject.net.pi.model.PiActionProfileId;
-import org.onosproject.net.pi.model.PiControlMetadataId;
+import org.onosproject.net.pi.model.PiPacketMetadataId;
 import org.onosproject.net.pi.model.PiCounterId;
 import org.onosproject.net.pi.model.PiCounterType;
 import org.onosproject.net.pi.model.PiMatchFieldId;
@@ -232,7 +232,7 @@
 import org.onosproject.net.pi.runtime.PiActionProfileMember;
 import org.onosproject.net.pi.runtime.PiActionProfileMemberHandle;
 import org.onosproject.net.pi.runtime.PiActionProfileMemberId;
-import org.onosproject.net.pi.runtime.PiControlMetadata;
+import org.onosproject.net.pi.runtime.PiPacketMetadata;
 import org.onosproject.net.pi.runtime.PiCounterCell;
 import org.onosproject.net.pi.runtime.PiCounterCellData;
 import org.onosproject.net.pi.runtime.PiCounterCellId;
@@ -676,7 +676,7 @@
                     PiActionId.class,
                     PiActionParamId.class,
                     PiActionProfileId.class,
-                    PiControlMetadataId.class,
+                    PiPacketMetadataId.class,
                     PiCounterId.class,
                     PiCounterType.class,
                     PiMatchFieldId.class,
@@ -697,7 +697,7 @@
                     PiActionProfileMemberHandle.class,
                     PiActionProfileMemberId.class,
                     PiActionParam.class,
-                    PiControlMetadata.class,
+                    PiPacketMetadata.class,
                     PiCounterCell.class,
                     PiCounterCellData.class,
                     PiCounterCellId.class,