Extend ControlPlaneRedirect (vRouter) to allow multiple redirects

CORD-787

Change-Id: I9e5a6f74b7239eb0dcb42b52e562698ce415debc
diff --git a/apps/routing/fibinstaller/src/main/java/org/onosproject/routing/fibinstaller/FibInstaller.java b/apps/routing/fibinstaller/src/main/java/org/onosproject/routing/fibinstaller/FibInstaller.java
index 6401679..04b4352 100644
--- a/apps/routing/fibinstaller/src/main/java/org/onosproject/routing/fibinstaller/FibInstaller.java
+++ b/apps/routing/fibinstaller/src/main/java/org/onosproject/routing/fibinstaller/FibInstaller.java
@@ -19,7 +19,6 @@
 import com.google.common.collect.ConcurrentHashMultiset;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multiset;
-import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -44,7 +43,6 @@
 import org.onosproject.incubator.net.routing.RouteEvent;
 import org.onosproject.incubator.net.routing.RouteListener;
 import org.onosproject.incubator.net.routing.RouteService;
-import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.config.ConfigFactory;
 import org.onosproject.net.config.NetworkConfigEvent;
@@ -70,9 +68,13 @@
 import org.onosproject.routing.AsyncDeviceFetcher;
 import org.onosproject.routing.NextHop;
 import org.onosproject.routing.NextHopGroupKey;
-import org.onosproject.routing.RouterInterfaceManager;
+import org.onosproject.routing.RouterInfo;
+import org.onosproject.routing.InterfaceProvisionRequest;
+import org.onosproject.routing.Router;
 import org.onosproject.routing.RoutingService;
-import org.onosproject.routing.config.RouterConfig;
+import org.onosproject.routing.config.RouterConfigHelper;
+import org.onosproject.routing.config.RoutersConfig;
+import org.onosproject.routing.config.RoutingConfigurationService;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -124,6 +126,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ApplicationService applicationService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected RoutingConfigurationService rs;
+
     @Property(name = "routeToNextHop", boolValue = false,
             label = "Install a /32 or /128 route to each next hop")
     private boolean routeToNextHop = false;
@@ -131,9 +136,7 @@
     // Device id of data-plane switch - should be learned from config
     private DeviceId deviceId;
 
-    private ConnectPoint controlPlaneConnectPoint;
-
-    private RouterInterfaceManager interfaceManager;
+    private Router interfaceManager;
     private AsyncDeviceFetcher asyncDeviceFetcher;
 
     private ApplicationId coreAppId;
@@ -207,32 +210,27 @@
     }
 
     private void processRouterConfig() {
-        RouterConfig routerConfig =
-                networkConfigService.getConfig(routerAppId, RoutingService.ROUTER_CONFIG_CLASS);
-
-        if (routerConfig == null) {
+        Set<RoutersConfig.Router> routerConfigs =
+                RouterConfigHelper.getRouterConfigurations(networkConfigService, routerAppId);
+        if (routerConfigs.isEmpty()) {
             log.info("Router config not available");
             return;
         }
+        RoutersConfig.Router routerConfig = routerConfigs.stream().findFirst().get();
 
-        Set<String> interfaces = Sets.newHashSet(routerConfig.getInterfaces());
-
-        if (deviceId == null) {
-            controlPlaneConnectPoint = routerConfig.getControlPlaneConnectPoint();
-            log.info("Control Plane Connect Point: {}", controlPlaneConnectPoint);
-
-            deviceId = routerConfig.getControlPlaneConnectPoint().deviceId();
+        if (interfaceManager == null) {
+            deviceId = routerConfig.controlPlaneConnectPoint().deviceId();
             log.info("Router device ID is {}", deviceId);
 
             routeService.addListener(routeListener);
-            asyncDeviceFetcher.getDevice(deviceId).whenComplete((deviceId, e) ->
-                    interfaceManager = createRouter(deviceId, interfaces));
+
+            interfaceManager = createRouter(RouterInfo.from(routerConfig));
         } else {
-            interfaceManager.changeConfiguredInterfaces(interfaces);
+            interfaceManager.changeConfiguration(RouterInfo.from(routerConfig));
         }
     }
 
-    /*
+    /**
      * Removes filtering objectives and routes before deactivate.
      */
     private void cleanUp() {
@@ -249,10 +247,11 @@
         }
     }
 
-    private RouterInterfaceManager createRouter(DeviceId deviceId, Set<String> configuredInterfaces) {
-        return new RouterInterfaceManager(deviceId,
-                configuredInterfaces,
+    private Router createRouter(RouterInfo info) {
+        return new Router(
+                info,
                 interfaceService,
+                deviceService,
                 this::provisionInterface,
                 this::unprovisionInterface);
     }
@@ -410,11 +409,11 @@
         return group;
     }*/
 
-    private void provisionInterface(Interface intf) {
+    private void provisionInterface(InterfaceProvisionRequest intf) {
         updateInterfaceFilters(intf, true);
     }
 
-    private void unprovisionInterface(Interface intf) {
+    private void unprovisionInterface(InterfaceProvisionRequest intf) {
         updateInterfaceFilters(intf, false);
     }
 
@@ -424,7 +423,7 @@
      * @param intf interface to update objectives for
      * @param install true to install the objectives, false to remove them
      */
-    private void updateInterfaceFilters(Interface intf, boolean install) {
+    private void updateInterfaceFilters(InterfaceProvisionRequest intf, boolean install) {
         updateFilteringObjective(intf, install);
         updateMcastFilteringObjective(intf, install);
     }
@@ -432,10 +431,11 @@
     /**
      * Installs or removes unicast filtering objectives relating to an interface.
      *
-     * @param intf interface to update objectives for
+     * @param routerIntf interface to update objectives for
      * @param install true to install the objectives, false to remove them
      */
-    private void updateFilteringObjective(Interface intf, boolean install) {
+    private void updateFilteringObjective(InterfaceProvisionRequest routerIntf, boolean install) {
+        Interface intf = routerIntf.intf();
         VlanId assignedVlan = (egressVlan().equals(VlanId.NONE)) ?
                 VlanId.vlanId(ASSIGNED_VLAN) :
                 egressVlan();
@@ -454,20 +454,19 @@
         fob.permit().fromApp(fibAppId);
         sendFilteringObjective(install, fob, intf);
 
-        if (controlPlaneConnectPoint != null) {
-            // then add the same mac/vlan filters for control-plane connect point
-            fob.withKey(Criteria.matchInPort(controlPlaneConnectPoint.port()));
-            sendFilteringObjective(install, fob, intf);
-        }
+        // then add the same mac/vlan filters for control-plane connect point
+        fob.withKey(Criteria.matchInPort(routerIntf.controlPlaneConnectPoint().port()));
+        sendFilteringObjective(install, fob, intf);
     }
 
     /**
      * Installs or removes multicast filtering objectives relating to an interface.
      *
-     * @param intf interface to update objectives for
+     * @param routerIntf interface to update objectives for
      * @param install true to install the objectives, false to remove them
      */
-    private void updateMcastFilteringObjective(Interface intf, boolean install) {
+    private void updateMcastFilteringObjective(InterfaceProvisionRequest routerIntf, boolean install) {
+        Interface intf = routerIntf.intf();
         VlanId assignedVlan = (egressVlan().equals(VlanId.NONE)) ?
                 VlanId.vlanId(ASSIGNED_VLAN) :
                 egressVlan();