Toggle SingleSwitchFibInstaller via component config

Fix deactivation issues of vRouter components in addition
Clean up flows installed by SingleSwitchFibInstaller when it is deactivated

Change-Id: I398a38852deaafa693ea20a6cd17b9dd70053f21
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 1e61cf6..5cd78a9 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
@@ -136,6 +136,8 @@
         interfaceService.addListener(interfaceListener);
 
         readConfig();
+
+        // FIXME There can be an issue when this component is deactivated before vRouter
         applicationService.registerDeactivateHook(this.appId, () -> provisionDevice(false));
     }
 
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/DirectHostManager.java b/apps/routing/src/main/java/org/onosproject/routing/impl/DirectHostManager.java
index 7e0b2ac..d5c0d27 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/DirectHostManager.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/impl/DirectHostManager.java
@@ -113,13 +113,8 @@
     @Activate
     public void activate(ComponentContext context) {
         componentConfigService.registerProperties(getClass());
-        modified(context);
-
         appId = coreService.registerApplication(APP_NAME);
-
-        if (enabled) {
-            enable();
-        }
+        modified(context);
     }
 
     @Modified
@@ -156,7 +151,9 @@
 
     @Deactivate
     public void deactivate() {
-        disable();
+        if (enabled) {
+            disable();
+        }
 
         componentConfigService.unregisterProperties(getClass(), false);
     }
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/SingleSwitchFibInstaller.java b/apps/routing/src/main/java/org/onosproject/routing/impl/SingleSwitchFibInstaller.java
index dcdba8e..66767a0 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/SingleSwitchFibInstaller.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/impl/SingleSwitchFibInstaller.java
@@ -178,6 +178,8 @@
 
         updateConfig();
 
+        // FIXME: There can be an issue when this component is deactivated before vRouter.
+        //        This will be addressed in CORD-710.
         applicationService.registerDeactivateHook(vrouterAppId, () -> cleanUp());
 
         log.info("Started");
@@ -185,7 +187,10 @@
 
     @Deactivate
     protected void deactivate() {
-        routeService.removeListener(routeListener);
+         // FIXME: This will also remove flows when an instance goes down.
+         //        This is a temporary solution and should be addressed in CORD-710.
+        cleanUp();
+
         deviceService.removeListener(deviceListener);
         interfaceService.removeListener(internalInterfaceList);
         networkConfigService.removeListener(configListener);
@@ -292,11 +297,10 @@
     }
 
     private Set<Interface> filterInterfaces(List<String> interfaces) {
-        Set<Interface> intfs = interfaceService.getInterfaces().stream()
+        return interfaceService.getInterfaces().stream()
                 .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
                 .filter(intf -> interfaces.contains(intf.name()))
                 .collect(Collectors.toSet());
-        return intfs;
     }
 
     private void updateRoute(ResolvedRoute route) {
diff --git a/apps/vrouter/src/main/java/org/onosproject/vrouter/Vrouter.java b/apps/vrouter/src/main/java/org/onosproject/vrouter/Vrouter.java
index 562279f..afdea06 100644
--- a/apps/vrouter/src/main/java/org/onosproject/vrouter/Vrouter.java
+++ b/apps/vrouter/src/main/java/org/onosproject/vrouter/Vrouter.java
@@ -15,19 +15,24 @@
  */
 package org.onosproject.vrouter;
 
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.util.Tools;
 import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.incubator.component.ComponentService;
+import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Dictionary;
 import java.util.List;
 
 /**
@@ -39,35 +44,46 @@
     private final Logger log = LoggerFactory.getLogger(getClass());
 
     private static final String APP_NAME = "org.onosproject.vrouter";
+    private static final String FPM_MANAGER = "org.onosproject.routing.fpm.FpmManager";
+    private static final String FIB_INSTALLER = "org.onosproject.routing.impl.SingleSwitchFibInstaller";
+    private static final String CP_REDIRECT = "org.onosproject.routing.impl.ControlPlaneRedirectManager";
+    private static final String DIRECT_HOST_MGR = "org.onosproject.routing.impl.DirectHostManager";
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
+    private CoreService coreService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ComponentService componentService;
+    private ComponentService componentService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ComponentConfigService componentConfigService;
+    private ComponentConfigService componentConfigService;
+
+    /**
+     * vRouter will push flows to the switches when receiving routes by enabling
+     * FIB installer.
+     * <p>
+     * It should be turned off when vRouter is deployed in a scenario where
+     * other components that pushes the routes.
+     */
+    @Property(boolValue = true,
+            label = "Enable single switch fib installer; default is true")
+    private static final String FIB_INSTALLED_ENABLED = "fibInstalledEnabled";
 
     private ApplicationId appId;
 
-    private final List<String> components = ImmutableList.<String>builder()
-            .add("org.onosproject.routing.fpm.FpmManager")
-            .add("org.onosproject.routing.impl.SingleSwitchFibInstaller")
-            .add("org.onosproject.routing.impl.ControlPlaneRedirectManager")
-            .add("org.onosproject.routing.impl.DirectHostManager")
-            .build();
-
+    private List<String> baseComponents = Lists.newArrayList(FPM_MANAGER, CP_REDIRECT, DIRECT_HOST_MGR);
 
     @Activate
-    protected void activate() {
+    protected void activate(ComponentContext context) {
         appId = coreService.registerApplication(APP_NAME);
+        componentConfigService.registerProperties(getClass());
 
         componentConfigService.preSetProperty(
                 "org.onosproject.incubator.store.routing.impl.RouteStoreImpl",
                 "distributed", "true");
 
-        components.forEach(name -> componentService.activate(appId, name));
+        baseComponents.forEach(name -> componentService.activate(appId, name));
+        modified(context);
 
         log.info("Started");
     }
@@ -81,4 +97,20 @@
         log.info("Stopped");
     }
 
+    @Modified
+    private void modified(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+        if (properties == null) {
+            return;
+        }
+
+        boolean fibInstallerEnabled = Boolean.parseBoolean(Tools.get(properties, FIB_INSTALLED_ENABLED));
+        log.info("fibInstallerEnabled set to {}", fibInstallerEnabled);
+
+        if (fibInstallerEnabled) {
+            componentService.activate(appId, FIB_INSTALLER);
+        } else {
+            componentService.deactivate(appId, FIB_INSTALLER);
+        }
+    }
 }