[ONOS-4926] floating Ip flow rules handling when restarting ONOS

Change-Id: I844ebf8c0ef48289675124c79c96edd886bbff16
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java
index b984ecc..2e218bd 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java
@@ -40,6 +40,8 @@
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.net.host.HostService;
 import org.onosproject.openstackinterface.OpenstackFloatingIP;
+import org.onosproject.openstackinterface.OpenstackInterfaceService;
+import org.onosproject.openstacknetworking.AbstractVmHandler;
 import org.onosproject.openstacknetworking.Constants;
 import org.onosproject.openstacknetworking.OpenstackFloatingIpService;
 import org.onosproject.openstacknetworking.RulePopulatorUtil;
@@ -70,7 +72,7 @@
 
 @Service
 @Component(immediate = true)
-public class OpenstackFloatingIpManager implements OpenstackFloatingIpService {
+public class OpenstackFloatingIpManager extends AbstractVmHandler implements OpenstackFloatingIpService {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
@@ -95,6 +97,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ScalableGatewayService gatewayService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenstackInterfaceService openstackService;
+
     private static final String NOT_ASSOCIATED = "null";
     private static final KryoNamespace.Builder FLOATING_IP_SERIALIZER =
             KryoNamespace.newBuilder().register(KryoNamespaces.API);
@@ -108,6 +113,7 @@
 
     @Activate
     protected void activate() {
+        super.activate();
         appId = coreService.registerApplication(ROUTING_APP_ID);
         nodeService.addListener(nodeListener);
         floatingIpMap = storageService.<IpAddress, Host>consistentMapBuilder()
@@ -121,11 +127,34 @@
 
     @Deactivate
     protected void deactivate() {
+        super.deactivate();
         nodeService.removeListener(nodeListener);
         log.info("Stopped");
     }
 
     @Override
+    protected void hostDetected(Host host) {
+        IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
+        Optional<OpenstackFloatingIP> floatingIp = openstackService.floatingIps().stream()
+                .filter(fip -> fip.fixedIpAddress() != null && fip.fixedIpAddress().equals(hostIp))
+                .findFirst();
+        if (floatingIp.isPresent()) {
+            eventExecutor.execute(() -> associateFloatingIp(floatingIp.get()));
+        }
+    }
+
+    @Override
+    protected void hostRemoved(Host host) {
+        IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
+        Optional<OpenstackFloatingIP> floatingIp = openstackService.floatingIps().stream()
+                .filter(fip -> fip.fixedIpAddress() != null && fip.fixedIpAddress().equals(hostIp))
+                .findFirst();
+        if (floatingIp.isPresent()) {
+            eventExecutor.execute(() -> disassociateFloatingIp(floatingIp.get()));
+        }
+    }
+
+    @Override
     public void createFloatingIp(OpenstackFloatingIP floatingIp) {
     }
 
@@ -285,18 +314,6 @@
         });
     }
 
-    private void reloadFloatingIpRules() {
-        floatingIpMap.entrySet().stream().forEach(entry -> {
-            IpAddress floatingIp = entry.getKey();
-            Host associatedVm = entry.getValue().value();
-
-            populateFloatingIpRules(floatingIp, associatedVm);
-            log.debug("Reload floating IP {} mapped to {}",
-                      floatingIp, associatedVm.ipAddresses());
-        });
-    }
-
-    // TODO apply existing floating IPs on service start-up by handling host event
     // TODO consider the case that port with associated floating IP is attached to a VM
 
     private class InternalNodeListener implements OpenstackNodeListener {
@@ -316,7 +333,6 @@
                                     .uplinkIntf(node.externalPortName().get())
                                     .build();
                             gatewayService.addGatewayNode(gnode);
-                            reloadFloatingIpRules();
                         });
                     }
                     break;