ONOS-3411 Disconnect switches and stop stat collectors when openflow-base is being deactivated

Change-Id: I9a1b5fbb60a9e7135cd586fe717c18f83e3d864d
diff --git a/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java b/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
index b97c336..b410158 100644
--- a/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
+++ b/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
@@ -27,6 +27,7 @@
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
 import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.core.CoreService;
 import org.onosproject.net.driver.DefaultDriverProviderService;
 import org.onosproject.net.driver.DriverService;
 import org.onosproject.openflow.controller.DefaultOpenFlowPacketContext;
@@ -83,6 +84,7 @@
 @Component(immediate = true)
 @Service
 public class OpenFlowControllerImpl implements OpenFlowController {
+    private static final String APP_ID = "org.onosproject.openflow-base";
     private static final String DEFAULT_OFPORT = "6633,6653";
     private static final int DEFAULT_WORKER_THREADS = 16;
 
@@ -90,6 +92,9 @@
             LoggerFactory.getLogger(OpenFlowControllerImpl.class);
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DriverService driverService;
 
     // References exists merely for sequencing purpose to assure drivers are loaded
@@ -147,15 +152,24 @@
 
     @Activate
     public void activate(ComponentContext context) {
+        coreService.registerApplication(APP_ID, this::preDeactivate);
         cfgService.registerProperties(getClass());
         ctrl.setConfigParams(context.getProperties());
         ctrl.start(agent, driverService);
     }
 
+    private void preDeactivate() {
+        // Close listening channel and all OF channels before deactivating
+        ctrl.stop();
+        connectedSwitches.values().forEach(OpenFlowSwitch::disconnectSwitch);
+    }
+
     @Deactivate
     public void deactivate() {
         cfgService.unregisterProperties(getClass(), false);
-        ctrl.stop();
+        connectedSwitches.clear();
+        activeMasterSwitches.clear();
+        activeEqualSwitches.clear();
     }
 
     @Modified