Using provider pattern for cluster metadata.
Change-Id: I5a572b3df9149be959dde9868a9c594dec26a3e0
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 1bb2182..49a24db 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
@@ -21,81 +21,117 @@
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Collection;
import java.util.Enumeration;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.IpAddress;
import org.onosproject.cluster.ClusterMetadata;
import org.onosproject.cluster.ClusterMetadataAdminService;
import org.onosproject.cluster.ClusterMetadataEvent;
import org.onosproject.cluster.ClusterMetadataEventListener;
+import org.onosproject.cluster.ClusterMetadataProvider;
+import org.onosproject.cluster.ClusterMetadataProviderRegistry;
+import org.onosproject.cluster.ClusterMetadataProviderService;
import org.onosproject.cluster.ClusterMetadataService;
-import org.onosproject.cluster.ClusterMetadataStore;
-import org.onosproject.cluster.ClusterMetadataStoreDelegate;
import org.onosproject.cluster.ControllerNode;
-import org.onosproject.event.AbstractListenerManager;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.cluster.PartitionId;
+import org.onosproject.net.provider.AbstractListenerProviderRegistry;
+import org.onosproject.net.provider.AbstractProviderService;
import org.onosproject.store.service.Versioned;
import org.slf4j.Logger;
+import com.google.common.base.Throwables;
+
/**
* Implementation of ClusterMetadataService.
*/
@Component(immediate = true)
@Service
public class ClusterMetadataManager
- extends AbstractListenerManager<ClusterMetadataEvent, ClusterMetadataEventListener>
- implements ClusterMetadataService, ClusterMetadataAdminService {
+ extends AbstractListenerProviderRegistry<ClusterMetadataEvent,
+ ClusterMetadataEventListener,
+ ClusterMetadataProvider,
+ ClusterMetadataProviderService>
+ implements ClusterMetadataService, ClusterMetadataAdminService, ClusterMetadataProviderRegistry {
private final Logger log = getLogger(getClass());
private ControllerNode localNode;
- private ClusterMetadataStoreDelegate delegate = new InternalStoreDelegate();
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected ClusterMetadataStore store;
-
@Activate
public void activate() {
- store.setDelegate(delegate);
+ // FIXME: Need to ensure all cluster metadata providers are registered before we activate
eventDispatcher.addSink(ClusterMetadataEvent.class, listenerRegistry);
- establishSelfIdentity();
log.info("Started");
}
@Deactivate
public void deactivate() {
- store.unsetDelegate(delegate);
eventDispatcher.removeSink(ClusterMetadataEvent.class);
log.info("Stopped");
}
@Override
public ClusterMetadata getClusterMetadata() {
- return Versioned.valueOrElse(store.getClusterMetadata(), null);
+ Versioned<ClusterMetadata> metadata = getProvider().getClusterMetadata();
+ return metadata.value();
+ }
+
+
+ @Override
+ protected ClusterMetadataProviderService createProviderService(
+ ClusterMetadataProvider provider) {
+ return new InternalClusterMetadataProviderService(provider);
}
@Override
public ControllerNode getLocalNode() {
+ if (localNode == null) {
+ establishSelfIdentity();
+ }
return localNode;
}
@Override
public void setClusterMetadata(ClusterMetadata metadata) {
checkNotNull(metadata, "Cluster metadata cannot be null");
- store.setClusterMetadata(metadata);
+ ClusterMetadataProvider primaryProvider = getPrimaryProvider();
+ if (primaryProvider == null) {
+ throw new IllegalStateException("Missing primary provider. Cannot update cluster metadata");
+ }
+ primaryProvider.setClusterMetadata(metadata);
}
- // Store delegate to re-post events emitted from the store.
- private class InternalStoreDelegate implements ClusterMetadataStoreDelegate {
- @Override
- public void notify(ClusterMetadataEvent event) {
- post(event);
+ /**
+ * Returns the provider to use for fetching cluster metadata.
+ * @return cluster metadata provider
+ */
+ private ClusterMetadataProvider getProvider() {
+ ClusterMetadataProvider primaryProvider = getPrimaryProvider();
+ if (primaryProvider != null && primaryProvider.isAvailable()) {
+ return primaryProvider;
+ }
+ log.warn("Primary cluster metadata provider not available. Using default fallback.");
+ return getProvider("default");
+ }
+
+ /**
+ * Returns the primary provider for cluster metadata.
+ * @return primary cluster metadata provider
+ */
+ private ClusterMetadataProvider getPrimaryProvider() {
+ try {
+ URI uri = new URI(System.getProperty("onos.cluster.metadata.uri", "config:///cluster.json"));
+ return getProvider(uri.getScheme());
+ } catch (URISyntaxException e) {
+ Throwables.propagate(e);
+ return null;
}
}
@@ -129,4 +165,25 @@
throw new IllegalStateException("Cannot determine local IP", e);
}
}
+
+ private class InternalClusterMetadataProviderService
+ extends AbstractProviderService<ClusterMetadataProvider>
+ implements ClusterMetadataProviderService {
+
+ InternalClusterMetadataProviderService(ClusterMetadataProvider provider) {
+ super(provider);
+ }
+
+ @Override
+ public void clusterMetadataChanged(Versioned<ClusterMetadata> newMetadata) {
+ log.info("Cluster metadata changed. New metadata: {}", newMetadata);
+ post(new ClusterMetadataEvent(ClusterMetadataEvent.Type.METADATA_CHANGED, newMetadata.value()));
+ }
+
+ @Override
+ public void newActiveMemberForPartition(PartitionId partitionId, NodeId nodeId) {
+ log.info("Node {} is active member for partition {}", nodeId, partitionId);
+ // TODO: notify listeners
+ }
+ }
}
\ No newline at end of file