blob: 1bb218277ed46007dfbe689d08e372974b005594 [file] [log] [blame]
Madan Jampaniab7e7cd2016-01-14 14:02:32 -08001/*
2 * Copyright 2015-2016 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Madan Jampaniec1df022015-10-13 21:23:03 -070016package org.onosproject.cluster.impl;
17
18import static com.google.common.base.Preconditions.checkNotNull;
19import static org.slf4j.LoggerFactory.getLogger;
20
21import java.net.InetAddress;
22import java.net.NetworkInterface;
23import java.net.SocketException;
24import java.util.Collection;
25import java.util.Enumeration;
26
27import org.apache.felix.scr.annotations.Activate;
28import org.apache.felix.scr.annotations.Component;
29import org.apache.felix.scr.annotations.Deactivate;
30import org.apache.felix.scr.annotations.Reference;
31import org.apache.felix.scr.annotations.ReferenceCardinality;
32import org.apache.felix.scr.annotations.Service;
33import org.onlab.packet.IpAddress;
34import org.onosproject.cluster.ClusterMetadata;
Madan Jampaniab7e7cd2016-01-14 14:02:32 -080035import org.onosproject.cluster.ClusterMetadataAdminService;
Madan Jampaniec1df022015-10-13 21:23:03 -070036import org.onosproject.cluster.ClusterMetadataEvent;
37import org.onosproject.cluster.ClusterMetadataEventListener;
38import org.onosproject.cluster.ClusterMetadataService;
39import org.onosproject.cluster.ClusterMetadataStore;
40import org.onosproject.cluster.ClusterMetadataStoreDelegate;
41import org.onosproject.cluster.ControllerNode;
42import org.onosproject.event.AbstractListenerManager;
43import org.onosproject.store.service.Versioned;
44import org.slf4j.Logger;
45
46/**
47 * Implementation of ClusterMetadataService.
48 */
49@Component(immediate = true)
50@Service
51public class ClusterMetadataManager
52 extends AbstractListenerManager<ClusterMetadataEvent, ClusterMetadataEventListener>
Madan Jampaniab7e7cd2016-01-14 14:02:32 -080053 implements ClusterMetadataService, ClusterMetadataAdminService {
Madan Jampaniec1df022015-10-13 21:23:03 -070054
Madan Jampaniec1df022015-10-13 21:23:03 -070055 private final Logger log = getLogger(getClass());
Madan Jampaniab7e7cd2016-01-14 14:02:32 -080056 private ControllerNode localNode;
Madan Jampaniec1df022015-10-13 21:23:03 -070057
58 private ClusterMetadataStoreDelegate delegate = new InternalStoreDelegate();
59
60 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 protected ClusterMetadataStore store;
62
63 @Activate
64 public void activate() {
65 store.setDelegate(delegate);
66 eventDispatcher.addSink(ClusterMetadataEvent.class, listenerRegistry);
67 establishSelfIdentity();
68 log.info("Started");
69 }
70
71 @Deactivate
72 public void deactivate() {
73 store.unsetDelegate(delegate);
74 eventDispatcher.removeSink(ClusterMetadataEvent.class);
75 log.info("Stopped");
76 }
77
78 @Override
79 public ClusterMetadata getClusterMetadata() {
80 return Versioned.valueOrElse(store.getClusterMetadata(), null);
81 }
82
83 @Override
84 public ControllerNode getLocalNode() {
85 return localNode;
86 }
87
88 @Override
89 public void setClusterMetadata(ClusterMetadata metadata) {
90 checkNotNull(metadata, "Cluster metadata cannot be null");
91 store.setClusterMetadata(metadata);
92 }
93
94 // Store delegate to re-post events emitted from the store.
95 private class InternalStoreDelegate implements ClusterMetadataStoreDelegate {
96 @Override
97 public void notify(ClusterMetadataEvent event) {
98 post(event);
99 }
100 }
101
102 private IpAddress findLocalIp(Collection<ControllerNode> controllerNodes) throws SocketException {
103 Enumeration<NetworkInterface> interfaces =
104 NetworkInterface.getNetworkInterfaces();
105 while (interfaces.hasMoreElements()) {
106 NetworkInterface iface = interfaces.nextElement();
107 Enumeration<InetAddress> inetAddresses = iface.getInetAddresses();
108 while (inetAddresses.hasMoreElements()) {
109 IpAddress ip = IpAddress.valueOf(inetAddresses.nextElement());
110 if (controllerNodes.stream()
111 .map(ControllerNode::ip)
112 .anyMatch(nodeIp -> ip.equals(nodeIp))) {
113 return ip;
114 }
115 }
116 }
117 throw new IllegalStateException("Unable to determine local ip");
118 }
119
120 private void establishSelfIdentity() {
121 try {
122 IpAddress ip = findLocalIp(getClusterMetadata().getNodes());
123 localNode = getClusterMetadata().getNodes()
124 .stream()
125 .filter(node -> node.ip().equals(ip))
126 .findFirst()
127 .get();
128 } catch (SocketException e) {
129 throw new IllegalStateException("Cannot determine local IP", e);
130 }
131 }
132}