[ONOS-6774] Mechanism to unregister pipeconfs in PiPipeconfService

Change-Id: If6d7b4985d3a624c9be3b831f0a3d3d4a42b0b62
diff --git a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiPipeconfService.java b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiPipeconfService.java
index 34b5174..71b63a8 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/runtime/PiPipeconfService.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/runtime/PiPipeconfService.java
@@ -41,6 +41,17 @@
     void register(PiPipeconf pipeconf) throws IllegalStateException;
 
     /**
+     * Unregisters the Pipeconf identified by the given PiPipeconfId.
+     * Unregistering a Pipeconf removes it from the ONOS controller, thus making it un-capable
+     * of controlling (e.g installing flow rules) the devices that have the pipeconf's p4 program deployed.
+     * For now this method DOES NOT remove the p4 program from the devices.
+     *
+     * @param pipeconfId a pipeconfId
+     * @throws IllegalStateException if the same pipeconf identifier is already registered.
+     */
+    void remove(PiPipeconfId pipeconfId) throws IllegalStateException;
+
+    /**
      * Returns all pipeconfs registered.
      *
      * @return a collection of pipeconfs
@@ -62,7 +73,7 @@
      * device's driver. Returns a completable future to provide async methods with a boolean if the merge
      * of the drivers succeeded.
      *
-     * @param deviceId a device identifier
+     * @param deviceId   a device identifier
      * @param pipeconfId a pipeconf identifier
      * @return a CompletableFuture with a boolean, true if operation succeeded
      */
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 000ded3..2b1b4bf 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
@@ -90,7 +90,7 @@
 
     protected ExecutorService executor =
             Executors.newFixedThreadPool(5, groupedThreads("onos/pipipeconfservice",
-                                                           "pipeline-to-device-%d", log));
+                    "pipeline-to-device-%d", log));
 
     protected final ConfigFactory factory =
             new ConfigFactory<DeviceId, PiPipeconfConfig>(
@@ -138,6 +138,16 @@
     }
 
     @Override
+    public void remove(PiPipeconfId pipeconfId) throws IllegalStateException {
+        //TODO move to the distributed mechanism
+        //TODO add mechanism to remove from device.
+        if (!piPipeconfs.containsKey(pipeconfId)) {
+            throw new IllegalStateException(format("Pipeconf %s is not registered", pipeconfId));
+        }
+        piPipeconfs.remove(pipeconfId);
+    }
+
+    @Override
     public Iterable<PiPipeconf> getPipeconfs() {
         return piPipeconfs.values();
     }
@@ -170,7 +180,7 @@
                 } catch (ItemNotFoundException e) {
 
                     log.debug("First time pipeconf {} is used with base driver {}, merging the two",
-                              pipeconfId, baseDriver);
+                            pipeconfId, baseDriver);
                     //extract the behaviours from the pipipeconf.
                     Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours = new HashMap<>();
                     piPipeconf.behaviours().forEach(b -> {
@@ -178,8 +188,8 @@
                     });
 
                     Driver piPipeconfDriver = new DefaultDriver(completeDriverName, baseDriver.parents(),
-                                                                baseDriver.manufacturer(), baseDriver.hwVersion(),
-                                                                baseDriver.swVersion(), behaviours, new HashMap<>());
+                            baseDriver.manufacturer(), baseDriver.hwVersion(),
+                            baseDriver.swVersion(), behaviours, new HashMap<>());
                     //we take the base driver created with the behaviours of the PiPeconf and
                     // merge it with the base driver that was assigned to the device
                     Driver completeDriver = piPipeconfDriver.merge(baseDriver);
diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java
index 046e93b..a733b19 100644
--- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java
+++ b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java
@@ -40,4 +40,10 @@
         pipeconfService.register(Bmv2DefaultPipeconfFactory.get());
         super.activate();
     }
+
+    @Override
+    public void deactivate() {
+        pipeconfService.remove(Bmv2DefaultPipeconfFactory.get().id());
+        super.activate();
+    }
 }