blob: 56c4fd5e61e412b8172d2c4203d3638546afe0fe [file] [log] [blame]
Thomas Vachuska33979fd2015-07-31 11:41:14 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Thomas Vachuska33979fd2015-07-31 11:41:14 -07003 *
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.incubator.net.virtual.impl;
17
Brian Stanke86914282016-05-25 15:36:50 -040018import com.google.common.collect.Maps;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070019import org.apache.felix.scr.annotations.Activate;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Deactivate;
22import org.apache.felix.scr.annotations.Reference;
23import org.apache.felix.scr.annotations.ReferenceCardinality;
24import org.apache.felix.scr.annotations.Service;
Brian Stanke11f6d532016-07-05 16:17:59 -040025import org.onlab.osgi.DefaultServiceDirectory;
Brian Stanke7a81b532016-06-14 15:43:51 -040026import org.onlab.packet.IpAddress;
27import org.onlab.packet.MacAddress;
28import org.onlab.packet.VlanId;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070029import org.onosproject.incubator.net.tunnel.TunnelId;
Brian Stankefb61df42016-07-25 11:47:51 -040030import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070031import org.onosproject.incubator.net.virtual.NetworkId;
32import org.onosproject.incubator.net.virtual.TenantId;
33import org.onosproject.incubator.net.virtual.VirtualDevice;
Brian Stanke7a81b532016-06-14 15:43:51 -040034import org.onosproject.incubator.net.virtual.VirtualHost;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070035import org.onosproject.incubator.net.virtual.VirtualLink;
36import org.onosproject.incubator.net.virtual.VirtualNetwork;
37import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
38import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
Brian Stanke11f6d532016-07-05 16:17:59 -040039import org.onosproject.incubator.net.virtual.VirtualNetworkIntent;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070040import org.onosproject.incubator.net.virtual.VirtualNetworkListener;
Thomas Vachuska3d62fd72015-09-25 14:58:13 -070041import org.onosproject.incubator.net.virtual.VirtualNetworkProvider;
Thomas Vachuska858f65b2016-07-06 10:46:01 -070042import org.onosproject.incubator.net.virtual.VirtualNetworkProviderRegistry;
Thomas Vachuska3d62fd72015-09-25 14:58:13 -070043import org.onosproject.incubator.net.virtual.VirtualNetworkProviderService;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070044import org.onosproject.incubator.net.virtual.VirtualNetworkService;
45import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
46import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate;
47import org.onosproject.incubator.net.virtual.VirtualPort;
48import org.onosproject.net.ConnectPoint;
49import org.onosproject.net.DeviceId;
Brian Stanke7a81b532016-06-14 15:43:51 -040050import org.onosproject.net.HostId;
51import org.onosproject.net.HostLocation;
Brian Stanke612cebf2016-05-02 10:21:33 -040052import org.onosproject.net.Link;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070053import org.onosproject.net.Port;
54import org.onosproject.net.PortNumber;
Brian Stanke86914282016-05-25 15:36:50 -040055import org.onosproject.net.device.DeviceService;
Claudine Chiu30a8a2a2016-07-14 17:09:04 -040056import org.onosproject.net.host.HostService;
Brian Stanke11f6d532016-07-05 16:17:59 -040057import org.onosproject.net.intent.IntentEvent;
58import org.onosproject.net.intent.IntentListener;
59import org.onosproject.net.intent.IntentService;
60import org.onosproject.net.intent.IntentState;
Brian Stanke86914282016-05-25 15:36:50 -040061import org.onosproject.net.link.LinkService;
Thomas Vachuska3d62fd72015-09-25 14:58:13 -070062import org.onosproject.net.provider.AbstractListenerProviderRegistry;
63import org.onosproject.net.provider.AbstractProviderService;
Claudine Chiu45920dd2016-07-28 19:19:46 +000064import org.onosproject.net.topology.PathService;
Brian Stanke8e9f8d12016-06-08 14:48:33 -040065import org.onosproject.net.topology.TopologyService;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070066import org.slf4j.Logger;
67import org.slf4j.LoggerFactory;
68
Brian Stanke86914282016-05-25 15:36:50 -040069import java.util.Map;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070070import java.util.Set;
71
72import static com.google.common.base.Preconditions.checkNotNull;
73
74/**
75 * Implementation of the virtual network service.
76 */
77@Component(immediate = true)
78@Service
79public class VirtualNetworkManager
Thomas Vachuska3d62fd72015-09-25 14:58:13 -070080 extends AbstractListenerProviderRegistry<VirtualNetworkEvent, VirtualNetworkListener,
Brian Stankefb61df42016-07-25 11:47:51 -040081 VirtualNetworkProvider, VirtualNetworkProviderService>
Thomas Vachuska858f65b2016-07-06 10:46:01 -070082 implements VirtualNetworkService, VirtualNetworkAdminService, VirtualNetworkProviderRegistry {
Thomas Vachuska33979fd2015-07-31 11:41:14 -070083
84 private final Logger log = LoggerFactory.getLogger(getClass());
85
86 private static final String TENANT_NULL = "Tenant ID cannot be null";
87 private static final String NETWORK_NULL = "Network ID cannot be null";
88 private static final String DEVICE_NULL = "Device ID cannot be null";
89 private static final String LINK_POINT_NULL = "Link end-point cannot be null";
90
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 protected VirtualNetworkStore store;
93
Brian Stanke11f6d532016-07-05 16:17:59 -040094 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
95 protected IntentService intentService;
96
97 private final InternalVirtualIntentListener intentListener = new InternalVirtualIntentListener();
98
Brian Stanke0e5c94e2016-03-08 11:20:04 -050099 private VirtualNetworkStoreDelegate delegate = this::post;
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700100
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700101 // TODO: figure out how to coordinate "implementation" of a virtual network in a cluster
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700102
Brian Stanke11f6d532016-07-05 16:17:59 -0400103 /**
104 * Only used for Junit test methods outside of this package.
105 *
106 * @param store virtual network store
107 */
108 public void setStore(VirtualNetworkStore store) {
109 this.store = store;
110 }
111
112 /**
113 * Only used for Junit test methods outside of this package.
114 *
115 * @param intentService intent service
116 */
117
118 public void setIntentService(IntentService intentService) {
119 this.intentService = intentService;
120 }
121
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700122 @Activate
Brian Stanke11f6d532016-07-05 16:17:59 -0400123 public void activate() {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700124 store.setDelegate(delegate);
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500125 eventDispatcher.addSink(VirtualNetworkEvent.class, listenerRegistry);
Brian Stanke11f6d532016-07-05 16:17:59 -0400126 intentService.addListener(intentListener);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700127 log.info("Started");
128 }
129
130 @Deactivate
Brian Stanke11f6d532016-07-05 16:17:59 -0400131 public void deactivate() {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700132 store.unsetDelegate(delegate);
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500133 eventDispatcher.removeSink(VirtualNetworkEvent.class);
Brian Stanke11f6d532016-07-05 16:17:59 -0400134 intentService.removeListener(intentListener);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700135 log.info("Stopped");
136 }
137
138 @Override
139 public void registerTenantId(TenantId tenantId) {
140 checkNotNull(tenantId, TENANT_NULL);
141 store.addTenantId(tenantId);
142 }
143
144 @Override
145 public void unregisterTenantId(TenantId tenantId) {
146 checkNotNull(tenantId, TENANT_NULL);
147 store.removeTenantId(tenantId);
148 }
149
150 @Override
151 public Set<TenantId> getTenantIds() {
152 return store.getTenantIds();
153 }
154
155 @Override
156 public VirtualNetwork createVirtualNetwork(TenantId tenantId) {
157 checkNotNull(tenantId, TENANT_NULL);
158 return store.addNetwork(tenantId);
159 }
160
161 @Override
162 public void removeVirtualNetwork(NetworkId networkId) {
163 checkNotNull(networkId, NETWORK_NULL);
164 store.removeNetwork(networkId);
165 }
166
167 @Override
168 public VirtualDevice createVirtualDevice(NetworkId networkId, DeviceId deviceId) {
169 checkNotNull(networkId, NETWORK_NULL);
170 checkNotNull(deviceId, DEVICE_NULL);
171 return store.addDevice(networkId, deviceId);
172 }
173
174 @Override
175 public void removeVirtualDevice(NetworkId networkId, DeviceId deviceId) {
176 checkNotNull(networkId, NETWORK_NULL);
177 checkNotNull(deviceId, DEVICE_NULL);
178 store.removeDevice(networkId, deviceId);
179 }
180
181 @Override
Brian Stanke7a81b532016-06-14 15:43:51 -0400182 public VirtualHost createVirtualHost(NetworkId networkId, HostId hostId, MacAddress mac,
183 VlanId vlan, HostLocation location, Set<IpAddress> ips) {
184 checkNotNull(networkId, NETWORK_NULL);
185 checkNotNull(hostId, DEVICE_NULL);
186 return store.addHost(networkId, hostId, mac, vlan, location, ips);
187 }
188
189 @Override
190 public void removeVirtualHost(NetworkId networkId, HostId hostId) {
191 checkNotNull(networkId, NETWORK_NULL);
192 checkNotNull(hostId, DEVICE_NULL);
193 store.removeHost(networkId, hostId);
194 }
195
196 @Override
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700197 public VirtualLink createVirtualLink(NetworkId networkId,
Brian Stanke9a108972016-04-11 15:25:17 -0400198 ConnectPoint src, ConnectPoint dst) {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700199 checkNotNull(networkId, NETWORK_NULL);
200 checkNotNull(src, LINK_POINT_NULL);
201 checkNotNull(dst, LINK_POINT_NULL);
Brian Stankefb61df42016-07-25 11:47:51 -0400202 ConnectPoint physicalSrc = mapVirtualToPhysicalPort(networkId, src);
203 checkNotNull(physicalSrc, LINK_POINT_NULL);
204 ConnectPoint physicalDst = mapVirtualToPhysicalPort(networkId, dst);
205 checkNotNull(physicalDst, LINK_POINT_NULL);
206
207 VirtualNetworkProvider provider = getProvider(DefaultVirtualLink.PID);
208 Link.State state = Link.State.INACTIVE;
209 if (provider != null) {
210 boolean traversable = provider.isTraversable(physicalSrc, physicalDst);
211 state = traversable ? Link.State.ACTIVE : Link.State.INACTIVE;
212 }
213 return store.addLink(networkId, src, dst, state, null);
214 }
215
216 /**
217 * Maps the virtual connect point to a physical connect point.
218 *
219 * @param networkId network identifier
220 * @param virtualCp virtual connect point
221 * @return physical connect point
222 */
223 private ConnectPoint mapVirtualToPhysicalPort(NetworkId networkId,
224 ConnectPoint virtualCp) {
225 Set<VirtualPort> ports = store.getPorts(networkId, virtualCp.deviceId());
226 for (VirtualPort port : ports) {
227 if (port.number().equals(virtualCp.port())) {
228 return new ConnectPoint(port.realizedBy().element().id(), port.realizedBy().number());
229 }
230 }
231 return null;
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700232 }
233
Brian Stanke612cebf2016-05-02 10:21:33 -0400234 /**
235 * Maps the physical connect point to a virtual connect point.
236 *
Brian Stanke11f6d532016-07-05 16:17:59 -0400237 * @param networkId network identifier
Brian Stanke612cebf2016-05-02 10:21:33 -0400238 * @param physicalCp physical connect point
239 * @return virtual connect point
240 */
241 private ConnectPoint mapPhysicalToVirtualToPort(NetworkId networkId,
Brian Stanke11f6d532016-07-05 16:17:59 -0400242 ConnectPoint physicalCp) {
Brian Stanke612cebf2016-05-02 10:21:33 -0400243 Set<VirtualPort> ports = store.getPorts(networkId, null);
244 for (VirtualPort port : ports) {
245 if (port.realizedBy().element().id().equals(physicalCp.elementId()) &&
246 port.realizedBy().number().equals(physicalCp.port())) {
247 return new ConnectPoint(port.element().id(), port.number());
248 }
249 }
250 return null;
251 }
252
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700253 @Override
254 public void removeVirtualLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
255 checkNotNull(networkId, NETWORK_NULL);
256 checkNotNull(src, LINK_POINT_NULL);
257 checkNotNull(dst, LINK_POINT_NULL);
Brian Stanke11f6d532016-07-05 16:17:59 -0400258 store.removeLink(networkId, src, dst);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700259 }
260
261 @Override
262 public VirtualPort createVirtualPort(NetworkId networkId, DeviceId deviceId,
263 PortNumber portNumber, Port realizedBy) {
264 checkNotNull(networkId, NETWORK_NULL);
265 checkNotNull(deviceId, DEVICE_NULL);
266 checkNotNull(portNumber, "Port description cannot be null");
267 return store.addPort(networkId, deviceId, portNumber, realizedBy);
268 }
269
270 @Override
271 public void removeVirtualPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
272 checkNotNull(networkId, NETWORK_NULL);
273 checkNotNull(deviceId, DEVICE_NULL);
274 checkNotNull(portNumber, "Port number cannot be null");
275 store.removePort(networkId, deviceId, portNumber);
276 }
277
278 @Override
279 public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
280 checkNotNull(tenantId, TENANT_NULL);
281 return store.getNetworks(tenantId);
282 }
283
Brian Stanke11f6d532016-07-05 16:17:59 -0400284 /**
285 * Returns the virtual network matching the network identifier.
286 *
287 * @param networkId network identifier
288 * @return virtual network
289 */
Brian Stanke86914282016-05-25 15:36:50 -0400290 private VirtualNetwork getVirtualNetwork(NetworkId networkId) {
291 checkNotNull(networkId, NETWORK_NULL);
292 return store.getNetwork(networkId);
293 }
294
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700295 @Override
296 public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
297 checkNotNull(networkId, NETWORK_NULL);
298 return store.getDevices(networkId);
299 }
300
301 @Override
Brian Stanke7a81b532016-06-14 15:43:51 -0400302 public Set<VirtualHost> getVirtualHosts(NetworkId networkId) {
303 checkNotNull(networkId, NETWORK_NULL);
304 return store.getHosts(networkId);
305 }
306
307 @Override
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700308 public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
309 checkNotNull(networkId, NETWORK_NULL);
310 return store.getLinks(networkId);
311 }
312
313 @Override
314 public Set<VirtualPort> getVirtualPorts(NetworkId networkId, DeviceId deviceId) {
315 checkNotNull(networkId, NETWORK_NULL);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700316 return store.getPorts(networkId, deviceId);
317 }
318
Brian Stanke86914282016-05-25 15:36:50 -0400319 private final Map<ServiceKey, VnetService> networkServices = Maps.newConcurrentMap();
320
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700321 @Override
322 public <T> T get(NetworkId networkId, Class<T> serviceClass) {
323 checkNotNull(networkId, NETWORK_NULL);
Brian Stanke86914282016-05-25 15:36:50 -0400324 ServiceKey serviceKey = networkServiceKey(networkId, serviceClass);
325 VnetService service = lookup(serviceKey);
326 if (service == null) {
327 service = create(serviceKey);
328 }
329 return (T) service;
330 }
331
Brian Stanke11f6d532016-07-05 16:17:59 -0400332 /**
333 * Returns the Vnet service matching the service key.
334 *
335 * @param serviceKey service key
336 * @return vnet service
337 */
Brian Stanke86914282016-05-25 15:36:50 -0400338 private VnetService lookup(ServiceKey serviceKey) {
339 return networkServices.get(serviceKey);
340 }
341
Brian Stanke11f6d532016-07-05 16:17:59 -0400342 /**
343 * Creates a new service key using the specified network identifier and service class.
344 *
345 * @param networkId network identifier
346 * @param serviceClass service class
347 * @param <T> type of service
348 * @return service key
349 */
Brian Stanke86914282016-05-25 15:36:50 -0400350 private <T> ServiceKey networkServiceKey(NetworkId networkId, Class<T> serviceClass) {
351 return new ServiceKey(networkId, serviceClass);
352 }
353
354
Brian Stanke11f6d532016-07-05 16:17:59 -0400355 /**
356 * Create a new vnet service instance.
357 *
358 * @param serviceKey service key
359 * @return vnet service
360 */
Brian Stanke86914282016-05-25 15:36:50 -0400361 private VnetService create(ServiceKey serviceKey) {
362 VirtualNetwork network = getVirtualNetwork(serviceKey.networkId());
Brian Stanke11f6d532016-07-05 16:17:59 -0400363 checkNotNull(network, NETWORK_NULL);
Brian Stanke86914282016-05-25 15:36:50 -0400364 VnetService service;
365 if (serviceKey.serviceClass.equals(DeviceService.class)) {
366 service = new VirtualNetworkDeviceService(this, network);
367 } else if (serviceKey.serviceClass.equals(LinkService.class)) {
368 service = new VirtualNetworkLinkService(this, network);
Brian Stanke8e9f8d12016-06-08 14:48:33 -0400369 } else if (serviceKey.serviceClass.equals(TopologyService.class)) {
370 service = new VirtualNetworkTopologyService(this, network);
Brian Stanke11f6d532016-07-05 16:17:59 -0400371 } else if (serviceKey.serviceClass.equals(IntentService.class)) {
372 service = new VirtualNetworkIntentService(this, network, new DefaultServiceDirectory());
Claudine Chiu30a8a2a2016-07-14 17:09:04 -0400373 } else if (serviceKey.serviceClass.equals(HostService.class)) {
374 service = new VirtualNetworkHostService(this, network);
Claudine Chiu45920dd2016-07-28 19:19:46 +0000375 } else if (serviceKey.serviceClass.equals(PathService.class)) {
376 service = new VirtualNetworkPathService(this, network);
Brian Stanke86914282016-05-25 15:36:50 -0400377 } else {
378 return null;
379 }
380 networkServices.put(serviceKey, service);
381 return service;
382 }
383
Brian Stanke11f6d532016-07-05 16:17:59 -0400384 /**
385 * Service key class.
386 */
Brian Stanke86914282016-05-25 15:36:50 -0400387 private class ServiceKey {
388 final NetworkId networkId;
389 final Class serviceClass;
390
Brian Stanke11f6d532016-07-05 16:17:59 -0400391 /**
392 * Constructor for service key.
393 *
394 * @param networkId network identifier
395 * @param serviceClass service class
396 */
Brian Stanke86914282016-05-25 15:36:50 -0400397 public ServiceKey(NetworkId networkId, Class serviceClass) {
398 checkNotNull(networkId, NETWORK_NULL);
399 this.networkId = networkId;
400 this.serviceClass = serviceClass;
401 }
402
Brian Stanke11f6d532016-07-05 16:17:59 -0400403 /**
404 * Returns the network identifier.
405 *
406 * @return network identifier
407 */
Brian Stanke86914282016-05-25 15:36:50 -0400408 public NetworkId networkId() {
409 return networkId;
410 }
411
Brian Stanke11f6d532016-07-05 16:17:59 -0400412 /**
413 * Returns the service class.
414 *
415 * @return service class
416 */
Brian Stanke86914282016-05-25 15:36:50 -0400417 public Class serviceClass() {
418 return serviceClass;
419 }
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700420 }
421
Brian Stanke11f6d532016-07-05 16:17:59 -0400422 /**
423 * Internal intent event listener.
424 */
425 private class InternalVirtualIntentListener implements IntentListener {
426 @Override
427 public void event(IntentEvent event) {
428
429 // Ignore intent events that are not relevant.
430 if (!isRelevant(event)) {
431 return;
432 }
433
434 VirtualNetworkIntent intent = (VirtualNetworkIntent) event.subject();
435
436 switch (event.type()) {
437 case INSTALL_REQ:
438 store.addOrUpdateIntent(intent, IntentState.INSTALL_REQ);
439 break;
440 case INSTALLED:
441 store.addOrUpdateIntent(intent, IntentState.INSTALLED);
442 break;
443 case WITHDRAW_REQ:
444 store.addOrUpdateIntent(intent, IntentState.WITHDRAW_REQ);
445 break;
446 case WITHDRAWN:
447 store.addOrUpdateIntent(intent, IntentState.WITHDRAWN);
448 break;
449 case FAILED:
450 store.addOrUpdateIntent(intent, IntentState.FAILED);
451 break;
452 case CORRUPT:
453 store.addOrUpdateIntent(intent, IntentState.CORRUPT);
454 break;
455 case PURGED:
456 store.removeIntent(intent.key());
457 default:
458 break;
459 }
460 }
461
462 @Override
463 public boolean isRelevant(IntentEvent event) {
464 if (event.subject() instanceof VirtualNetworkIntent) {
465 return true;
466 }
467 return false;
468 }
469 }
470
471
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700472 @Override
473 protected VirtualNetworkProviderService createProviderService(VirtualNetworkProvider provider) {
474 return new InternalVirtualNetworkProviderService(provider);
475 }
476
Brian Stankefb61df42016-07-25 11:47:51 -0400477 /**
478 * Service issued to registered virtual network providers so that they
479 * can interact with the core.
480 */
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700481 private class InternalVirtualNetworkProviderService
482 extends AbstractProviderService<VirtualNetworkProvider>
483 implements VirtualNetworkProviderService {
Brian Stankefb61df42016-07-25 11:47:51 -0400484 /**
485 * Constructor.
486 * @param provider virtual network provider
487 */
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700488 InternalVirtualNetworkProviderService(VirtualNetworkProvider provider) {
489 super(provider);
490 }
Brian Stanke4d579882016-04-22 13:28:46 -0400491
492 @Override
Brian Stankefb61df42016-07-25 11:47:51 -0400493 public void topologyChanged(Set<Set<ConnectPoint>> clusters) {
494
495 Set<TenantId> tenantIds = getTenantIds();
496 tenantIds.forEach(tenantId -> {
497 Set<VirtualNetwork> virtualNetworks = getVirtualNetworks(tenantId);
498
499 virtualNetworks.forEach(virtualNetwork -> {
500 Set<VirtualLink> virtualLinks = getVirtualLinks(virtualNetwork.id());
501
502 virtualLinks.forEach(virtualLink -> {
503 if (isVirtualLinkInCluster(virtualNetwork.id(), virtualLink, clusters)) {
504 store.updateLink(virtualLink, virtualLink.tunnelId(), Link.State.ACTIVE);
505 } else {
506 store.updateLink(virtualLink, virtualLink.tunnelId(), Link.State.INACTIVE);
507 }
508 });
509 });
510 });
511 }
512
513 /**
514 * Determines if the virtual link (both source and destination connect point) is in a cluster.
515 *
516 * @param networkId virtual network identifier
517 * @param virtualLink virtual link
518 * @param clusters topology clusters
519 * @return true if the virtual link is in a cluster.
520 */
521 private boolean isVirtualLinkInCluster(NetworkId networkId, VirtualLink virtualLink,
522 Set<Set<ConnectPoint>> clusters) {
523 ConnectPoint srcPhysicalCp = mapVirtualToPhysicalPort(networkId, virtualLink.src());
524 ConnectPoint dstPhysicalCp = mapVirtualToPhysicalPort(networkId, virtualLink.dst());
525
526 final boolean[] foundSrc = {false};
527 final boolean[] foundDst = {false};
528 clusters.forEach(connectPoints -> {
529 connectPoints.forEach(connectPoint -> {
530 if (connectPoint.equals(srcPhysicalCp)) {
531 foundSrc[0] = true;
532 } else if (connectPoint.equals(dstPhysicalCp)) {
533 foundDst[0] = true;
534 }
535 });
536 if (foundSrc[0] && foundDst[0]) {
537 return;
538 }
539 });
540 return foundSrc[0] && foundDst[0];
541 }
542
543 @Override
Brian Stanke612cebf2016-05-02 10:21:33 -0400544 public void tunnelUp(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) {
Brian Stanke4d579882016-04-22 13:28:46 -0400545
Brian Stanke612cebf2016-05-02 10:21:33 -0400546 ConnectPoint srcVirtualCp = mapPhysicalToVirtualToPort(networkId, src);
547 ConnectPoint dstVirtualCp = mapPhysicalToVirtualToPort(networkId, dst);
548 if ((srcVirtualCp == null) || (dstVirtualCp == null)) {
549 log.error("Src or dst virtual connection point was not found.");
550 }
551
552 VirtualLink virtualLink = store.getLink(networkId, srcVirtualCp, dstVirtualCp);
553 if (virtualLink != null) {
554 store.updateLink(virtualLink, tunnelId, Link.State.ACTIVE);
555 }
Brian Stanke4d579882016-04-22 13:28:46 -0400556 }
557
558 @Override
Brian Stanke612cebf2016-05-02 10:21:33 -0400559 public void tunnelDown(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) {
560 ConnectPoint srcVirtualCp = mapPhysicalToVirtualToPort(networkId, src);
561 ConnectPoint dstVirtualCp = mapPhysicalToVirtualToPort(networkId, dst);
562 if ((srcVirtualCp == null) || (dstVirtualCp == null)) {
563 log.error("Src or dst virtual connection point was not found.");
564 }
Brian Stanke4d579882016-04-22 13:28:46 -0400565
Brian Stanke612cebf2016-05-02 10:21:33 -0400566 VirtualLink virtualLink = store.getLink(networkId, srcVirtualCp, dstVirtualCp);
567 if (virtualLink != null) {
568 store.updateLink(virtualLink, tunnelId, Link.State.INACTIVE);
569 }
Brian Stanke4d579882016-04-22 13:28:46 -0400570 }
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700571 }
572
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700573}