Fix race condition between AtomixManager and metadata providers startup
Change-Id: I4799c079455e0e5c79a800ba3108b4c9eedbe1b2
diff --git a/core/net/BUILD b/core/net/BUILD
index 8cd9b48..571c45a 100644
--- a/core/net/BUILD
+++ b/core/net/BUILD
@@ -5,6 +5,7 @@
"//incubator/net:onos-incubator-net",
"//incubator/store:onos-incubator-store",
"//core/store/serializers:onos-core-serializers",
+ "//core/store/primitives:onos-core-primitives",
"@org_osgi_service_cm//jar",
]
diff --git a/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java b/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java
index 3cf47ba..df77d09 100644
--- a/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java
+++ b/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java
@@ -15,8 +15,8 @@
*/
package org.onosproject.cluster.impl;
+import com.google.common.collect.ImmutableList;
import org.onlab.packet.IpAddress;
-import org.onlab.util.Tools;
import org.onosproject.cluster.ClusterMetadata;
import org.onosproject.cluster.ClusterMetadataAdminService;
import org.onosproject.cluster.ClusterMetadataEvent;
@@ -31,10 +31,14 @@
import org.onosproject.cluster.PartitionId;
import org.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.atomix.ClusterActivator;
import org.onosproject.store.service.Versioned;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
import org.slf4j.Logger;
import java.net.Inet4Address;
@@ -45,6 +49,9 @@
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.security.AppGuard.checkPermission;
@@ -67,12 +74,16 @@
private static final int MAX_WAIT_TRIES = 600;
private static final int MAX_WAIT_MS = 100;
+ private List<String> requiredProviders = ImmutableList.of("file", "default");
+
private final Logger log = getLogger(getClass());
private ControllerNode localNode;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ private ClusterActivator clusterActivator;
+
@Activate
public void activate() {
- // FIXME: Need to ensure all cluster metadata providers are registered before we activate
eventDispatcher.addSink(ClusterMetadataEvent.class, listenerRegistry);
log.info("Started");
}
@@ -84,22 +95,22 @@
}
@Override
- public ClusterMetadata getClusterMetadata() {
- checkPermission(CLUSTER_READ);
- waitForAvailableProvider();
- Versioned<ClusterMetadata> metadata = getProvider().getClusterMetadata();
- return metadata.value();
+ public synchronized ClusterMetadataProviderService register(ClusterMetadataProvider provider) {
+ ClusterMetadataProviderService s = super.register(provider);
+ Set<String> providerNames = getProviders().stream().map(ProviderId::scheme).collect(Collectors.toSet());
+ if (providerNames.containsAll(requiredProviders)) {
+ // Safe to release Atomix now, cluster metadata is ready
+ clusterActivator.activateCluster();
+ }
+ return s;
}
- // FIXME: Temporary hack to navigate around bootstrap timing issue
- private void waitForAvailableProvider() {
- for (int i = 0; i < MAX_WAIT_TRIES && getProvider() == null; i++) {
- Tools.delay(MAX_WAIT_MS);
- }
- if (getProvider() == null) {
- log.error("Unable to find cluster metadata provider");
- throw new IllegalStateException("Unable to find cluster metadata provider");
- }
+
+ @Override
+ public ClusterMetadata getClusterMetadata() {
+ checkPermission(CLUSTER_READ);
+ Versioned<ClusterMetadata> metadata = getProvider().getClusterMetadata();
+ return metadata.value();
}
@Override