blob: a0f7a833b3760bfab6a3b819f33ce263228ac7f7 [file] [log] [blame]
Madan Jampaniec1df022015-10-13 21:23:03 -07001package org.onosproject.cluster.impl;
2
3import static com.google.common.base.Preconditions.checkNotNull;
4import static org.slf4j.LoggerFactory.getLogger;
5
6import java.net.InetAddress;
7import java.net.NetworkInterface;
8import java.net.SocketException;
9import java.util.Collection;
10import java.util.Enumeration;
11
12import org.apache.felix.scr.annotations.Activate;
13import org.apache.felix.scr.annotations.Component;
14import org.apache.felix.scr.annotations.Deactivate;
15import org.apache.felix.scr.annotations.Reference;
16import org.apache.felix.scr.annotations.ReferenceCardinality;
17import org.apache.felix.scr.annotations.Service;
18import org.onlab.packet.IpAddress;
19import org.onosproject.cluster.ClusterMetadata;
20import org.onosproject.cluster.ClusterMetadataEvent;
21import org.onosproject.cluster.ClusterMetadataEventListener;
22import org.onosproject.cluster.ClusterMetadataService;
23import org.onosproject.cluster.ClusterMetadataStore;
24import org.onosproject.cluster.ClusterMetadataStoreDelegate;
25import org.onosproject.cluster.ControllerNode;
26import org.onosproject.event.AbstractListenerManager;
27import org.onosproject.store.service.Versioned;
28import org.slf4j.Logger;
29
30/**
31 * Implementation of ClusterMetadataService.
32 */
33@Component(immediate = true)
34@Service
35public class ClusterMetadataManager
36 extends AbstractListenerManager<ClusterMetadataEvent, ClusterMetadataEventListener>
37 implements ClusterMetadataService {
38
39 private ControllerNode localNode;
40 private final Logger log = getLogger(getClass());
41
42 private ClusterMetadataStoreDelegate delegate = new InternalStoreDelegate();
43
44 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
45 protected ClusterMetadataStore store;
46
47 @Activate
48 public void activate() {
49 store.setDelegate(delegate);
50 eventDispatcher.addSink(ClusterMetadataEvent.class, listenerRegistry);
51 establishSelfIdentity();
52 log.info("Started");
53 }
54
55 @Deactivate
56 public void deactivate() {
57 store.unsetDelegate(delegate);
58 eventDispatcher.removeSink(ClusterMetadataEvent.class);
59 log.info("Stopped");
60 }
61
62 @Override
63 public ClusterMetadata getClusterMetadata() {
64 return Versioned.valueOrElse(store.getClusterMetadata(), null);
65 }
66
67 @Override
68 public ControllerNode getLocalNode() {
69 return localNode;
70 }
71
72 @Override
73 public void setClusterMetadata(ClusterMetadata metadata) {
74 checkNotNull(metadata, "Cluster metadata cannot be null");
75 store.setClusterMetadata(metadata);
76 }
77
78 // Store delegate to re-post events emitted from the store.
79 private class InternalStoreDelegate implements ClusterMetadataStoreDelegate {
80 @Override
81 public void notify(ClusterMetadataEvent event) {
82 post(event);
83 }
84 }
85
86 private IpAddress findLocalIp(Collection<ControllerNode> controllerNodes) throws SocketException {
87 Enumeration<NetworkInterface> interfaces =
88 NetworkInterface.getNetworkInterfaces();
89 while (interfaces.hasMoreElements()) {
90 NetworkInterface iface = interfaces.nextElement();
91 Enumeration<InetAddress> inetAddresses = iface.getInetAddresses();
92 while (inetAddresses.hasMoreElements()) {
93 IpAddress ip = IpAddress.valueOf(inetAddresses.nextElement());
94 if (controllerNodes.stream()
95 .map(ControllerNode::ip)
96 .anyMatch(nodeIp -> ip.equals(nodeIp))) {
97 return ip;
98 }
99 }
100 }
101 throw new IllegalStateException("Unable to determine local ip");
102 }
103
104 private void establishSelfIdentity() {
105 try {
106 IpAddress ip = findLocalIp(getClusterMetadata().getNodes());
107 localNode = getClusterMetadata().getNodes()
108 .stream()
109 .filter(node -> node.ip().equals(ip))
110 .findFirst()
111 .get();
112 } catch (SocketException e) {
113 throw new IllegalStateException("Cannot determine local IP", e);
114 }
115 }
116}