ControlPlaneRedirectManager.java, Cleaning flows on Deactivating the app

Change-Id: I06c9c2dd286f02ad84a1c01bfa5b7202988b0402
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java b/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java
index 90d0905..49dc0ed 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java
@@ -27,6 +27,7 @@
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
+import org.onosproject.app.ApplicationService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.incubator.net.intf.Interface;
@@ -85,7 +86,7 @@
     private static final int ACL_PRIORITY = 40001;
     private static final int OSPF_IP_PROTO = 0x59;
 
-    private static final String APP_NAME = "org.onosproject.cpredirect";
+    private static final String APP_NAME = "org.onosproject.vrouter";
     private ApplicationId appId;
 
     private ConnectPoint controlPlaneConnectPoint;
@@ -114,6 +115,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected HostService hostService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ApplicationService applicationService;
+
     private final InternalDeviceListener deviceListener = new InternalDeviceListener();
     private final InternalNetworkConfigListener networkConfigListener =
             new InternalNetworkConfigListener();
@@ -129,7 +133,10 @@
         hostService.addListener(hostListener);
         interfaceService.addListener(interfaceListener);
 
-        updateConfig();
+        updateConfig(true);
+        applicationService.registerDeactivateHook(this.appId, () -> {
+            this.updateConfig(false);
+        });
     }
 
     @Deactivate
@@ -140,7 +147,14 @@
         interfaceService.removeListener(interfaceListener);
     }
 
-    private void updateConfig() {
+    /**
+     * Installs or removes interface configuration
+     * based on the flag used on activate or deactivate.
+     *
+     * @param operation true on activate application, false on deactivate
+     *            the application
+     **/
+    private void updateConfig(boolean operation) {
         ApplicationId routingAppId =
                 coreService.registerApplication(RoutingService.ROUTER_APP_ID);
 
@@ -156,10 +170,17 @@
         ospfEnabled = config.getOspfEnabled();
         interfaces = config.getInterfaces();
 
-        updateDevice();
+        updateDevice(operation);
     }
 
-    private void updateDevice() {
+    /**
+     * Installs or removes interface configuration for each interface
+     * based on the flag used on activate or deactivate.
+     *
+     * @param operation true on activate application, false on deactivate
+     *            the application
+     **/
+    private void updateDevice(boolean operation) {
         if (controlPlaneConnectPoint != null &&
                 deviceService.isAvailable(controlPlaneConnectPoint.deviceId())) {
             DeviceId deviceId = controlPlaneConnectPoint.deviceId();
@@ -167,7 +188,7 @@
             interfaceService.getInterfaces().stream()
                     .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
                     .filter(intf -> interfaces.isEmpty() || interfaces.contains(intf.name()))
-                    .forEach(this::provisionInterface);
+                    .forEach(operation ? this::provisionInterface : this::removeInterface);
 
             log.info("Set up interfaces on {}", controlPlaneConnectPoint.deviceId());
         }
@@ -383,7 +404,7 @@
                 case DEVICE_AVAILABILITY_CHANGED:
                     if (deviceService.isAvailable(event.subject().id())) {
                         log.info("Device connected {}", event.subject().id());
-                        updateDevice();
+                        updateDevice(true);
                     }
                     break;
                 case DEVICE_UPDATED:
@@ -410,7 +431,7 @@
                 switch (event.type()) {
                 case CONFIG_ADDED:
                 case CONFIG_UPDATED:
-                    updateConfig();
+                    updateConfig(true);
                     break;
                 case CONFIG_REGISTERED:
                 case CONFIG_UNREGISTERED:
diff --git a/apps/routing/src/test/java/org/onosproject/routing/impl/ControlPlaneRedirectManagerTest.java b/apps/routing/src/test/java/org/onosproject/routing/impl/ControlPlaneRedirectManagerTest.java
index 8f61ddb..59f1fc2 100644
--- a/apps/routing/src/test/java/org/onosproject/routing/impl/ControlPlaneRedirectManagerTest.java
+++ b/apps/routing/src/test/java/org/onosproject/routing/impl/ControlPlaneRedirectManagerTest.java
@@ -24,6 +24,7 @@
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
+import org.onosproject.app.ApplicationService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.core.CoreServiceAdapter;
@@ -89,7 +90,7 @@
     private static final int OSPF_IP_PROTO = 0x59;
     private CoreService coreService = new TestCoreService();
     private InterfaceService interfaceService;
-    private static final ApplicationId APPID = TestApplicationId.create("org.onosproject.cpredirect");
+    private static final ApplicationId APPID = TestApplicationId.create("org.onosproject.vrouter");
 
     private static final DeviceId DEVICE_ID = DeviceId.deviceId("of:0000000000000001");
 
@@ -111,6 +112,7 @@
     private DeviceListener deviceListener;
     private MastershipService mastershipService = new InternalMastershipServiceTest();
     private InterfaceListener interfaceListener;
+    private ApplicationService applicationService;
 
     @Before
     public void setUp() {
@@ -126,6 +128,8 @@
         networkConfigService = new TestNetworkConfigService();
         networkConfigService.addListener(networkConfigListener);
         flowObjectiveService = createMock(FlowObjectiveService.class);
+        applicationService = createNiceMock(ApplicationService.class);
+        replay(applicationService);
         setUpFlowObjectiveService();
         controlPlaneRedirectManager.coreService = coreService;
         controlPlaneRedirectManager.flowObjectiveService = flowObjectiveService;
@@ -134,6 +138,7 @@
         controlPlaneRedirectManager.deviceService = deviceService;
         controlPlaneRedirectManager.hostService = createNiceMock(HostService.class);
         controlPlaneRedirectManager.mastershipService = mastershipService;
+        controlPlaneRedirectManager.applicationService = applicationService;
         controlPlaneRedirectManager.activate();
         verify(flowObjectiveService);
     }