blob: 35a56a8403082198ef5b5681a8d2ff7046792116 [file] [log] [blame]
Madan Jampaniad3c5262016-01-20 00:50:17 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Madan Jampaniad3c5262016-01-20 00:50:17 -08003 *
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 */
16package org.onosproject.cluster.impl;
17
Madan Jampaniad3c5262016-01-20 00:50:17 -080018import java.net.Inet4Address;
19import java.net.InetAddress;
20import java.net.NetworkInterface;
21import java.util.Collections;
22import java.util.Set;
Samuel Jero31e16f52018-09-21 10:34:28 -040023import java.util.UUID;
Madan Jampaniad3c5262016-01-20 00:50:17 -080024import java.util.concurrent.atomic.AtomicReference;
25import java.util.function.Function;
26
Jordan Halterman00e92da2018-05-22 23:05:52 -070027import com.google.common.collect.ImmutableSet;
Madan Jampaniad3c5262016-01-20 00:50:17 -080028import org.apache.felix.scr.annotations.Activate;
29import org.apache.felix.scr.annotations.Component;
30import org.apache.felix.scr.annotations.Deactivate;
31import org.apache.felix.scr.annotations.Reference;
32import org.apache.felix.scr.annotations.ReferenceCardinality;
33import org.onlab.packet.IpAddress;
34import org.onosproject.cluster.ClusterMetadata;
35import org.onosproject.cluster.ClusterMetadataProvider;
36import org.onosproject.cluster.ClusterMetadataProviderRegistry;
37import org.onosproject.cluster.ControllerNode;
38import org.onosproject.cluster.DefaultControllerNode;
Madan Jampaniad3c5262016-01-20 00:50:17 -080039import org.onosproject.cluster.NodeId;
Madan Jampaniad3c5262016-01-20 00:50:17 -080040import org.onosproject.cluster.PartitionId;
Jordan Halterman07f052b2017-10-08 14:22:41 -070041import org.onosproject.core.VersionService;
Madan Jampaniad3c5262016-01-20 00:50:17 -080042import org.onosproject.net.provider.ProviderId;
43import org.onosproject.store.service.Versioned;
44import org.slf4j.Logger;
45
Jordan Halterman00e92da2018-05-22 23:05:52 -070046import static java.net.NetworkInterface.getNetworkInterfaces;
47import static org.slf4j.LoggerFactory.getLogger;
Madan Jampaniad3c5262016-01-20 00:50:17 -080048
49/**
50 * Provider of default {@link ClusterMetadata cluster metadata}.
51 */
52@Component(immediate = true)
53public class DefaultClusterMetadataProvider implements ClusterMetadataProvider {
54
55 private final Logger log = getLogger(getClass());
56
57 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 protected ClusterMetadataProviderRegistry providerRegistry;
59
Jordan Halterman07f052b2017-10-08 14:22:41 -070060 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 protected VersionService versionService;
62
Madan Jampaniad3c5262016-01-20 00:50:17 -080063 private static final String ONOS_IP = "ONOS_IP";
64 private static final String ONOS_INTERFACE = "ONOS_INTERFACE";
65 private static final String ONOS_ALLOW_IPV6 = "ONOS_ALLOW_IPV6";
66 private static final String DEFAULT_ONOS_INTERFACE = "eth0";
67 private static final int DEFAULT_ONOS_PORT = 9876;
68 private static final ProviderId PROVIDER_ID = new ProviderId("default", "none");
HIGUCHI Yuta4ad9df02016-05-20 14:29:15 -070069 private final AtomicReference<Versioned<ClusterMetadata>> cachedMetadata = new AtomicReference<>();
Madan Jampaniad3c5262016-01-20 00:50:17 -080070
71 @Activate
72 public void activate() {
73 String localIp = getSiteLocalAddress();
74 ControllerNode localNode =
75 new DefaultControllerNode(new NodeId(localIp), IpAddress.valueOf(localIp), DEFAULT_ONOS_PORT);
Jordan Halterman00e92da2018-05-22 23:05:52 -070076 ClusterMetadata metadata = new ClusterMetadata(
Samuel Jero31e16f52018-09-21 10:34:28 -040077 PROVIDER_ID, "default", localNode, ImmutableSet.of(), ImmutableSet.of(),
78 UUID.randomUUID().toString());
Madan Jampaniad3c5262016-01-20 00:50:17 -080079 long version = System.currentTimeMillis();
80 cachedMetadata.set(new Versioned<>(metadata, version));
81 providerRegistry.register(this);
82 log.info("Started");
83 }
84
85 @Deactivate
86 public void deactivate() {
87 providerRegistry.unregister(this);
88 log.info("Stopped");
89 }
90
91 @Override
92 public ProviderId id() {
93 return PROVIDER_ID;
94 }
95
96 @Override
97 public Versioned<ClusterMetadata> getClusterMetadata() {
98 return cachedMetadata.get();
99 }
100
101 @Override
102 public void setClusterMetadata(ClusterMetadata metadata) {
103 throw new UnsupportedOperationException();
104 }
105
106 @Override
107 public void addActivePartitionMember(PartitionId partitionId, NodeId nodeId) {
108 throw new UnsupportedOperationException();
109 }
110
111 @Override
112 public void removeActivePartitionMember(PartitionId partitionId, NodeId nodeId) {
113 throw new UnsupportedOperationException();
114 }
115
116 @Override
117 public Set<NodeId> getActivePartitionMembers(PartitionId partitionId) {
118 throw new UnsupportedOperationException();
119 }
120
121 @Override
122 public boolean isAvailable() {
123 return true;
124 }
125
126 private static String getSiteLocalAddress() {
127
128 /*
129 * If the IP ONOS should use is set via the environment variable we will assume it is valid and should be used.
130 * Setting the IP address takes presidence over setting the interface via the environment.
131 */
132 String useOnosIp = System.getenv(ONOS_IP);
133 if (useOnosIp != null) {
134 return useOnosIp;
135 }
136
137 // Read environment variables for IP interface information or set to default
138 String useOnosInterface = System.getenv(ONOS_INTERFACE);
139 if (useOnosInterface == null) {
140 useOnosInterface = DEFAULT_ONOS_INTERFACE;
141 }
142
143 // Capture if they want to limit IP address selection to only IPv4 (default).
144 boolean allowIPv6 = (System.getenv(ONOS_ALLOW_IPV6) != null);
145
146 Function<NetworkInterface, IpAddress> ipLookup = nif -> {
147 IpAddress fallback = null;
148
149 // nif can be null if the interface name specified doesn't exist on the node's host
150 if (nif != null) {
151 for (InetAddress address : Collections.list(nif.getInetAddresses())) {
152 if (address.isSiteLocalAddress() && (allowIPv6 || address instanceof Inet4Address)) {
153 return IpAddress.valueOf(address);
154 }
155 if (fallback == null && !address.isLoopbackAddress() && !address.isMulticastAddress()
156 && (allowIPv6 || address instanceof Inet4Address)) {
157 fallback = IpAddress.valueOf(address);
158 }
159 }
160 }
161 return fallback;
162 };
163 try {
164 IpAddress ip = ipLookup.apply(NetworkInterface.getByName(useOnosInterface));
165 if (ip != null) {
166 return ip.toString();
167 }
168 for (NetworkInterface nif : Collections.list(getNetworkInterfaces())) {
169 if (!nif.getName().equals(useOnosInterface)) {
170 ip = ipLookup.apply(nif);
171 if (ip != null) {
172 return ip.toString();
173 }
174 }
175 }
176 } catch (Exception e) {
177 throw new IllegalStateException("Unable to get network interfaces", e);
178 }
179
180 return IpAddress.valueOf(InetAddress.getLoopbackAddress()).toString();
181 }
182}