Fix: install flow rules to corresponding GW by listening fip events

Change-Id: Iece92a37181b1c4bf71a55ffd00b8bb080ae2fa9
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
index 0319d40..e938a90 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
@@ -97,7 +97,7 @@
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ARP_GATEWAY_RULE;
 import static org.onosproject.openstacknetworking.impl.HostBasedInstancePort.ANNOTATION_NETWORK_ID;
 import static org.onosproject.openstacknetworking.impl.HostBasedInstancePort.ANNOTATION_PORT_ID;
-import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByComputeDevId;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -243,7 +243,9 @@
                 return;
             }
 
-            OpenstackNode gw = getGwByTargetMac(osNodeService.completeNodes(GATEWAY), targetMac);
+            InstancePort instPort = instancePortService.instancePort(targetMac);
+
+            OpenstackNode gw = getGwByInstancePort(osNodeService.completeNodes(GATEWAY), instPort);
 
             if (gw == null) {
                 return;
@@ -443,8 +445,9 @@
             }
 
             MacAddress targetMac = MacAddress.valueOf(macString);
+            InstancePort instPort = instancePortService.instancePort(targetMac);
 
-            OpenstackNode gw = getGwByTargetMac(gateways, targetMac);
+            OpenstackNode gw = getGwByInstancePort(gateways, instPort);
 
             if (gw == null) {
                 return;
@@ -483,17 +486,6 @@
         }
     }
 
