Add support for enabling/disabling ports for gNMI devices

This change also includes:
- Refactoring of gNMI protocol+driver to take advantage of the recent
changes to the gRPC protocol subsystem (e.g. no more locking, start RPC
with timeouts, etc.).
- Fixed Stratum driver to work after GeneralDeviceProvider refactoring
- Updated bmv2.py to generate ChassisConfig for stratum_bmv2
- Fixed portstate command to use the same port name as in the store

Change-Id: I0dad3bc73e4b6d907b5cf6b7b9a2852943226be7
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfManager.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfManager.java
index 9653091..29deb4f 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfManager.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfManager.java
@@ -25,6 +25,7 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.config.NetworkConfigRegistry;
 import org.onosproject.net.config.basics.BasicDeviceConfig;
+import org.onosproject.net.device.PortStatisticsDiscovery;
 import org.onosproject.net.driver.Behaviour;
 import org.onosproject.net.driver.DefaultDriver;
 import org.onosproject.net.driver.Driver;
@@ -283,6 +284,20 @@
                 new HashMap<>();
         pipeconf.behaviours().forEach(
                 b -> behaviours.put(b, pipeconf.implementation(b).get()));
+
+        // FIXME: remove this check when stratum_bmv2 will be open source and we
+        //  will no longer need to read port counters from the p4 program. Here
+        //  we ignore the PortStatisticsDiscovery behaviour from the pipeconf if
+        //  the base driver (e.g. stratum with gnmi) already has it. But in
+        //  general, we should give higher priority to pipeconf behaviours.
+        if (baseDriver.hasBehaviour(PortStatisticsDiscovery.class)
+                && behaviours.remove(PortStatisticsDiscovery.class) != null) {
+            log.warn("Ignoring {} behaviour from pipeconf {}, but using " +
+                             "the one provided by {} driver...",
+                     PortStatisticsDiscovery.class.getSimpleName(), pipeconfId,
+                     baseDriver.name());
+        }
+
         final Driver piPipeconfDriver = new DefaultDriver(
                 newDriverName, baseDriver.parents(),
                 baseDriver.manufacturer(), baseDriver.hwVersion(),