Route is not populated correctly when next hop moves

When the next hop moves from [1A,1B] to [1A],
there should be a route on 1B pointing to 1A via spines

Change-Id: I817414fb4e9edf29357fdb5e55675537ff5f0cac
(cherry picked from commit 53eae194a8b66287855483359309597e8df2efa9)
diff --git a/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java b/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
index 8790d93..40cdf53 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
@@ -249,14 +249,23 @@
             Sets.difference(prevLocations, newLocations).forEach(prevLocation -> {
                 // Remove flows for unchanged IPs only when the host moves from a switch to another.
                 // Otherwise, do not remove and let the adding part update the old flow
-                if (!newDeviceIds.contains(prevLocation.deviceId())) {
-                    log.debug("HostMoved. removeSubnet {}, {}", prevLocation, prefix);
-                    srManager.deviceConfiguration.removeSubnet(prevLocation, prefix);
-
-                    log.debug("HostMoved. revokeRoute {}, {}, {}, {}", prevLocation, prefix, hostMac, hostVlanId);
-                    srManager.defaultRoutingHandler.revokeRoute(prevLocation.deviceId(), prefix,
-                            hostMac, hostVlanId, prevLocation.port());
+                if (newDeviceIds.contains(prevLocation.deviceId())) {
+                    return;
                 }
+
+                log.debug("HostMoved. removeSubnet {}, {}", prevLocation, prefix);
+                srManager.deviceConfiguration.removeSubnet(prevLocation, prefix);
+
+                // Do not remove flow from a device if the route is still reachable via its pair device.
+                // populateSubnet will update the flow to point to its pair device via spine.
+                DeviceId pairDeviceId = srManager.getPairDeviceId(prevLocation.deviceId()).orElse(null);
+                if (newLocations.stream().anyMatch(n -> n.deviceId().equals(pairDeviceId))) {
+                    return;
+                }
+
+                log.debug("HostMoved. revokeRoute {}, {}, {}, {}", prevLocation, prefix, hostMac, hostVlanId);
+                srManager.defaultRoutingHandler.revokeRoute(prevLocation.deviceId(), prefix,
+                        hostMac, hostVlanId, prevLocation.port());
             });
 
             // For each new location, add all new IPs.
diff --git a/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java b/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java
index 7804e68..494b9ec 100644
--- a/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java
+++ b/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java
@@ -414,7 +414,8 @@
         HostEvent he = new HostEvent(HostEvent.Type.HOST_MOVED, H3S, H3D);
         routeHandler.processHostMovedEvent(he);
 
-        assertEquals(1, ROUTING_TABLE.size());
+        // We do not remove the route on CP2. Instead, we let the subnet population overrides it
+        assertEquals(2, ROUTING_TABLE.size());
         MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
         assertEquals(M3, rtv1.macAddress);
         assertEquals(V3, rtv1.vlanId);