Added interfaces configuration to allow vRouter to be selective about what
interfaces to use.

Change-Id: I4eb069760df0995d9e831e024ddbc0493bccce0b
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/config/RouterConfig.java b/apps/routing-api/src/main/java/org/onosproject/routing/config/RouterConfig.java
index cfe719d..9099019 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/config/RouterConfig.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/config/RouterConfig.java
@@ -16,10 +16,16 @@
 
 package org.onosproject.routing.config;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.config.Config;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * Routing configuration.
  */
@@ -28,6 +34,7 @@
     private static final String CP_CONNECT_POINT = "controlPlaneConnectPoint";
     private static final String OSPF_ENABLED = "ospfEnabled";
     private static final String PIM_ENABLED = "pimEnabled";
+    private static final String INTERFACES = "interfaces";
 
     /**
      * Returns the routing control plane connect point.
@@ -55,4 +62,24 @@
     public boolean pimEnabled() {
         return object.path(PIM_ENABLED).asBoolean(false);
     }
+
+    /**
+     * Returns the list of interfaces enabled on this router.
+     *
+     * @return list of interface names that are enabled, or an empty list if
+     * all available interfaces should be used
+     */
+    public List<String> getInterfaces() {
+        JsonNode intfNode = object.path(INTERFACES);
+        if (intfNode.isMissingNode() || !intfNode.isArray()) {
+            return Collections.emptyList();
+        }
+        ArrayNode array = (ArrayNode) intfNode;
+        List<String> interfaces = new ArrayList<>(array.size());
+        for (JsonNode intf : array) {
+            interfaces.add(intf.asText());
+        }
+        return interfaces;
+    }
+
 }
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 b78b0ff..54a6966 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
@@ -50,6 +50,9 @@
 import org.onosproject.routing.config.RouterConfig;
 import org.slf4j.Logger;
 
+import java.util.Collections;
+import java.util.List;
+
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -69,6 +72,7 @@
 
     private ConnectPoint controlPlaneConnectPoint;
     private boolean ospfEnabled = false;
+    private List<String> interfaces = Collections.emptyList();
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
@@ -119,6 +123,7 @@
 
         controlPlaneConnectPoint = config.getControlPlaneConnectPoint();
         ospfEnabled = config.getOspfEnabled();
+        interfaces = config.getInterfaces();
 
         updateDevice();
     }
@@ -130,6 +135,7 @@
 
             interfaceService.getInterfaces().stream()
                     .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
+                    .filter(intf -> interfaces.isEmpty() || interfaces.contains(intf.name()))
                     .forEach(this::provisionInterface);
 
             log.info("Set up interfaces on {}", controlPlaneConnectPoint.deviceId());
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 ee9958c..99ecaf3 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
@@ -67,8 +67,10 @@
 
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Programs routes to a single OpenFlow switch.
@@ -108,6 +110,8 @@
 
     private ConnectPoint controlPlaneConnectPoint;
 
+    private List<String> interfaces;
+
     private ApplicationId routerAppId;
 
     // Reference count for how many times a next hop is used by a route
@@ -161,15 +165,29 @@
         log.info("Control Plane Connect Point: {}", controlPlaneConnectPoint);
 
         deviceId = routerConfig.getControlPlaneConnectPoint().deviceId();
-
         log.info("Router device ID is {}", deviceId);
 
+        interfaces = routerConfig.getInterfaces();
+        log.info("Using interfaces: {}", interfaces.isEmpty() ? "all" : interfaces);
+
         updateDevice();
     }
 
     private void updateDevice() {
         if (deviceId != null && deviceService.isAvailable(deviceId)) {
-            processIntfFilters(true, interfaceService.getInterfaces());
+
+            Set<Interface> intfs;
+            if (interfaces.isEmpty()) {
+                intfs = interfaceService.getInterfaces();
+            } else {
+                // TODO need to fix by making interface names globally unique
+                intfs = interfaceService.getInterfaces().stream()
+                        .filter(intf -> intf.connectPoint().deviceId().equals(deviceId))
+                        .filter(intf -> interfaces.contains(intf.name()))
+                        .collect(Collectors.toSet());
+            }
+
+            processIntfFilters(true, intfs);
         }
     }