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/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClientKey.java b/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClientKey.java
deleted file mode 100644
index 3a66c18..0000000
--- a/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiClientKey.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2018-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.gnmi.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 gNMI client.
- */
-@Beta
-public class GnmiClientKey extends GrpcClientKey {
-
-    private static final String GNMI = "gNMI";
-
-    /**
-     * Creates a new gNMI client key.
-     *
-     * @param deviceId  ONOS device ID
-     * @param serverUri gNMI server URI
-     */
-    public GnmiClientKey(DeviceId deviceId, URI serverUri) {
-        super(GNMI, deviceId, serverUri);
-    }
-}
diff --git a/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiController.java b/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiController.java
index b0e0071..4794570 100644
--- a/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiController.java
+++ b/protocols/gnmi/api/src/main/java/org/onosproject/gnmi/api/GnmiController.java
@@ -25,6 +25,6 @@
  */
 @Beta
 public interface GnmiController
-        extends GrpcClientController<GnmiClientKey, GnmiClient>,
+        extends GrpcClientController<GnmiClient>,
         ListenerService<GnmiEvent, GnmiEventListener> {
 }
diff --git a/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiClientImpl.java b/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiClientImpl.java
index 8d93a63..47daa83 100644
--- a/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiClientImpl.java
+++ b/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiClientImpl.java
@@ -30,8 +30,8 @@
 import io.grpc.Status;
 import io.grpc.stub.StreamObserver;
 import org.onosproject.gnmi.api.GnmiClient;
-import org.onosproject.gnmi.api.GnmiClientKey;
 import org.onosproject.grpc.ctl.AbstractGrpcClient;
+import org.onosproject.net.DeviceId;
 
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
@@ -51,8 +51,9 @@
 
     private GnmiSubscriptionManager subscribeManager;
 
-    GnmiClientImpl(GnmiClientKey clientKey, ManagedChannel managedChannel, GnmiControllerImpl controller) {
-        super(clientKey, managedChannel, false, controller);
+    GnmiClientImpl(DeviceId deviceId, ManagedChannel managedChannel,
+                   GnmiControllerImpl controller) {
+        super(deviceId, managedChannel, false, controller);
         this.subscribeManager =
                 new GnmiSubscriptionManager(this, deviceId, controller);
     }
diff --git a/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiControllerImpl.java b/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiControllerImpl.java
index 9c4643a..42d31db 100644
--- a/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiControllerImpl.java
+++ b/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiControllerImpl.java
@@ -18,11 +18,11 @@
 
 import io.grpc.ManagedChannel;
 import org.onosproject.gnmi.api.GnmiClient;
-import org.onosproject.gnmi.api.GnmiClientKey;
 import org.onosproject.gnmi.api.GnmiController;
 import org.onosproject.gnmi.api.GnmiEvent;
 import org.onosproject.gnmi.api.GnmiEventListener;
 import org.onosproject.grpc.ctl.AbstractGrpcClientController;
+import org.onosproject.net.DeviceId;
 import org.osgi.service.component.annotations.Component;
 
 /**
@@ -31,16 +31,16 @@
 @Component(immediate = true, service = GnmiController.class)
 public class GnmiControllerImpl
         extends AbstractGrpcClientController
-        <GnmiClientKey, GnmiClient, GnmiEvent, GnmiEventListener>
+        <GnmiClient, GnmiEvent, GnmiEventListener>
         implements GnmiController {
 
     public GnmiControllerImpl() {
-        super(GnmiEvent.class);
+        super(GnmiEvent.class, "gNMI");
     }
 
     @Override
     protected GnmiClient createClientInstance(
-            GnmiClientKey clientKey, ManagedChannel channel) {
-        return new GnmiClientImpl(clientKey, channel, this);
+            DeviceId deviceId, ManagedChannel channel) {
+        return new GnmiClientImpl(deviceId, channel, this);
     }
 }
diff --git a/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiSubscriptionManager.java b/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiSubscriptionManager.java
index 73bb807..a33f4b6 100644
--- a/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiSubscriptionManager.java
+++ b/protocols/gnmi/ctl/src/main/java/org/onosproject/gnmi/ctl/GnmiSubscriptionManager.java
@@ -77,7 +77,7 @@
                 if (existingSubscription.equals(request)) {
                     // Nothing to do. We are already subscribed for the same
                     // request.
-                    log.debug("Ignoring re-subscription to same request",
+                    log.debug("Ignoring re-subscription to same request for {}",
                               deviceId);
                     return;
                 }