blob: b75c2d5f8758c5d7e823cf1c26efc1c75039023c [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.PortNumber;
Brian Stanke86914282016-05-25 15:36:50 -040054import org.onosproject.net.device.DeviceService;
Claudine Chiu30a8a2a2016-07-14 17:09:04 -040055import org.onosproject.net.host.HostService;
Brian Stanke11f6d532016-07-05 16:17:59 -040056import org.onosproject.net.intent.IntentEvent;
57import org.onosproject.net.intent.IntentListener;
58import org.onosproject.net.intent.IntentService;
59import org.onosproject.net.intent.IntentState;
Brian Stanke86914282016-05-25 15:36:50 -040060import org.onosproject.net.link.LinkService;
Thomas Vachuska3d62fd72015-09-25 14:58:13 -070061import org.onosproject.net.provider.AbstractListenerProviderRegistry;
62import org.onosproject.net.provider.AbstractProviderService;
Claudine Chiu45920dd2016-07-28 19:19:46 +000063import org.onosproject.net.topology.PathService;
Brian Stanke8e9f8d12016-06-08 14:48:33 -040064import org.onosproject.net.topology.TopologyService;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070065import org.slf4j.Logger;
66import org.slf4j.LoggerFactory;
67
Brian Stanke86914282016-05-25 15:36:50 -040068import java.util.Map;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070069import java.util.Set;
70
71import static com.google.common.base.Preconditions.checkNotNull;
72
73/**
74 * Implementation of the virtual network service.
75 */
76@Component(immediate = true)
77@Service
78public class VirtualNetworkManager
Thomas Vachuska3d62fd72015-09-25 14:58:13 -070079 extends AbstractListenerProviderRegistry<VirtualNetworkEvent, VirtualNetworkListener,
Brian Stankefb61df42016-07-25 11:47:51 -040080 VirtualNetworkProvider, VirtualNetworkProviderService>
Thomas Vachuska858f65b2016-07-06 10:46:01 -070081 implements VirtualNetworkService, VirtualNetworkAdminService, VirtualNetworkProviderRegistry {
Thomas Vachuska33979fd2015-07-31 11:41:14 -070082
83 private final Logger log = LoggerFactory.getLogger(getClass());
84
85 private static final String TENANT_NULL = "Tenant ID cannot be null";
86 private static final String NETWORK_NULL = "Network ID cannot be null";
87 private static final String DEVICE_NULL = "Device ID cannot be null";
88 private static final String LINK_POINT_NULL = "Link end-point cannot be null";
89
90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 protected VirtualNetworkStore store;
92
Brian Stanke11f6d532016-07-05 16:17:59 -040093 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected IntentService intentService;
95
96 private final InternalVirtualIntentListener intentListener = new InternalVirtualIntentListener();
97
Brian Stanke0e5c94e2016-03-08 11:20:04 -050098 private VirtualNetworkStoreDelegate delegate = this::post;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070099
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700100 // TODO: figure out how to coordinate "implementation" of a virtual network in a cluster
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700101
Brian Stanke11f6d532016-07-05 16:17:59 -0400102 /**
103 * Only used for Junit test methods outside of this package.
104 *
105 * @param store virtual network store
106 */
107 public void setStore(VirtualNetworkStore store) {
108 this.store = store;
109 }
110
111 /**
112 * Only used for Junit test methods outside of this package.
113 *
114 * @param intentService intent service
115 */
116
117 public void setIntentService(IntentService intentService) {
118 this.intentService = intentService;
119 }
120
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700121 @Activate
Brian Stanke11f6d532016-07-05 16:17:59 -0400122 public void activate() {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700123 store.setDelegate(delegate);
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500124 eventDispatcher.addSink(VirtualNetworkEvent.class, listenerRegistry);
Brian Stanke11f6d532016-07-05 16:17:59 -0400125 intentService.addListener(intentListener);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700126 log.info("Started");
127 }
128
129 @Deactivate
Brian Stanke11f6d532016-07-05 16:17:59 -0400130 public void deactivate() {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700131 store.unsetDelegate(delegate);
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500132 eventDispatcher.removeSink(VirtualNetworkEvent.class);
Brian Stanke11f6d532016-07-05 16:17:59 -0400133 intentService.removeListener(intentListener);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700134 log.info("Stopped");
135 }
136
137 @Override
138 public void registerTenantId(TenantId tenantId) {
139 checkNotNull(tenantId, TENANT_NULL);
140 store.addTenantId(tenantId);
141 }
142
143 @Override
144 public void unregisterTenantId(TenantId tenantId) {
145 checkNotNull(tenantId, TENANT_NULL);
146 store.removeTenantId(tenantId);
147 }
148
149 @Override
150 public Set<TenantId> getTenantIds() {
151 return store.getTenantIds();
152 }
153
154 @Override
155 public VirtualNetwork createVirtualNetwork(TenantId tenantId) {
156 checkNotNull(tenantId, TENANT_NULL);
157 return store.addNetwork(tenantId);
158 }
159
160 @Override
161 public void removeVirtualNetwork(NetworkId networkId) {
162 checkNotNull(networkId, NETWORK_NULL);
163 store.removeNetwork(networkId);
164 }
165
166 @Override
167 public VirtualDevice createVirtualDevice(NetworkId networkId, DeviceId deviceId) {
168 checkNotNull(networkId, NETWORK_NULL);
169 checkNotNull(deviceId, DEVICE_NULL);
170 return store.addDevice(networkId, deviceId);
171 }
172
173 @Override
174 public void removeVirtualDevice(NetworkId networkId, DeviceId deviceId) {
175 checkNotNull(networkId, NETWORK_NULL);
176 checkNotNull(deviceId, DEVICE_NULL);
177 store.removeDevice(networkId, deviceId);
178 }
179
180 @Override
Brian Stanke7a81b532016-06-14 15:43:51 -0400181 public VirtualHost createVirtualHost(NetworkId networkId, HostId hostId, MacAddress mac,
182 VlanId vlan, HostLocation location, Set<IpAddress> ips) {
183 checkNotNull(networkId, NETWORK_NULL);
184 checkNotNull(hostId, DEVICE_NULL);
185 return store.addHost(networkId, hostId, mac, vlan, location, ips);
186 }
187
188 @Override
189 public void removeVirtualHost(NetworkId networkId, HostId hostId) {
190 checkNotNull(networkId, NETWORK_NULL);
191 checkNotNull(hostId, DEVICE_NULL);
192 store.removeHost(networkId, hostId);
193 }
194
195 @Override
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700196 public VirtualLink createVirtualLink(NetworkId networkId,
Brian Stanke9a108972016-04-11 15:25:17 -0400197 ConnectPoint src, ConnectPoint dst) {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700198 checkNotNull(networkId, NETWORK_NULL);
199 checkNotNull(src, LINK_POINT_NULL);
200 checkNotNull(dst, LINK_POINT_NULL);
Brian Stankefb61df42016-07-25 11:47:51 -0400201 ConnectPoint physicalSrc = mapVirtualToPhysicalPort(networkId, src);
202 checkNotNull(physicalSrc, LINK_POINT_NULL);
203 ConnectPoint physicalDst = mapVirtualToPhysicalPort(networkId, dst);
204 checkNotNull(physicalDst, LINK_POINT_NULL);
205
206 VirtualNetworkProvider provider = getProvider(DefaultVirtualLink.PID);
207 Link.State state = Link.State.INACTIVE;
208 if (provider != null) {
209 boolean traversable = provider.isTraversable(physicalSrc, physicalDst);
210 state = traversable ? Link.State.ACTIVE : Link.State.INACTIVE;
211 }
212 return store.addLink(networkId, src, dst, state, null);
213 }
214
215 /**
216 * Maps the virtual connect point to a physical connect point.
217 *
218 * @param networkId network identifier
219 * @param virtualCp virtual connect point
220 * @return physical connect point
221 */
222 private ConnectPoint mapVirtualToPhysicalPort(NetworkId networkId,
223 ConnectPoint virtualCp) {
224 Set<VirtualPort> ports = store.getPorts(networkId, virtualCp.deviceId());
225 for (VirtualPort port : ports) {
226 if (port.number().equals(virtualCp.port())) {
Yoonseon Han6c603892016-09-01 11:52:21 -0700227 return new ConnectPoint(port.realizedBy().deviceId(),
228 port.realizedBy().port());
Brian Stankefb61df42016-07-25 11:47:51 -0400229 }
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) {
Yoonseon Han6c603892016-09-01 11:52:21 -0700245 if (port.realizedBy().deviceId().equals(physicalCp.elementId()) &&
246 port.realizedBy().port().equals(physicalCp.port())) {
Brian Stanke612cebf2016-05-02 10:21:33 -0400247 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,
Yoonseon Han6c603892016-09-01 11:52:21 -0700263 PortNumber portNumber, ConnectPoint realizedBy) {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700264 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
Yoonseon Han6c603892016-09-01 11:52:21 -0700271 public void bindVirtualPort(NetworkId networkId, DeviceId deviceId,
272 PortNumber portNumber, ConnectPoint realizedBy) {
273 checkNotNull(networkId, NETWORK_NULL);
274 checkNotNull(deviceId, DEVICE_NULL);
275 checkNotNull(portNumber, "Port description cannot be null");
276 checkNotNull(realizedBy, "Physical port description cannot be null");
277
278 store.bindPort(networkId, deviceId, portNumber, realizedBy);
279 }
280
281 @Override
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700282 public void removeVirtualPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
283 checkNotNull(networkId, NETWORK_NULL);
284 checkNotNull(deviceId, DEVICE_NULL);
285 checkNotNull(portNumber, "Port number cannot be null");
286 store.removePort(networkId, deviceId, portNumber);
287 }
288
289 @Override
290 public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
291 checkNotNull(tenantId, TENANT_NULL);
292 return store.getNetworks(tenantId);
293 }
294
Brian Stanke11f6d532016-07-05 16:17:59 -0400295 /**
296 * Returns the virtual network matching the network identifier.
297 *
298 * @param networkId network identifier
299 * @return virtual network
300 */
Brian Stanke86914282016-05-25 15:36:50 -0400301 private VirtualNetwork getVirtualNetwork(NetworkId networkId) {
302 checkNotNull(networkId, NETWORK_NULL);
303 return store.getNetwork(networkId);
304 }
305
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700306 @Override
307 public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
308 checkNotNull(networkId, NETWORK_NULL);
309 return store.getDevices(networkId);
310 }
311
312 @Override
Brian Stanke7a81b532016-06-14 15:43:51 -0400313 public Set<VirtualHost> getVirtualHosts(NetworkId networkId) {
314 checkNotNull(networkId, NETWORK_NULL);
315 return store.getHosts(networkId);
316 }
317
318 @Override
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700319 public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
320 checkNotNull(networkId, NETWORK_NULL);
321 return store.getLinks(networkId);
322 }
323
324 @Override
325 public Set<VirtualPort> getVirtualPorts(NetworkId networkId, DeviceId deviceId) {
326 checkNotNull(networkId, NETWORK_NULL);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700327 return store.getPorts(networkId, deviceId);
328 }
329
Brian Stanke86914282016-05-25 15:36:50 -0400330 private final Map<ServiceKey, VnetService> networkServices = Maps.newConcurrentMap();
331
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700332 @Override
333 public <T> T get(NetworkId networkId, Class<T> serviceClass) {
334 checkNotNull(networkId, NETWORK_NULL);
Brian Stanke86914282016-05-25 15:36:50 -0400335 ServiceKey serviceKey = networkServiceKey(networkId, serviceClass);
336 VnetService service = lookup(serviceKey);
337 if (service == null) {
338 service = create(serviceKey);
339 }
340 return (T) service;
341 }
342
Brian Stanke11f6d532016-07-05 16:17:59 -0400343 /**
344 * Returns the Vnet service matching the service key.
345 *
346 * @param serviceKey service key
347 * @return vnet service
348 */
Brian Stanke86914282016-05-25 15:36:50 -0400349 private VnetService lookup(ServiceKey serviceKey) {
350 return networkServices.get(serviceKey);
351 }
352
Brian Stanke11f6d532016-07-05 16:17:59 -0400353 /**
354 * Creates a new service key using the specified network identifier and service class.
355 *
356 * @param networkId network identifier
357 * @param serviceClass service class
358 * @param <T> type of service
359 * @return service key
360 */
Brian Stanke86914282016-05-25 15:36:50 -0400361 private <T> ServiceKey networkServiceKey(NetworkId networkId, Class<T> serviceClass) {
362 return new ServiceKey(networkId, serviceClass);
363 }
364
365
Brian Stanke11f6d532016-07-05 16:17:59 -0400366 /**
367 * Create a new vnet service instance.
368 *
369 * @param serviceKey service key
370 * @return vnet service
371 */
Brian Stanke86914282016-05-25 15:36:50 -0400372 private VnetService create(ServiceKey serviceKey) {
373 VirtualNetwork network = getVirtualNetwork(serviceKey.networkId());
Brian Stanke11f6d532016-07-05 16:17:59 -0400374 checkNotNull(network, NETWORK_NULL);
Brian Stanke86914282016-05-25 15:36:50 -0400375 VnetService service;
376 if (serviceKey.serviceClass.equals(DeviceService.class)) {
377 service = new VirtualNetworkDeviceService(this, network);
378 } else if (serviceKey.serviceClass.equals(LinkService.class)) {
379 service = new VirtualNetworkLinkService(this, network);
Brian Stanke8e9f8d12016-06-08 14:48:33 -0400380 } else if (serviceKey.serviceClass.equals(TopologyService.class)) {
381 service = new VirtualNetworkTopologyService(this, network);
Brian Stanke11f6d532016-07-05 16:17:59 -0400382 } else if (serviceKey.serviceClass.equals(IntentService.class)) {
383 service = new VirtualNetworkIntentService(this, network, new DefaultServiceDirectory());
Claudine Chiu30a8a2a2016-07-14 17:09:04 -0400384 } else if (serviceKey.serviceClass.equals(HostService.class)) {
385 service = new VirtualNetworkHostService(this, network);
Claudine Chiu45920dd2016-07-28 19:19:46 +0000386 } else if (serviceKey.serviceClass.equals(PathService.class)) {
387 service = new VirtualNetworkPathService(this, network);
Brian Stanke86914282016-05-25 15:36:50 -0400388 } else {
389 return null;
390 }
391 networkServices.put(serviceKey, service);
392 return service;
393 }
394
Brian Stanke11f6d532016-07-05 16:17:59 -0400395 /**
396 * Service key class.
397 */
Brian Stanke86914282016-05-25 15:36:50 -0400398 private class ServiceKey {
399 final NetworkId networkId;
400 final Class serviceClass;
401
Brian Stanke11f6d532016-07-05 16:17:59 -0400402 /**
403 * Constructor for service key.
404 *
405 * @param networkId network identifier
406 * @param serviceClass service class
407 */
Brian Stanke86914282016-05-25 15:36:50 -0400408 public ServiceKey(NetworkId networkId, Class serviceClass) {
409 checkNotNull(networkId, NETWORK_NULL);
410 this.networkId = networkId;
411 this.serviceClass = serviceClass;
412 }
413
Brian Stanke11f6d532016-07-05 16:17:59 -0400414 /**
415 * Returns the network identifier.
416 *
417 * @return network identifier
418 */
Brian Stanke86914282016-05-25 15:36:50 -0400419 public NetworkId networkId() {
420 return networkId;
421 }
422
Brian Stanke11f6d532016-07-05 16:17:59 -0400423 /**
424 * Returns the service class.
425 *
426 * @return service class
427 */
Brian Stanke86914282016-05-25 15:36:50 -0400428 public Class serviceClass() {
429 return serviceClass;
430 }
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700431 }
432
Brian Stanke11f6d532016-07-05 16:17:59 -0400433 /**
434 * Internal intent event listener.
435 */
436 private class InternalVirtualIntentListener implements IntentListener {
437 @Override
438 public void event(IntentEvent event) {
439
440 // Ignore intent events that are not relevant.
441 if (!isRelevant(event)) {
442 return;
443 }
444
445 VirtualNetworkIntent intent = (VirtualNetworkIntent) event.subject();
446
447 switch (event.type()) {
448 case INSTALL_REQ:
449 store.addOrUpdateIntent(intent, IntentState.INSTALL_REQ);
450 break;
451 case INSTALLED:
452 store.addOrUpdateIntent(intent, IntentState.INSTALLED);
453 break;
454 case WITHDRAW_REQ:
455 store.addOrUpdateIntent(intent, IntentState.WITHDRAW_REQ);
456 break;
457 case WITHDRAWN:
458 store.addOrUpdateIntent(intent, IntentState.WITHDRAWN);
459 break;
460 case FAILED:
461 store.addOrUpdateIntent(intent, IntentState.FAILED);
462 break;
463 case CORRUPT:
464 store.addOrUpdateIntent(intent, IntentState.CORRUPT);
465 break;
466 case PURGED:
467 store.removeIntent(intent.key());
468 default:
469 break;
470 }
471 }
472
473 @Override
474 public boolean isRelevant(IntentEvent event) {
475 if (event.subject() instanceof VirtualNetworkIntent) {
476 return true;
477 }
478 return false;
479 }
480 }
481
482
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700483 @Override
484 protected VirtualNetworkProviderService createProviderService(VirtualNetworkProvider provider) {
485 return new InternalVirtualNetworkProviderService(provider);
486 }
487
Brian Stankefb61df42016-07-25 11:47:51 -0400488 /**
489 * Service issued to registered virtual network providers so that they
490 * can interact with the core.
491 */
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700492 private class InternalVirtualNetworkProviderService
493 extends AbstractProviderService<VirtualNetworkProvider>
494 implements VirtualNetworkProviderService {
Brian Stankefb61df42016-07-25 11:47:51 -0400495 /**
496 * Constructor.
497 * @param provider virtual network provider
498 */
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700499 InternalVirtualNetworkProviderService(VirtualNetworkProvider provider) {
500 super(provider);
501 }
Brian Stanke4d579882016-04-22 13:28:46 -0400502
503 @Override
Brian Stankefb61df42016-07-25 11:47:51 -0400504 public void topologyChanged(Set<Set<ConnectPoint>> clusters) {
505
506 Set<TenantId> tenantIds = getTenantIds();
507 tenantIds.forEach(tenantId -> {
508 Set<VirtualNetwork> virtualNetworks = getVirtualNetworks(tenantId);
509
510 virtualNetworks.forEach(virtualNetwork -> {
511 Set<VirtualLink> virtualLinks = getVirtualLinks(virtualNetwork.id());
512
513 virtualLinks.forEach(virtualLink -> {
514 if (isVirtualLinkInCluster(virtualNetwork.id(), virtualLink, clusters)) {
515 store.updateLink(virtualLink, virtualLink.tunnelId(), Link.State.ACTIVE);
516 } else {
517 store.updateLink(virtualLink, virtualLink.tunnelId(), Link.State.INACTIVE);
518 }
519 });
520 });
521 });
522 }
523
524 /**
525 * Determines if the virtual link (both source and destination connect point) is in a cluster.
526 *
527 * @param networkId virtual network identifier
528 * @param virtualLink virtual link
529 * @param clusters topology clusters
530 * @return true if the virtual link is in a cluster.
531 */
532 private boolean isVirtualLinkInCluster(NetworkId networkId, VirtualLink virtualLink,
533 Set<Set<ConnectPoint>> clusters) {
534 ConnectPoint srcPhysicalCp = mapVirtualToPhysicalPort(networkId, virtualLink.src());
535 ConnectPoint dstPhysicalCp = mapVirtualToPhysicalPort(networkId, virtualLink.dst());
536
537 final boolean[] foundSrc = {false};
538 final boolean[] foundDst = {false};
539 clusters.forEach(connectPoints -> {
540 connectPoints.forEach(connectPoint -> {
541 if (connectPoint.equals(srcPhysicalCp)) {
542 foundSrc[0] = true;
543 } else if (connectPoint.equals(dstPhysicalCp)) {
544 foundDst[0] = true;
545 }
546 });
547 if (foundSrc[0] && foundDst[0]) {
548 return;
549 }
550 });
551 return foundSrc[0] && foundDst[0];
552 }
553
554 @Override
Brian Stanke612cebf2016-05-02 10:21:33 -0400555 public void tunnelUp(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) {
Brian Stanke4d579882016-04-22 13:28:46 -0400556
Brian Stanke612cebf2016-05-02 10:21:33 -0400557 ConnectPoint srcVirtualCp = mapPhysicalToVirtualToPort(networkId, src);
558 ConnectPoint dstVirtualCp = mapPhysicalToVirtualToPort(networkId, dst);
559 if ((srcVirtualCp == null) || (dstVirtualCp == null)) {
560 log.error("Src or dst virtual connection point was not found.");
561 }
562
563 VirtualLink virtualLink = store.getLink(networkId, srcVirtualCp, dstVirtualCp);
564 if (virtualLink != null) {
565 store.updateLink(virtualLink, tunnelId, Link.State.ACTIVE);
566 }
Brian Stanke4d579882016-04-22 13:28:46 -0400567 }
568
569 @Override
Brian Stanke612cebf2016-05-02 10:21:33 -0400570 public void tunnelDown(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId tunnelId) {
571 ConnectPoint srcVirtualCp = mapPhysicalToVirtualToPort(networkId, src);
572 ConnectPoint dstVirtualCp = mapPhysicalToVirtualToPort(networkId, dst);
573 if ((srcVirtualCp == null) || (dstVirtualCp == null)) {
574 log.error("Src or dst virtual connection point was not found.");
575 }
Brian Stanke4d579882016-04-22 13:28:46 -0400576
Brian Stanke612cebf2016-05-02 10:21:33 -0400577 VirtualLink virtualLink = store.getLink(networkId, srcVirtualCp, dstVirtualCp);
578 if (virtualLink != null) {
579 store.updateLink(virtualLink, tunnelId, Link.State.INACTIVE);
580 }
Brian Stanke4d579882016-04-22 13:28:46 -0400581 }
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700582 }
583
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700584}