Allow sharing the same gRPC channel between clients

This change introduces a refactoring of the gRPC protocol subsystem that
allows the creation of a gRPC chanel independently of the client, while
allowing multiple clients to share the same channel (e.g. as in Stratum
where we use 3 clients).

Moreover, we refactor the P4RuntimeClient API to support multiple
P4Runtime-internal device ID using the same client. While before the
client was associated to one of such ID.

Finally, we provide an abstract implementation for gRPC-based driver
behaviors, reducing code duplication in P4Runtime, gNMI and gNOI drivers.

Change-Id: I1a46352bbbef1e0d24042f169ae8ba580202944f
diff --git a/protocols/gnoi/api/src/main/java/org/onosproject/gnoi/api/GnoiClientKey.java b/protocols/gnoi/api/src/main/java/org/onosproject/gnoi/api/GnoiClientKey.java
deleted file mode 100644
index e246d74..0000000
--- a/protocols/gnoi/api/src/main/java/org/onosproject/gnoi/api/GnoiClientKey.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2019-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onosproject.gnoi.api;
-
-import com.google.common.annotations.Beta;
-import org.onosproject.grpc.api.GrpcClientKey;
-import org.onosproject.net.DeviceId;
-
-import java.net.URI;
-
-/**
- * Key that uniquely identifies a gNOI client.
- */
-@Beta
-public class GnoiClientKey extends GrpcClientKey {
-
-    private static final String GNOI = "gNOI";
-
-    /**
-     * Creates a new gNOI client key.
-     *
-     * @param deviceId  ONOS device ID
-     * @param serverUri gNOI server URI
-     */
-    public GnoiClientKey(DeviceId deviceId, URI serverUri) {
-        super(GNOI, deviceId, serverUri);
-    }
-}
diff --git a/protocols/gnoi/api/src/main/java/org/onosproject/gnoi/api/GnoiController.java b/protocols/gnoi/api/src/main/java/org/onosproject/gnoi/api/GnoiController.java
index b601e21..811356a 100644
--- a/protocols/gnoi/api/src/main/java/org/onosproject/gnoi/api/GnoiController.java
+++ b/protocols/gnoi/api/src/main/java/org/onosproject/gnoi/api/GnoiController.java
@@ -24,5 +24,5 @@
  */
 @Beta
 public interface GnoiController
-        extends GrpcClientController<GnoiClientKey, GnoiClient> {
+        extends GrpcClientController<GnoiClient> {
 }
diff --git a/protocols/gnoi/ctl/src/main/java/org/onosproject/gnoi/ctl/GnoiClientImpl.java b/protocols/gnoi/ctl/src/main/java/org/onosproject/gnoi/ctl/GnoiClientImpl.java
index f1f1482..84c8364 100644
--- a/protocols/gnoi/ctl/src/main/java/org/onosproject/gnoi/ctl/GnoiClientImpl.java
+++ b/protocols/gnoi/ctl/src/main/java/org/onosproject/gnoi/ctl/GnoiClientImpl.java
@@ -17,20 +17,21 @@
 package org.onosproject.gnoi.ctl;
 
 import gnoi.system.SystemGrpc;
-import gnoi.system.SystemOuterClass.TimeRequest;
-import gnoi.system.SystemOuterClass.TimeResponse;
 import gnoi.system.SystemOuterClass.RebootRequest;
 import gnoi.system.SystemOuterClass.RebootResponse;
+import gnoi.system.SystemOuterClass.TimeRequest;
+import gnoi.system.SystemOuterClass.TimeResponse;
 import io.grpc.ManagedChannel;
 import io.grpc.stub.StreamObserver;
 import org.onosproject.gnoi.api.GnoiClient;
-import org.onosproject.gnoi.api.GnoiClientKey;
 import org.onosproject.grpc.ctl.AbstractGrpcClient;
+import org.onosproject.net.DeviceId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Implementation of gNOI client.
@@ -40,8 +41,8 @@
     private static final int RPC_TIMEOUT_SECONDS = 10;
     private static final Logger log = LoggerFactory.getLogger(GnoiClientImpl.class);
 
-    GnoiClientImpl(GnoiClientKey clientKey, ManagedChannel managedChannel, GnoiControllerImpl controller) {
-        super(clientKey, managedChannel, false, controller);
+    GnoiClientImpl(DeviceId deviceId, ManagedChannel managedChannel, GnoiControllerImpl controller) {
+        super(deviceId, managedChannel, false, controller);
     }
 
     @Override
@@ -123,19 +124,4 @@
                 SystemGrpc.newStub(channel)
                         .withDeadlineAfter(RPC_TIMEOUT_SECONDS, TimeUnit.SECONDS)));
     }
-
-    /**
-     * Forces execution of an RPC in a cancellable context with no timeout.
-     *
-     * @param stubConsumer SystemStub stub consumer
-     */
-    void execRpcNoTimeout(Consumer<SystemGrpc.SystemStub> stubConsumer) {
-        if (log.isTraceEnabled()) {
-            log.trace("Executing RPC with no timeout (context deadline {})...",
-                    context().getDeadline());
-        }
-        runInCancellableContext(() -> stubConsumer.accept(
-                SystemGrpc.newStub(channel)));
-    }
-
 }
diff --git a/protocols/gnoi/ctl/src/main/java/org/onosproject/gnoi/ctl/GnoiControllerImpl.java b/protocols/gnoi/ctl/src/main/java/org/onosproject/gnoi/ctl/GnoiControllerImpl.java
index 09ef01d..445d521 100644
--- a/protocols/gnoi/ctl/src/main/java/org/onosproject/gnoi/ctl/GnoiControllerImpl.java
+++ b/protocols/gnoi/ctl/src/main/java/org/onosproject/gnoi/ctl/GnoiControllerImpl.java
@@ -19,9 +19,9 @@
 import org.onosproject.event.AbstractEvent;
 import org.onosproject.event.EventListener;
 import org.onosproject.gnoi.api.GnoiClient;
-import org.onosproject.gnoi.api.GnoiClientKey;
 import org.onosproject.gnoi.api.GnoiController;
 import org.onosproject.grpc.ctl.AbstractGrpcClientController;
+import org.onosproject.net.DeviceId;
 import org.osgi.service.component.annotations.Component;
 
 /**
@@ -29,15 +29,15 @@
  */
 @Component(immediate = true, service = GnoiController.class)
 public class GnoiControllerImpl
-        extends AbstractGrpcClientController<GnoiClientKey, GnoiClient, AbstractEvent, EventListener<AbstractEvent>>
+        extends AbstractGrpcClientController<GnoiClient, AbstractEvent, EventListener<AbstractEvent>>
         implements GnoiController {
 
     public GnoiControllerImpl() {
-        super(AbstractEvent.class);
+        super(AbstractEvent.class, "gNOI");
     }
 
     @Override
-    protected GnoiClient createClientInstance(GnoiClientKey clientKey, ManagedChannel channel) {
-        return new GnoiClientImpl(clientKey, channel, this);
+    protected GnoiClient createClientInstance(DeviceId deviceId, ManagedChannel channel) {
+        return new GnoiClientImpl(deviceId, channel, this);
     }
-}
\ No newline at end of file
+}