Fix: resolve dup host insertion problem caused by resource contention

Change-Id: I647d3aa6f6423e5f3cf281f6a135d38dc5f48fab
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java
index 0935f53..9878de0 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java
@@ -26,6 +26,10 @@
 import org.apache.felix.scr.annotations.Service;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.event.ListenerRegistry;
 import org.onosproject.net.Host;
@@ -43,6 +47,7 @@
 import org.onosproject.openstacknetworking.api.InstancePortStoreDelegate;
 import org.slf4j.Logger;
 
+import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -88,6 +93,12 @@
     protected InstancePortStore instancePortStore;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LeadershipService leadershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected HostService hostService;
 
     private final InstancePortStoreDelegate
@@ -95,11 +106,17 @@
     private final InternalHostListener
                             hostListener = new InternalHostListener();
 
+    private ApplicationId appId;
+    private NodeId localNodeId;
+
     @Activate
     protected void activate() {
-        coreService.registerApplication(Constants.OPENSTACK_NETWORKING_APP_ID);
+        appId = coreService.registerApplication(Constants.OPENSTACK_NETWORKING_APP_ID);
+        localNodeId = clusterService.getLocalNode().id();
         instancePortStore.setDelegate(delegate);
         hostService.addListener(hostListener);
+        leadershipService.runForLeadership(appId.name());
+
         log.info("Started");
     }
 
@@ -107,6 +124,8 @@
     protected void deactivate() {
         hostService.removeListener(hostListener);
         instancePortStore.unsetDelegate(delegate);
+        leadershipService.withdraw(appId.name());
+
         log.info("Stopped");
     }
 
@@ -229,7 +248,10 @@
                 log.debug("Invalid host detected, ignore it {}", host);
                 return false;
             }
-            return true;
+
+            // do not allow to proceed without leadership
+            NodeId leader = leadershipService.getLeader(appId.name());
+            return Objects.equals(localNodeId, leader);
         }
 
         @Override
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortManagerTest.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortManagerTest.java
index 8b325a3..d7f0291 100644
--- a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortManagerTest.java
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortManagerTest.java
@@ -25,6 +25,8 @@
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.LeadershipServiceAdapter;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreServiceAdapter;
 import org.onosproject.core.DefaultApplicationId;
@@ -120,6 +122,8 @@
         target = new InstancePortManager();
         TestUtils.setField(target, "coreService", new TestCoreService());
         TestUtils.setField(target, "hostService", new TestHostService());
+        TestUtils.setField(target, "leadershipService", new TestLeadershipService());
+        TestUtils.setField(target, "clusterService", new TestClusterService());
         target.instancePortStore = store;
         target.addListener(testInstancePortListener);
         target.activate();
@@ -433,6 +437,12 @@
         }
     }
 
+    private static class TestLeadershipService extends LeadershipServiceAdapter {
+    }
+
+    private static class TestClusterService extends ClusterServiceAdapter {
+    }
+
     private static class TestHostService extends HostServiceAdapter {
     }