-    // a helper method
-    private OpenstackNode getGwByTargetMac(Set<OpenstackNode> gateways,
-                                           MacAddress targetMac) {
-        InstancePort instPort = instancePortService.instancePort(targetMac);
-        OpenstackNode gw = null;
-        if (instPort != null && instPort.deviceId() != null) {
-            gw = getGwByComputeDevId(gateways, instPort.deviceId());
-        }
-        return gw;
-    }
-
     /**
      * An internal router event listener, intended to install/uninstall
      * ARP rules for forwarding packets created from floating IPs.
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
index dda949f..6493fc8 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
@@ -188,7 +188,6 @@
             throw new IllegalStateException(error);
         }
 
-
         ExternalPeerRouter externalPeerRouter = externalPeerRouter(osNet);
         if (externalPeerRouter == null) {
             final String errorFormat = ERR_FLOW + "no external peer router found";
@@ -221,33 +220,42 @@
         Set<OpenstackNode> finalGws = Sets.newConcurrentHashSet();
         finalGws.addAll(ImmutableSet.copyOf(completedGws));
 
-        if (install) {
-            if (completedGws.contains(gateway)) {
-                if (completedGws.size() > 1) {
-                    finalGws.remove(gateway);
-                    if (fip.getPortId() != null) {
-                        setDownstreamExternalRulesHelper(fip, osNet, instPort, router,
-                                ImmutableSet.copyOf(finalGws), false);
-                        finalGws.add(gateway);
-                    }
-                }
-                if (fip.getPortId() != null) {
-                    setDownstreamExternalRulesHelper(fip, osNet, instPort, router,
-                            ImmutableSet.copyOf(finalGws), true);
-                }
-            } else {
-                log.warn("Detected node should be included in completed gateway set");
-            }
+
+        if (gateway == null) {
+            // these are floating IP related cases...
+            setDownstreamExternalRulesHelper(fip, osNet, instPort, router,
+                                        ImmutableSet.copyOf(finalGws), install);
+
         } else {
-            if (!completedGws.contains(gateway)) {
-                if (completedGws.size() >= 1) {
+            // these are openstack node related cases...
+            if (install) {
+                if (completedGws.contains(gateway)) {
+                    if (completedGws.size() > 1) {
+                        finalGws.remove(gateway);
+                        if (fip.getPortId() != null) {
+                            setDownstreamExternalRulesHelper(fip, osNet, instPort, router,
+                                    ImmutableSet.copyOf(finalGws), false);
+                            finalGws.add(gateway);
+                        }
+                    }
                     if (fip.getPortId() != null) {
                         setDownstreamExternalRulesHelper(fip, osNet, instPort, router,
                                 ImmutableSet.copyOf(finalGws), true);
                     }
+                } else {
+                    log.warn("Detected node should be included in completed gateway set");
                 }
             } else {
-                log.warn("Detected node should NOT be included in completed gateway set");
+                if (!completedGws.contains(gateway)) {
+                    if (completedGws.size() >= 1) {
+                        if (fip.getPortId() != null) {
+                            setDownstreamExternalRulesHelper(fip, osNet, instPort, router,
+                                    ImmutableSet.copyOf(finalGws), true);
+                        }
+                    }
+                } else {
+                    log.warn("Detected node should NOT be included in completed gateway set");
+                }
             }
         }
     }
@@ -634,15 +642,6 @@
                                 osFip.getFloatingIpAddress(), osFip.getFixedIpAddress());
                     });
                     break;
-                case OPENSTACK_FLOATING_IP_REMOVED:
-                    eventExecutor.execute(() -> {
-                        NetFloatingIP osFip = event.floatingIp();
-                        if (!Strings.isNullOrEmpty(osFip.getPortId())) {
-                            disassociateFloatingIp(osFip, osFip.getPortId());
-                        }
-                        log.info("Removed floating IP {}", osFip.getFloatingIpAddress());
-                    });
-                    break;
                 case OPENSTACK_FLOATING_IP_CREATED:
                     eventExecutor.execute(() -> {
                         NetFloatingIP osFip = event.floatingIp();
@@ -652,6 +651,15 @@
                         log.info("Created floating IP {}", osFip.getFloatingIpAddress());
                     });
                     break;
+                case OPENSTACK_FLOATING_IP_REMOVED:
+                    eventExecutor.execute(() -> {
+                        NetFloatingIP osFip = event.floatingIp();
+                        if (!Strings.isNullOrEmpty(osFip.getPortId())) {
+                            disassociateFloatingIp(osFip, osFip.getPortId());
+                        }
+                        log.info("Removed floating IP {}", osFip.getFloatingIpAddress());
+                    });
+                    break;
                 case OPENSTACK_FLOATING_IP_UPDATED:
                 case OPENSTACK_ROUTER_CREATED:
                 case OPENSTACK_ROUTER_UPDATED:
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
index f3c5d92..6a42902 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
@@ -19,6 +19,7 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.onosproject.net.DeviceId;
+import org.onosproject.openstacknetworking.api.InstancePort;
 import org.onosproject.openstacknode.api.OpenstackAuth;
 import org.onosproject.openstacknode.api.OpenstackAuth.Perspective;
 import org.onosproject.openstacknode.api.OpenstackNode;
@@ -29,8 +30,8 @@
 import org.openstack4j.core.transport.Config;
 import org.openstack4j.core.transport.ObjectMapperSingleton;
 import org.openstack4j.model.ModelEntity;
-import org.openstack4j.model.network.Port;
 import org.openstack4j.model.common.Identifier;
+import org.openstack4j.model.network.Port;
 import org.openstack4j.openstack.OSFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -119,6 +120,22 @@
     }
 
     /**
+     * Obtains the gateway node by instance port.
+     *
+     * @param gateways      a collection of gateway nodes
+     * @param instPort      instance port
+     * @return a gateway node
+     */
+    public static OpenstackNode getGwByInstancePort(Set<OpenstackNode> gateways,
+                                                    InstancePort instPort) {
+        OpenstackNode gw = null;
+        if (instPort != null && instPort.deviceId() != null) {
+            gw = getGwByComputeDevId(gateways, instPort.deviceId());
+        }
+        return gw;
+    }
+
+    /**
      * Obtains the gateway node by device in compute node. Note that the gateway
      * node is determined by device's device identifier.
      *