blob: 49a24db7b4a0536171fc731abbeb06b54f50dd4c [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;
Madan Jampaniad3c5262016-01-20 00:50:17 -080024import java.net.URI;
25import java.net.URISyntaxException;
Madan Jampaniec1df022015-10-13 21:23:03 -070026import java.util.Collection;
27import java.util.Enumeration;
28
29import org.apache.felix.scr.annotations.Activate;
30import org.apache.felix.scr.annotations.Component;
31import org.apache.felix.scr.annotations.Deactivate;
Madan Jampaniec1df022015-10-13 21:23:03 -070032import 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;
Madan Jampaniad3c5262016-01-20 00:50:17 -080038import org.onosproject.cluster.ClusterMetadataProvider;
39import org.onosproject.cluster.ClusterMetadataProviderRegistry;
40import org.onosproject.cluster.ClusterMetadataProviderService;
Madan Jampaniec1df022015-10-13 21:23:03 -070041import org.onosproject.cluster.ClusterMetadataService;
Madan Jampaniec1df022015-10-13 21:23:03 -070042import org.onosproject.cluster.ControllerNode;
Madan Jampaniad3c5262016-01-20 00:50:17 -080043import org.onosproject.cluster.NodeId;
44import org.onosproject.cluster.PartitionId;
45import org.onosproject.net.provider.AbstractListenerProviderRegistry;
46import org.onosproject.net.provider.AbstractProviderService;
Madan Jampaniec1df022015-10-13 21:23:03 -070047import org.onosproject.store.service.Versioned;
48import org.slf4j.Logger;
49
Madan Jampaniad3c5262016-01-20 00:50:17 -080050import com.google.common.base.Throwables;
51
Madan Jampaniec1df022015-10-13 21:23:03 -070052/**
53 * Implementation of ClusterMetadataService.
54 */
55@Component(immediate = true)
56@Service
57public class ClusterMetadataManager
Madan Jampaniad3c5262016-01-20 00:50:17 -080058 extends AbstractListenerProviderRegistry<ClusterMetadataEvent,
59 ClusterMetadataEventListener,
60 ClusterMetadataProvider,
61 ClusterMetadataProviderService>
62 implements ClusterMetadataService, ClusterMetadataAdminService, ClusterMetadataProviderRegistry {
Madan Jampaniec1df022015-10-13 21:23:03 -070063
Madan Jampaniec1df022015-10-13 21:23:03 -070064 private final Logger log = getLogger(getClass());
Madan Jampaniab7e7cd2016-01-14 14:02:32 -080065 private ControllerNode localNode;
Madan Jampaniec1df022015-10-13 21:23:03 -070066
Madan Jampaniec1df022015-10-13 21:23:03 -070067 @Activate
68 public void activate() {
Madan Jampaniad3c5262016-01-20 00:50:17 -080069 // FIXME: Need to ensure all cluster metadata providers are registered before we activate
Madan Jampaniec1df022015-10-13 21:23:03 -070070 eventDispatcher.addSink(ClusterMetadataEvent.class, listenerRegistry);
Madan Jampaniec1df022015-10-13 21:23:03 -070071 log.info("Started");
72 }
73
74 @Deactivate
75 public void deactivate() {
Madan Jampaniec1df022015-10-13 21:23:03 -070076 eventDispatcher.removeSink(ClusterMetadataEvent.class);
77 log.info("Stopped");
78 }
79
80 @Override
81 public ClusterMetadata getClusterMetadata() {
Madan Jampaniad3c5262016-01-20 00:50:17 -080082 Versioned<ClusterMetadata> metadata = getProvider().getClusterMetadata();
83 return metadata.value();
84 }
85
86
87 @Override
88 protected ClusterMetadataProviderService createProviderService(
89 ClusterMetadataProvider provider) {
90 return new InternalClusterMetadataProviderService(provider);
Madan Jampaniec1df022015-10-13 21:23:03 -070091 }
92
93 @Override
94 public ControllerNode getLocalNode() {
Madan Jampaniad3c5262016-01-20 00:50:17 -080095 if (localNode == null) {
96 establishSelfIdentity();
97 }
Madan Jampaniec1df022015-10-13 21:23:03 -070098 return localNode;
99 }
100
101 @Override
102 public void setClusterMetadata(ClusterMetadata metadata) {
103 checkNotNull(metadata, "Cluster metadata cannot be null");
Madan Jampaniad3c5262016-01-20 00:50:17 -0800104 ClusterMetadataProvider primaryProvider = getPrimaryProvider();
105 if (primaryProvider == null) {
106 throw new IllegalStateException("Missing primary provider. Cannot update cluster metadata");
107 }
108 primaryProvider.setClusterMetadata(metadata);
Madan Jampaniec1df022015-10-13 21:23:03 -0700109 }
110
Madan Jampaniad3c5262016-01-20 00:50:17 -0800111 /**
112 * Returns the provider to use for fetching cluster metadata.
113 * @return cluster metadata provider
114 */
115 private ClusterMetadataProvider getProvider() {
116 ClusterMetadataProvider primaryProvider = getPrimaryProvider();
117 if (primaryProvider != null && primaryProvider.isAvailable()) {
118 return primaryProvider;
119 }
120 log.warn("Primary cluster metadata provider not available. Using default fallback.");
121 return getProvider("default");
122 }
123
124 /**
125 * Returns the primary provider for cluster metadata.
126 * @return primary cluster metadata provider
127 */
128 private ClusterMetadataProvider getPrimaryProvider() {
129 try {
130 URI uri = new URI(System.getProperty("onos.cluster.metadata.uri", "config:///cluster.json"));
131 return getProvider(uri.getScheme());
132 } catch (URISyntaxException e) {
133 Throwables.propagate(e);
134 return null;
Madan Jampaniec1df022015-10-13 21:23:03 -0700135 }
136 }
137
138 private IpAddress findLocalIp(Collection<ControllerNode> controllerNodes) throws SocketException {
139 Enumeration<NetworkInterface> interfaces =
140 NetworkInterface.getNetworkInterfaces();
141 while (interfaces.hasMoreElements()) {
142 NetworkInterface iface = interfaces.nextElement();
143 Enumeration<InetAddress> inetAddresses = iface.getInetAddresses();
144 while (inetAddresses.hasMoreElements()) {
145 IpAddress ip = IpAddress.valueOf(inetAddresses.nextElement());
146 if (controllerNodes.stream()
147 .map(ControllerNode::ip)
148 .anyMatch(nodeIp -> ip.equals(nodeIp))) {
149 return ip;
150 }
151 }
152 }
153 throw new IllegalStateException("Unable to determine local ip");
154 }
155
156 private void establishSelfIdentity() {
157 try {
158 IpAddress ip = findLocalIp(getClusterMetadata().getNodes());
159 localNode = getClusterMetadata().getNodes()
160 .stream()
161 .filter(node -> node.ip().equals(ip))
162 .findFirst()
163 .get();
164 } catch (SocketException e) {
165 throw new IllegalStateException("Cannot determine local IP", e);
166 }
167 }
Madan Jampaniad3c5262016-01-20 00:50:17 -0800168
169 private class InternalClusterMetadataProviderService
170 extends AbstractProviderService<ClusterMetadataProvider>
171 implements ClusterMetadataProviderService {
172
173 InternalClusterMetadataProviderService(ClusterMetadataProvider provider) {
174 super(provider);
175 }
176
177 @Override
178 public void clusterMetadataChanged(Versioned<ClusterMetadata> newMetadata) {
179 log.info("Cluster metadata changed. New metadata: {}", newMetadata);
180 post(new ClusterMetadataEvent(ClusterMetadataEvent.Type.METADATA_CHANGED, newMetadata.value()));
181 }
182
183 @Override
184 public void newActiveMemberForPartition(PartitionId partitionId, NodeId nodeId) {
185 log.info("Node {} is active member for partition {}", nodeId, partitionId);
186 // TODO: notify listeners
187 }
188 }
Madan Jampaniec1df022015-10-13 21:23:03 -0700189}