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 {
}