SONA: OpenstackSwitching - init flow rules
 - Populates flow rules when the app is initialized for existing VMs
 - Add the IP mappings for the existing VMs to DHCP service.

Change-Id: Ie73c2532c83b0c0df21261616d7af81744c0aa32
diff --git a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java
index d881d81..5a19ed0 100644
--- a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java
+++ b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java
@@ -214,6 +214,30 @@
         log.debug("port {} is removed", port.toString());
     }
 
+    private void initializeFlowRules() {
+        OpenstackSwitchingRulePopulator rulePopulator =
+                new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
+                        deviceService, restHandler, driverService);
+
+        deviceService.getDevices().forEach(device -> {
+                    log.debug("device {} num of ports {} ", device.id(),
+                            deviceService.getPorts(device.id()).size());
+                    deviceService.getPorts(device.id()).stream()
+                            .filter(port -> port.annotations().value("portName").startsWith("tap"))
+                            .forEach(vmPort -> {
+                                        OpenstackPort osPort = rulePopulator.openstackPort(vmPort);
+                                        if (osPort != null) {
+                                            rulePopulator.populateSwitchingRules(device, vmPort);
+                                            registerDhcpInfo(osPort);
+                                        } else {
+                                            log.warn("No openstackPort information for port {}", vmPort);
+                                        }
+                                    }
+                            );
+                }
+        );
+    }
+
     private void registerDhcpInfo(OpenstackPort openstackPort) {
         Ip4Address ip4Address;
         Ip4Address subnetMask;
@@ -343,6 +367,7 @@
             doNotPushFlows = cfg.doNotPushFlows();
             restHandler = new OpenstackRestHandler(cfg);
             arpHandler = new OpenstackArpHandler(restHandler, packetService);
+            initializeFlowRules();
         }
 
         @Override
diff --git a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java
index 38c0363..3d1e3fb 100644
--- a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java
+++ b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java
@@ -99,6 +99,18 @@
     }
 
     /**
+     * Returns OpenstackPort object for the Port reference given.
+     *
+     * @param port Port object
+     * @return OpenstackPort reference, or null when not found
+     */
+    public OpenstackPort openstackPort(Port port) {
+        String uuid = port.annotations().value("portName").substring(3);
+        return openstackPortList.stream().filter(p -> p.id().startsWith(uuid))
+                .findAny().orElse(null);
+    }
+
+    /**
      * Populates the flow rules for traffic to VMs in the same Cnode as the sender.
      *
      * @param device device to put the rules