blob: e977170a7a031c5485574ee6eb18d2c14cb6571d [file] [log] [blame]
nosignal5fd282e2016-09-16 16:11:40 -07001/*
2 * Copyright 2016-present 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 */
16package org.onosproject.vpls.config.impl;
17
18import com.google.common.collect.HashMultimap;
19import com.google.common.collect.ImmutableSet;
20import com.google.common.collect.ImmutableSetMultimap;
21import com.google.common.collect.SetMultimap;
22import org.apache.felix.scr.annotations.Activate;
23import org.apache.felix.scr.annotations.Component;
24import org.apache.felix.scr.annotations.Deactivate;
25import org.apache.felix.scr.annotations.Reference;
26import org.apache.felix.scr.annotations.ReferenceCardinality;
27import org.apache.felix.scr.annotations.Service;
28import org.onlab.packet.VlanId;
29import org.onosproject.core.ApplicationId;
30import org.onosproject.core.CoreService;
31import org.onosproject.incubator.net.intf.Interface;
32import org.onosproject.incubator.net.intf.InterfaceService;
33import org.onosproject.net.ConnectPoint;
34import org.onosproject.net.config.NetworkConfigRegistry;
35import org.onosproject.net.config.NetworkConfigService;
36import org.onosproject.net.config.NetworkConfigListener;
37import org.onosproject.net.config.NetworkConfigEvent;
38import org.onosproject.net.config.ConfigFactory;
39import org.onosproject.net.config.basics.SubjectFactories;
40import org.onosproject.vpls.config.VplsConfig;
41import org.onosproject.vpls.config.VplsNetworkConfig;
42import org.onosproject.vpls.config.VplsConfigurationService;
43import org.slf4j.Logger;
44import org.slf4j.LoggerFactory;
45
46import java.util.HashSet;
47import java.util.Set;
48
49/**
50 * Implementation of VPLSConfigurationService which reads VPLS configuration
51 * from the network configuration service.
52 */
53@Component(immediate = true)
54@Service
55public class VplsConfigurationImpl implements VplsConfigurationService {
56 private static final String VPLS_APP = "org.onosproject.vpls";
57 private static final String VPLS = "vpls";
58 private static final String EMPTY = "";
59 private static final String CONFIG_NULL = "VPLS configuration not defined";
60 private static final String APP_ID_NULL = "VPLS application ID is null";
61 private static final String CONFIG_CHANGED = "VPLS configuration changed: {}";
62 private static final String CHECK_CONFIG =
63 "Checking the interface configuration";
64 private static final String NET_CONF_EVENT =
65 "Received NetworkConfigEvent {}";
66
67 private final Logger log = LoggerFactory.getLogger(getClass());
68
69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 protected NetworkConfigRegistry registry;
71
72 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 protected CoreService coreService;
74
75 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
76 protected InterfaceService interfaceService;
77
78 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
79 protected NetworkConfigService configService;
80
81 private final Set<String> vplsAffectedByApi = new HashSet<>();
82
83 private VplsConfig vplsConfig = new VplsConfig();
84
85 private SetMultimap<String, String> ifacesOfVpls = HashMultimap.create();
86 private SetMultimap<String, String> oldIfacesOfVpls = HashMultimap.create();
87 private SetMultimap<String, Interface> vplsNetworks = HashMultimap.create();
88
89 private final InternalNetworkConfigListener configListener =
90 new InternalNetworkConfigListener();
91
92 private ConfigFactory<ApplicationId, VplsConfig> vplsConfigFactory =
93 new ConfigFactory<ApplicationId, VplsConfig>(
94 SubjectFactories.APP_SUBJECT_FACTORY, VplsConfig.class, VPLS) {
95 @Override
96 public VplsConfig createConfig() {
97 return new VplsConfig();
98 }
99 };
100
101 private ApplicationId vplsAppId;
102
103 @Activate
104 protected void active() {
105 configService.addListener(configListener);
106 registry.registerConfigFactory(vplsConfigFactory);
107 loadConfiguration();
108 log.info("Started");
109 }
110
111 @Deactivate
112 protected void deactive() {
113 registry.unregisterConfigFactory(vplsConfigFactory);
114 configService.removeListener(configListener);
115 log.info("Stopped");
116 }
117
118 /**
119 * Retrieves the VPLS configuration from network configuration.
120 */
121 private void loadConfiguration() {
122 loadAppId();
123
124 vplsConfig = configService.getConfig(vplsAppId, VplsConfig.class);
125
126 if (vplsConfig == null) {
127 log.warn(CONFIG_NULL);
128 configService.addConfig(vplsAppId, VplsConfig.class);
129 return;
130 }
131
132 oldIfacesOfVpls = ifacesOfVpls;
133 ifacesOfVpls = getConfigInterfaces();
134 vplsNetworks = getConfigCPoints();
135 log.debug(CONFIG_CHANGED, ifacesOfVpls);
136 }
137
138 /**
139 * Retrieves the application identifier from core service.
140 */
141 private void loadAppId() {
142 vplsAppId = coreService.getAppId(VPLS_APP);
143 if (vplsAppId == null) {
144 log.warn(APP_ID_NULL);
145 }
146 }
147
148 /**
149 * Applies a given configuration to the VPLS application.
150 */
151 private void applyConfig(VplsConfig vplsConfig) {
152 loadAppId();
153 configService.applyConfig(vplsAppId, VplsConfig.class, vplsConfig.node());
154 }
155
156 /**
157 * Retrieves the VPLS names and associated interfaces names from the configuration.
158 *
159 * @return a map VPLS names and associated interface names
160 */
161 private SetMultimap<String, String> getConfigInterfaces() {
162 SetMultimap<String, String> confIntfByVpls =
163 HashMultimap.create();
164
165 vplsConfig.vplsNetworks().forEach(vpls -> {
166 if (vpls.ifaces().isEmpty()) {
167 confIntfByVpls.put(vpls.name(), EMPTY);
168 } else {
169 vpls.ifaces().forEach(iface -> confIntfByVpls.put(vpls.name(), iface));
170 }
171 });
172
173 return confIntfByVpls;
174 }
175
176 /**
177 * Retrieves the VPLS names and associated interfaces from the configuration.
178 *
179 * @return a map VPLS names and associated interfaces
180 */
181 private SetMultimap<String, Interface> getConfigCPoints() {
182 log.debug(CHECK_CONFIG);
183
184 SetMultimap<String, Interface> confCPointsByIntf =
185 HashMultimap.create();
186
187 ifacesOfVpls.entries().forEach(vpls -> {
188 interfaceService.getInterfaces()
189 .stream()
190 .filter(intf -> intf.ipAddressesList().isEmpty())
191 .filter(intf -> intf.name().equals(vpls.getValue()))
192 .forEach(intf -> confCPointsByIntf.put(vpls.getKey(), intf));
193 });
194
195 return confCPointsByIntf;
196 }
197
198 /**
199 * Listener for VPLS configuration events.
200 */
201 private class InternalNetworkConfigListener implements NetworkConfigListener {
202 @Override
203 public void event(NetworkConfigEvent event) {
204 if (event.configClass() == VplsConfigurationService.CONFIG_CLASS) {
205 log.debug(NET_CONF_EVENT, event.configClass());
206 switch (event.type()) {
207 case CONFIG_ADDED:
208 case CONFIG_UPDATED:
209 case CONFIG_REMOVED:
210 loadConfiguration();
211 break;
212
213 default:
214 break;
215 }
216 }
217 }
218 }
219
220 @Override
221 public void addVpls(String name, Set<String> ifaces) {
222 VplsNetworkConfig vpls;
223
224 if (ifacesOfVpls.containsKey(name)) {
225 if (ifaces.isEmpty()) {
226 return;
227 }
228
229 ifaces.forEach(iface ->
230 vplsConfig.addInterfaceToVpls(name, iface));
231 } else {
232 vpls = new VplsNetworkConfig(name, ifaces);
233 vplsConfig.addVpls(vpls);
234 }
235
236 vplsAffectedByApi.add(name);
237 applyConfig(vplsConfig);
238 }
239
240 @Override
241 public void removeVpls(String name) {
242 if (ifacesOfVpls.containsKey(name)) {
243 vplsConfig.removeVpls(name);
244 vplsAffectedByApi.add(name);
245 applyConfig(vplsConfig);
246 }
247 }
248
249 @Override
250 public void addInterfaceToVpls(String name, String iface) {
251 if (ifacesOfVpls.containsKey(name)) {
252 vplsConfig.addInterfaceToVpls(name, iface);
253 vplsAffectedByApi.add(name);
254 applyConfig(vplsConfig);
255 }
256 }
257
258 @Override
259 public void removeInterfaceFromVpls(String iface) {
260 if (ifacesOfVpls.containsValue(iface)) {
261 VplsNetworkConfig vpls = vplsConfig.getVplsFromInterface(iface);
262 vplsConfig.removeInterfaceFromVpls(vpls, iface);
263 vplsAffectedByApi.add(vpls.name());
264 applyConfig(vplsConfig);
265 }
266 }
267
268 @Override
269 public void cleanVpls() {
270 ifacesOfVpls.entries().forEach(e -> {
271 vplsConfig.removeVpls(e.getKey());
272 vplsAffectedByApi.add(e.getKey());
273 });
274 applyConfig(vplsConfig);
275 }
276
277 @Override
278 public Set<String> getVplsAffectedByApi() {
279 Set<String> vplsNames = ImmutableSet.copyOf(vplsAffectedByApi);
280
281 vplsAffectedByApi.clear();
282
283 return vplsNames;
284 }
285
286 @Override
287 public Set<Interface> getAllInterfaces() {
288 Set<Interface> allInterfaces = new HashSet<>();
289 vplsNetworks.values().forEach(allInterfaces::add);
290
291 return allInterfaces;
292 }
293
294 @Override
295 public Set<Interface> getVplsInterfaces(String name) {
296 Set<Interface> vplsInterfaces = new HashSet<>();
297 vplsNetworks.get(name).forEach(vplsInterfaces::add);
298
299 return vplsInterfaces;
300 }
301
302 @Override
303 public Set<String> getAllVpls() {
304 return ifacesOfVpls.keySet();
305 }
306
307 @Override
308 public Set<String> getOldVpls() {
309 return oldIfacesOfVpls.keySet();
310 }
311
312 @Override
313 public SetMultimap<String, Interface> getVplsNetworks() {
314 return ImmutableSetMultimap.copyOf(vplsNetworks);
315 }
316
317 @Override
318 public SetMultimap<String, Interface> getVplsNetwork(VlanId vlan,
319 ConnectPoint connectPoint) {
320 String vplsNetworkName =
321 vplsNetworks.entries().stream()
322 .filter(e -> e.getValue().connectPoint().equals(connectPoint))
323 .filter(e -> e.getValue().vlan().equals(vlan))
324 .map(e -> e.getKey())
325 .findFirst()
326 .orElse(null);
327 SetMultimap<String, Interface> result = HashMultimap.create();
328 if (vplsNetworkName != null && vplsNetworks.containsKey(vplsNetworkName)) {
329 vplsNetworks.get(vplsNetworkName)
330 .forEach(intf -> result.put(vplsNetworkName, intf));
331 return result;
332 }
333 return null;
334 }
335}