Add configuration setting to allow one switch to use the Corsa driver.

Change-Id: I6b17098e6d7c31a2d19ccbb0b5a56bd3b5b1e33a
diff --git a/openflow/ctl/pom.xml b/openflow/ctl/pom.xml
index 907160f..624b667 100644
--- a/openflow/ctl/pom.xml
+++ b/openflow/ctl/pom.xml
@@ -48,6 +48,10 @@
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.scr.annotations</artifactId>
         </dependency>
+	<dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java
index 23fd149..22a9cfc 100644
--- a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java
+++ b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java
@@ -89,7 +89,7 @@
         // We return a copy of the mapping so we can guarantee that
         // the mapping return is the same as one that will be (or was)
         // dispatched to IHAListeners
-        HashMap<String, String> retval = new HashMap<String, String>();
+        HashMap<String, String> retval = new HashMap<>();
         synchronized (controllerNodeIPsCache) {
             retval.putAll(controllerNodeIPsCache);
         }
@@ -152,6 +152,15 @@
         if (ofPort != null) {
             this.openFlowPort = Integer.parseInt(ofPort);
         }
+        String corsaDpid = configParams.get("corsaDpid");
+        if (corsaDpid != null) {
+            try {
+                DriverManager.setCorsaDpid(new Dpid(corsaDpid));
+                log.info("Corsa DPID set to {}", corsaDpid);
+            } catch (NumberFormatException e) {
+                log.warn("Malformed Corsa DPID string", e);
+            }
+        }
         log.debug("OpenFlow port set to {}", this.openFlowPort);
         String threads = configParams.get("workerthreads");
         this.workerThreads = threads != null ? Integer.parseInt(threads) : 16;
@@ -161,18 +170,13 @@
 
     /**
      * Initialize internal data structures.
-     *
-     * @param configParams configuration parameters
      */
-    public void init(Map<String, String> configParams) {
+    public void init() {
         // These data structures are initialized here because other
         // module's startUp() might be called before ours
-        this.controllerNodeIPsCache = new HashMap<String, String>();
+        this.controllerNodeIPsCache = new HashMap<>();
 
-        setConfigParams(configParams);
         this.systemStartTime = System.currentTimeMillis();
-
-
     }
 
     // **************
@@ -180,7 +184,7 @@
     // **************
 
     public Map<String, Long> getMemory() {
-        Map<String, Long> m = new HashMap<String, Long>();
+        Map<String, Long> m = new HashMap<>();
         Runtime runtime = Runtime.getRuntime();
         m.put("total", runtime.totalMemory());
         m.put("free", runtime.freeMemory());
@@ -213,7 +217,7 @@
     public void start(OpenFlowAgent ag) {
         log.info("Starting OpenFlow IO");
         this.agent = ag;
-        this.init(new HashMap<String, String>());
+        this.init();
         this.run();
     }
 
diff --git a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
index a98f000..762a8f5 100644
--- a/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
+++ b/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
@@ -22,6 +22,7 @@
 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.Service;
 import org.onosproject.openflow.controller.DefaultOpenFlowPacketContext;
 import org.onosproject.openflow.controller.Dpid;
@@ -33,6 +34,7 @@
 import org.onosproject.openflow.controller.PacketListener;
 import org.onosproject.openflow.controller.RoleState;
 import org.onosproject.openflow.controller.driver.OpenFlowAgent;
+import org.osgi.service.component.ComponentContext;
 import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus;
 import org.projectfloodlight.openflow.protocol.OFExperimenter;
 import org.projectfloodlight.openflow.protocol.OFFactories;
@@ -52,7 +54,10 @@
 import org.slf4j.LoggerFactory;
 
 import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
@@ -102,7 +107,9 @@
     private final Controller ctrl = new Controller();
 
     @Activate
-    public void activate() {
+    public void activate(ComponentContext context) {
+        Map<String, String> properties = readComponentConfiguration(context);
+        ctrl.setConfigParams(properties);
         ctrl.start(agent);
     }
 
@@ -111,6 +118,32 @@
         ctrl.stop();
     }
 
+    /**
+     * Extracts properties from the component configuration context.
+     *
+     * @param context the component context
+     */
+    private Map<String, String> readComponentConfiguration(ComponentContext context) {
+        Dictionary<?, ?> properties = context.getProperties();
+        Map<String, String> outProperties = new HashMap<>();
+        try {
+            String strDpid = (String) properties.get("corsaDpid");
+            if (strDpid != null) {
+                outProperties.put("corsaDpid", strDpid);
+            }
+        } catch (ClassCastException e) {
+            return outProperties;
+        }
+        return outProperties;
+    }
+
+    @Modified
+    public void modified(ComponentContext context) {
+        // Blank @Modified method to catch modifications to the context.
+        // If no @Modified method exists, @Activate is called again
+        // when the context is modified.
+    }
+
     @Override
     public Iterable<OpenFlowSwitch> getSwitches() {
         return connectedSwitches.values();
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/DriverManager.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/DriverManager.java
index 46f8e57..17f79f3 100644
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/DriverManager.java
+++ b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/DriverManager.java
@@ -16,9 +16,6 @@
 package org.onosproject.openflow.drivers;
 
 
-import java.util.Collections;
-import java.util.List;
-
 import org.onosproject.openflow.controller.Dpid;
 import org.onosproject.openflow.controller.RoleState;
 import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
@@ -33,6 +30,9 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Collections;
+import java.util.List;
+
 /**
  * A simple implementation of a driver manager that differentiates between
  * connected switches using the OF Description Statistics Reply message.
@@ -43,6 +43,8 @@
 
     private static final int LOWEST_PRIORITY = 0;
 
+    private static Dpid corsaDpid = new Dpid();
+
     /**
      * Return an IOFSwitch object based on switch's manufacturer description
      * from OFDescStatsReply.
@@ -56,6 +58,11 @@
             OFDescStatsReply desc, OFVersion ofv) {
         String vendor = desc.getMfrDesc();
         String hw = desc.getHwDesc();
+
+        if (dpid.equals(corsaDpid)) {
+            return new OFCorsaSwitchDriver(dpid, desc);
+        }
+
         if (vendor.startsWith("Stanford University, Ericsson Research and CPqD Research")
                 &&
                 hw.startsWith("OpenFlow 1.3 Reference Userspace Switch")) {
@@ -83,7 +90,7 @@
         }
 
         log.warn("DriverManager could not identify switch desc: {}. "
-                + "Assigning AbstractOpenFlowSwich", desc);
+                         + "Assigning AbstractOpenFlowSwich", desc);
         return new AbstractOpenFlowSwitch(dpid, desc) {
 
             @Override
@@ -157,4 +164,8 @@
         return new DriverManager().getOFSwitchImpl(dpid, desc, ofv);
     }
 
+    public static void setCorsaDpid(Dpid dpid) {
+        corsaDpid = dpid;
+    }
+
 }