Refactor P4Runtime subsystem to implement async connection procedure

This patch is an attempt to solve issues observed when restarting both
switches and ONOS nodes. Most of the issues seemed to depend on a
brittle mastership handling when deploying the pipeline.

With this patch, GDP registers devices to the core with available=false
(i.e. offline) and marks them online only when the P4 pipeline has been
deployed to the device. A new PiPipeconfWatchdogService takes care of
deploying pipelines and producing event when devices are ready.

Moreover, we fix a race condition where pipeconf-related behaviors
were not found. This was caused by GDP enforcing the merged
driver name in the network config, while external entities (e.g.
Mininet) were pushing a JSON blob with the base driver name. This patch
removes the need to rely on such a trick and instead uses
pipeconf-aware logic directly in the driver manager (change #19622).

Finally, we fix issues in P4RuntimeClientImpl that were causing the
stream channel not detecting unreachable devices. The solution is to
follow gRPC APIs and re-instantiate a new channel once the first fails.

Change-Id: I6fbc91859c0fb58a6db3bc197b7081a8fe9f97f7
diff --git a/core/api/src/main/java/org/onosproject/net/driver/DeviceConnect.java b/core/api/src/main/java/org/onosproject/net/driver/DeviceConnect.java
index 2f53620..f30386d 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/DeviceConnect.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/DeviceConnect.java
@@ -20,27 +20,38 @@
 import java.util.concurrent.CompletableFuture;
 
 /**
- * Abstraction of handler behaviour used to set-up and tear-down
- * connection with a device.
+ * Abstraction of handler behaviour used to set-up and tear-down connections
+ * with a device.
  */
 @Beta
 public interface DeviceConnect extends HandlerBehaviour {
 
     /**
-     * Connects to the device.
-     * It's supposed to initiate the transport sessions, channel and also,
-     * if applicable, store them in the proper protocol specific
-     * controller (e.g. GrpcController).
+     * Connects to the device, for example by opening the transport session that
+     * will be later used to send control messages. Returns true if the
+     * connection was initiated successfully, false otherwise.
+     * <p>
+     * Calling multiple times this method while a connection to the device is
+     * open should result in a no-op.
      *
      * @return CompletableFuture with true if the operation was successful
      */
     CompletableFuture<Boolean> connect();
 
     /**
-     * Disconnects from the device.
-     * It's supposed to destroy the transport sessions and channel and also,
-     * if applicable, remove them in the proper protocol specific
-     * controller (e.g. GrpcController).
+     * Returns true if a connection to the device is open, false otherwise.
+     *
+     * @return true if the connection is open, false otherwise
+     */
+    boolean isConnected();
+
+    /**
+     * Disconnects from the device, for example closing the transport session
+     * previously opened. Returns true if the disconnection procedure was
+     * successful, false otherwise.
+     * <p>
+     * Calling multiple times this method while a connection to the device is
+     * closed should result in a no-op.
      *
      * @return CompletableFuture with true if the operation was successful
      */