blob: f3c7281bbca58008adc0f01cf8e4341077ddfab3 [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;
41import org.onosproject.incubator.net.virtual.VirtualNetworkService;
42import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
43import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate;
44import org.onosproject.incubator.net.virtual.VirtualPort;
yoonseon214963b2016-11-21 15:41:07 -080045import org.onosproject.incubator.net.virtual.VnetService;
yoonseon6b972c32016-12-06 16:45:03 -080046import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProvider;
47import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderRegistry;
48import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderService;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070049import org.onosproject.net.ConnectPoint;
50import org.onosproject.net.DeviceId;
Brian Stanke7a81b532016-06-14 15:43:51 -040051import org.onosproject.net.HostId;
52import org.onosproject.net.HostLocation;
Brian Stanke612cebf2016-05-02 10:21:33 -040053import org.onosproject.net.Link;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070054import org.onosproject.net.PortNumber;
Brian Stanke86914282016-05-25 15:36:50 -040055import org.onosproject.net.device.DeviceService;
Claudine Chiu70222ad2016-11-17 22:29:20 -050056import org.onosproject.net.flow.FlowRuleService;
Claudine Chiu30a8a2a2016-07-14 17:09:04 -040057import org.onosproject.net.host.HostService;
Brian Stanke11f6d532016-07-05 16:17:59 -040058import org.onosproject.net.intent.IntentEvent;
59import org.onosproject.net.intent.IntentListener;
60import org.onosproject.net.intent.IntentService;
61import org.onosproject.net.intent.IntentState;
Brian Stanke86914282016-05-25 15:36:50 -040062import org.onosproject.net.link.LinkService;
Thomas Vachuska3d62fd72015-09-25 14:58:13 -070063import org.onosproject.net.provider.AbstractListenerProviderRegistry;
64import org.onosproject.net.provider.AbstractProviderService;
Claudine Chiu45920dd2016-07-28 19:19:46 +000065import org.onosproject.net.topology.PathService;
Brian Stanke8e9f8d12016-06-08 14:48:33 -040066import org.onosproject.net.topology.TopologyService;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070067import org.slf4j.Logger;
68import org.slf4j.LoggerFactory;
69
Brian Stanke86914282016-05-25 15:36:50 -040070import java.util.Map;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070071import java.util.Set;
72
73import static com.google.common.base.Preconditions.checkNotNull;
74
75/**
76 * Implementation of the virtual network service.
77 */
78@Component(immediate = true)
79@Service
80public class VirtualNetworkManager
yoonseon214963b2016-11-21 15:41:07 -080081 extends AbstractListenerProviderRegistry<VirtualNetworkEvent,
82 VirtualNetworkListener, VirtualNetworkProvider, VirtualNetworkProviderService>
83 implements VirtualNetworkService, VirtualNetworkAdminService,
84 VirtualNetworkProviderRegistry {
Thomas Vachuska33979fd2015-07-31 11:41:14 -070085
86 private final Logger log = LoggerFactory.getLogger(getClass());
87
88 private static final String TENANT_NULL = "Tenant ID cannot be null";
89 private static final String NETWORK_NULL = "Network ID cannot be null";
90 private static final String DEVICE_NULL = "Device ID cannot be null";
91 private static final String LINK_POINT_NULL = "Link end-point cannot be null";
92
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected VirtualNetworkStore store;
95
Brian Stanke11f6d532016-07-05 16:17:59 -040096 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected IntentService intentService;
98
yoonseon214963b2016-11-21 15:41:07 -080099 private final InternalVirtualIntentListener intentListener =
100 new InternalVirtualIntentListener();
Brian Stanke11f6d532016-07-05 16:17:59 -0400101
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500102 private VirtualNetworkStoreDelegate delegate = this::post;
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700103
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700104 // TODO: figure out how to coordinate "implementation" of a virtual network in a cluster
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700105
Brian Stanke11f6d532016-07-05 16:17:59 -0400106 /**
107 * Only used for Junit test methods outside of this package.
108 *
109 * @param store virtual network store
110 */
111 public void setStore(VirtualNetworkStore store) {
112 this.store = store;
113 }
114
115 /**
116 * Only used for Junit test methods outside of this package.
117 *
118 * @param intentService intent service
119 */
120
121 public void setIntentService(IntentService intentService) {
122 this.intentService = intentService;
123 }
124
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700125 @Activate
Brian Stanke11f6d532016-07-05 16:17:59 -0400126 public void activate() {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700127 store.setDelegate(delegate);
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500128 eventDispatcher.addSink(VirtualNetworkEvent.class, listenerRegistry);
Brian Stanke11f6d532016-07-05 16:17:59 -0400129 intentService.addListener(intentListener);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700130 log.info("Started");
131 }
132
133 @Deactivate
Brian Stanke11f6d532016-07-05 16:17:59 -0400134 public void deactivate() {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700135 store.unsetDelegate(delegate);
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500136 eventDispatcher.removeSink(VirtualNetworkEvent.class);
Brian Stanke11f6d532016-07-05 16:17:59 -0400137 intentService.removeListener(intentListener);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700138 log.info("Stopped");
139 }
140
141 @Override
142 public void registerTenantId(TenantId tenantId) {
143 checkNotNull(tenantId, TENANT_NULL);
144 store.addTenantId(tenantId);
145 }
146
147 @Override
148 public void unregisterTenantId(TenantId tenantId) {
149 checkNotNull(tenantId, TENANT_NULL);
150 store.removeTenantId(tenantId);
151 }
152
153 @Override
154 public Set<TenantId> getTenantIds() {
155 return store.getTenantIds();
156 }
157
158 @Override
159 public VirtualNetwork createVirtualNetwork(TenantId tenantId) {
160 checkNotNull(tenantId, TENANT_NULL);
161 return store.addNetwork(tenantId);
162 }
163
164 @Override
165 public void removeVirtualNetwork(NetworkId networkId) {
166 checkNotNull(networkId, NETWORK_NULL);
167 store.removeNetwork(networkId);
168 }
169
170 @Override
171 public VirtualDevice createVirtualDevice(NetworkId networkId, DeviceId deviceId) {
172 checkNotNull(networkId, NETWORK_NULL);
173 checkNotNull(deviceId, DEVICE_NULL);
174 return store.addDevice(networkId, deviceId);
175 }
176
177 @Override
178 public void removeVirtualDevice(NetworkId networkId, DeviceId deviceId) {
179 checkNotNull(networkId, NETWORK_NULL);
180 checkNotNull(deviceId, DEVICE_NULL);
181 store.removeDevice(networkId, deviceId);
182 }
183
184 @Override
yoonseon214963b2016-11-21 15:41:07 -0800185 public VirtualHost createVirtualHost(NetworkId networkId, HostId hostId,
186 MacAddress mac, VlanId vlan,
187 HostLocation location, Set<IpAddress> ips) {
Brian Stanke7a81b532016-06-14 15:43:51 -0400188 checkNotNull(networkId, NETWORK_NULL);
189 checkNotNull(hostId, DEVICE_NULL);
190 return store.addHost(networkId, hostId, mac, vlan, location, ips);
191 }
192
193 @Override
194 public void removeVirtualHost(NetworkId networkId, HostId hostId) {
195 checkNotNull(networkId, NETWORK_NULL);
196 checkNotNull(hostId, DEVICE_NULL);
197 store.removeHost(networkId, hostId);
198 }
199
200 @Override
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700201 public VirtualLink createVirtualLink(NetworkId networkId,
Brian Stanke9a108972016-04-11 15:25:17 -0400202 ConnectPoint src, ConnectPoint dst) {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700203 checkNotNull(networkId, NETWORK_NULL);
204 checkNotNull(src, LINK_POINT_NULL);
205 checkNotNull(dst, LINK_POINT_NULL);
Brian Stankefb61df42016-07-25 11:47:51 -0400206 ConnectPoint physicalSrc = mapVirtualToPhysicalPort(networkId, src);
207 checkNotNull(physicalSrc, LINK_POINT_NULL);
208 ConnectPoint physicalDst = mapVirtualToPhysicalPort(networkId, dst);
209 checkNotNull(physicalDst, LINK_POINT_NULL);
210
211 VirtualNetworkProvider provider = getProvider(DefaultVirtualLink.PID);
212 Link.State state = Link.State.INACTIVE;
213 if (provider != null) {
214 boolean traversable = provider.isTraversable(physicalSrc, physicalDst);
215 state = traversable ? Link.State.ACTIVE : Link.State.INACTIVE;
216 }
217 return store.addLink(networkId, src, dst, state, null);
218 }
219
220 /**
221 * Maps the virtual connect point to a physical connect point.
222 *
223 * @param networkId network identifier
224 * @param virtualCp virtual connect point
225 * @return physical connect point
226 */
227 private ConnectPoint mapVirtualToPhysicalPort(NetworkId networkId,
228 ConnectPoint virtualCp) {
229 Set<VirtualPort> ports = store.getPorts(networkId, virtualCp.deviceId());
230 for (VirtualPort port : ports) {
231 if (port.number().equals(virtualCp.port())) {
Yoonseon Han6c603892016-09-01 11:52:21 -0700232 return new ConnectPoint(port.realizedBy().deviceId(),
233 port.realizedBy().port());
Brian Stankefb61df42016-07-25 11:47:51 -0400234 }
235 }
236 return null;
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700237 }
238
Brian Stanke612cebf2016-05-02 10:21:33 -0400239 /**
240 * Maps the physical connect point to a virtual connect point.
241 *
Brian Stanke11f6d532016-07-05 16:17:59 -0400242 * @param networkId network identifier
Brian Stanke612cebf2016-05-02 10:21:33 -0400243 * @param physicalCp physical connect point
244 * @return virtual connect point
245 */
246 private ConnectPoint mapPhysicalToVirtualToPort(NetworkId networkId,
Brian Stanke11f6d532016-07-05 16:17:59 -0400247 ConnectPoint physicalCp) {
Brian Stanke612cebf2016-05-02 10:21:33 -0400248 Set<VirtualPort> ports = store.getPorts(networkId, null);
249 for (VirtualPort port : ports) {
Yoonseon Han6c603892016-09-01 11:52:21 -0700250 if (port.realizedBy().deviceId().equals(physicalCp.elementId()) &&
251 port.realizedBy().port().equals(physicalCp.port())) {
Brian Stanke612cebf2016-05-02 10:21:33 -0400252 return new ConnectPoint(port.element().id(), port.number());
253 }
254 }
255 return null;
256 }
257
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700258 @Override
yoonseon214963b2016-11-21 15:41:07 -0800259 public void removeVirtualLink(NetworkId networkId, ConnectPoint src,
260 ConnectPoint dst) {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700261 checkNotNull(networkId, NETWORK_NULL);
262 checkNotNull(src, LINK_POINT_NULL);
263 checkNotNull(dst, LINK_POINT_NULL);
Brian Stanke11f6d532016-07-05 16:17:59 -0400264 store.removeLink(networkId, src, dst);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700265 }
266
267 @Override
268 public VirtualPort createVirtualPort(NetworkId networkId, DeviceId deviceId,
Yoonseon Han6c603892016-09-01 11:52:21 -0700269 PortNumber portNumber, ConnectPoint realizedBy) {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700270 checkNotNull(networkId, NETWORK_NULL);
271 checkNotNull(deviceId, DEVICE_NULL);
272 checkNotNull(portNumber, "Port description cannot be null");
273 return store.addPort(networkId, deviceId, portNumber, realizedBy);
274 }
275
276 @Override
Yoonseon Han6c603892016-09-01 11:52:21 -0700277 public void bindVirtualPort(NetworkId networkId, DeviceId deviceId,
278 PortNumber portNumber, ConnectPoint realizedBy) {
279 checkNotNull(networkId, NETWORK_NULL);
280 checkNotNull(deviceId, DEVICE_NULL);
281 checkNotNull(portNumber, "Port description cannot be null");
282 checkNotNull(realizedBy, "Physical port description cannot be null");
283
284 store.bindPort(networkId, deviceId, portNumber, realizedBy);
285 }
286
287 @Override
yoonseon214963b2016-11-21 15:41:07 -0800288 public void removeVirtualPort(NetworkId networkId, DeviceId deviceId,
289 PortNumber portNumber) {
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700290 checkNotNull(networkId, NETWORK_NULL);
291 checkNotNull(deviceId, DEVICE_NULL);
292 checkNotNull(portNumber, "Port number cannot be null");
293 store.removePort(networkId, deviceId, portNumber);
294 }
295
296 @Override
297 public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
298 checkNotNull(tenantId, TENANT_NULL);
299 return store.getNetworks(tenantId);
300 }
301
Brian Stanke11f6d532016-07-05 16:17:59 -0400302 /**
303 * Returns the virtual network matching the network identifier.
304 *
305 * @param networkId network identifier
306 * @return virtual network
307 */
Brian Stanke86914282016-05-25 15:36:50 -0400308 private VirtualNetwork getVirtualNetwork(NetworkId networkId) {
309 checkNotNull(networkId, NETWORK_NULL);
310 return store.getNetwork(networkId);
311 }
312
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700313 @Override
314 public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
315 checkNotNull(networkId, NETWORK_NULL);
316 return store.getDevices(networkId);
317 }
318
319 @Override
Brian Stanke7a81b532016-06-14 15:43:51 -0400320 public Set<VirtualHost> getVirtualHosts(NetworkId networkId) {
321 checkNotNull(networkId, NETWORK_NULL);
322 return store.getHosts(networkId);
323 }
324
325 @Override
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700326 public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
327 checkNotNull(networkId, NETWORK_NULL);
328 return store.getLinks(networkId);
329 }
330
331 @Override
332 public Set<VirtualPort> getVirtualPorts(NetworkId networkId, DeviceId deviceId) {
333 checkNotNull(networkId, NETWORK_NULL);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700334 return store.getPorts(networkId, deviceId);
335 }
336
Brian Stanke86914282016-05-25 15:36:50 -0400337 private final Map<ServiceKey, VnetService> networkServices = Maps.newConcurrentMap();
338
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700339 @Override
340 public <T> T get(NetworkId networkId, Class<T> serviceClass) {
341 checkNotNull(networkId, NETWORK_NULL);
Brian Stanke86914282016-05-25 15:36:50 -0400342 ServiceKey serviceKey = networkServiceKey(networkId, serviceClass);
343 VnetService service = lookup(serviceKey);
344 if (service == null) {
345 service = create(serviceKey);
346 }
347 return (T) service;
348 }
349
Brian Stanke11f6d532016-07-05 16:17:59 -0400350 /**
351 * Returns the Vnet service matching the service key.
352 *
353 * @param serviceKey service key
354 * @return vnet service
355 */
Brian Stanke86914282016-05-25 15:36:50 -0400356 private VnetService lookup(ServiceKey serviceKey) {
357 return networkServices.get(serviceKey);
358 }
359
Brian Stanke11f6d532016-07-05 16:17:59 -0400360 /**
361 * Creates a new service key using the specified network identifier and service class.
362 *
363 * @param networkId network identifier
364 * @param serviceClass service class
365 * @param <T> type of service
366 * @return service key
367 */
Brian Stanke86914282016-05-25 15:36:50 -0400368 private <T> ServiceKey networkServiceKey(NetworkId networkId, Class<T> serviceClass) {
369 return new ServiceKey(networkId, serviceClass);
370 }
371
372
Brian Stanke11f6d532016-07-05 16:17:59 -0400373 /**
374 * Create a new vnet service instance.
375 *
376 * @param serviceKey service key
377 * @return vnet service
378 */
Brian Stanke86914282016-05-25 15:36:50 -0400379 private VnetService create(ServiceKey serviceKey) {
380 VirtualNetwork network = getVirtualNetwork(serviceKey.networkId());
Brian Stanke11f6d532016-07-05 16:17:59 -0400381 checkNotNull(network, NETWORK_NULL);
Brian Stanke86914282016-05-25 15:36:50 -0400382 VnetService service;
383 if (serviceKey.serviceClass.equals(DeviceService.class)) {
yoonseon214963b2016-11-21 15:41:07 -0800384 service = new VirtualNetworkDeviceManager(this, network);
Brian Stanke86914282016-05-25 15:36:50 -0400385 } else if (serviceKey.serviceClass.equals(LinkService.class)) {
yoonseon214963b2016-11-21 15:41:07 -0800386 service = new VirtualNetworkLinkManager(this, network);
Brian Stanke8e9f8d12016-06-08 14:48:33 -0400387 } else if (serviceKey.serviceClass.equals(TopologyService.class)) {
yoonseon214963b2016-11-21 15:41:07 -0800388 service = new VirtualNetworkTopologyManager(this, network);
Brian Stanke11f6d532016-07-05 16:17:59 -0400389 } else if (serviceKey.serviceClass.equals(IntentService.class)) {
yoonseon214963b2016-11-21 15:41:07 -0800390 service = new VirtualNetworkIntentManager(
391 this, network, new DefaultServiceDirectory());
Claudine Chiu30a8a2a2016-07-14 17:09:04 -0400392 } else if (serviceKey.serviceClass.equals(HostService.class)) {
yoonseon214963b2016-11-21 15:41:07 -0800393 service = new VirtualNetworkHostManager(this, network);
Claudine Chiu45920dd2016-07-28 19:19:46 +0000394 } else if (serviceKey.serviceClass.equals(PathService.class)) {
yoonseon214963b2016-11-21 15:41:07 -0800395 service = new VirtualNetworkPathManager(this, network);
Claudine Chiu70222ad2016-11-17 22:29:20 -0500396 } else if (serviceKey.serviceClass.equals(FlowRuleService.class)) {
yoonseon6b972c32016-12-06 16:45:03 -0800397 service = new VirtualNetworkFlowRuleManager(this, network,
398 new DefaultServiceDirectory());
Brian Stanke86914282016-05-25 15:36:50 -0400399 } else {
400 return null;
401 }
402 networkServices.put(serviceKey, service);
403 return service;
404 }
405
Brian Stanke11f6d532016-07-05 16:17:59 -0400406 /**
407 * Service key class.
408 */
Brian Stanke86914282016-05-25 15:36:50 -0400409 private class ServiceKey {
410 final NetworkId networkId;
411 final Class serviceClass;
412
Brian Stanke11f6d532016-07-05 16:17:59 -0400413 /**
414 * Constructor for service key.
415 *
416 * @param networkId network identifier
417 * @param serviceClass service class
418 */
Brian Stanke86914282016-05-25 15:36:50 -0400419 public ServiceKey(NetworkId networkId, Class serviceClass) {
yoonseon214963b2016-11-21 15:41:07 -0800420
Brian Stanke86914282016-05-25 15:36:50 -0400421 checkNotNull(networkId, NETWORK_NULL);
422 this.networkId = networkId;
423 this.serviceClass = serviceClass;
424 }
425
Brian Stanke11f6d532016-07-05 16:17:59 -0400426 /**
427 * Returns the network identifier.
428 *
429 * @return network identifier
430 */
Brian Stanke86914282016-05-25 15:36:50 -0400431 public NetworkId networkId() {
432 return networkId;
433 }
434
Brian Stanke11f6d532016-07-05 16:17:59 -0400435 /**
436 * Returns the service class.
437 *
438 * @return service class
439 */
Brian Stanke86914282016-05-25 15:36:50 -0400440 public Class serviceClass() {
441 return serviceClass;
442 }
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700443 }
444
Brian Stanke11f6d532016-07-05 16:17:59 -0400445 /**
446 * Internal intent event listener.
447 */
448 private class InternalVirtualIntentListener implements IntentListener {
yoonseon214963b2016-11-21 15:41:07 -0800449
Brian Stanke11f6d532016-07-05 16:17:59 -0400450 @Override
451 public void event(IntentEvent event) {
452
453 // Ignore intent events that are not relevant.
454 if (!isRelevant(event)) {
455 return;
456 }
457
458 VirtualNetworkIntent intent = (VirtualNetworkIntent) event.subject();
459
460 switch (event.type()) {
461 case INSTALL_REQ:
462 store.addOrUpdateIntent(intent, IntentState.INSTALL_REQ);
463 break;
464 case INSTALLED:
465 store.addOrUpdateIntent(intent, IntentState.INSTALLED);
466 break;
467 case WITHDRAW_REQ:
468 store.addOrUpdateIntent(intent, IntentState.WITHDRAW_REQ);
469 break;
470 case WITHDRAWN:
471 store.addOrUpdateIntent(intent, IntentState.WITHDRAWN);
472 break;
473 case FAILED:
474 store.addOrUpdateIntent(intent, IntentState.FAILED);
475 break;
476 case CORRUPT:
477 store.addOrUpdateIntent(intent, IntentState.CORRUPT);
478 break;
479 case PURGED:
480 store.removeIntent(intent.key());
481 default:
482 break;
483 }
484 }
485
486 @Override
487 public boolean isRelevant(IntentEvent event) {
488 if (event.subject() instanceof VirtualNetworkIntent) {
489 return true;
490 }
491 return false;
492 }
493 }
494
495
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700496 @Override
yoonseon214963b2016-11-21 15:41:07 -0800497 protected VirtualNetworkProviderService
498 createProviderService(VirtualNetworkProvider provider) {
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700499 return new InternalVirtualNetworkProviderService(provider);
500 }
501
yoonseon6b972c32016-12-06 16:45:03 -0800502
Brian Stankefb61df42016-07-25 11:47:51 -0400503 /**
504 * Service issued to registered virtual network providers so that they
505 * can interact with the core.
506 */
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700507 private class InternalVirtualNetworkProviderService
508 extends AbstractProviderService<VirtualNetworkProvider>
509 implements VirtualNetworkProviderService {
Brian Stankefb61df42016-07-25 11:47:51 -0400510 /**
511 * Constructor.
512 * @param provider virtual network provider
513 */
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700514 InternalVirtualNetworkProviderService(VirtualNetworkProvider provider) {
515 super(provider);
516 }
Brian Stanke4d579882016-04-22 13:28:46 -0400517
518 @Override
Brian Stankefb61df42016-07-25 11:47:51 -0400519 public void topologyChanged(Set<Set<ConnectPoint>> clusters) {
Brian Stankefb61df42016-07-25 11:47:51 -0400520 Set<TenantId> tenantIds = getTenantIds();
521 tenantIds.forEach(tenantId -> {
522 Set<VirtualNetwork> virtualNetworks = getVirtualNetworks(tenantId);
523
524 virtualNetworks.forEach(virtualNetwork -> {
525 Set<VirtualLink> virtualLinks = getVirtualLinks(virtualNetwork.id());
526
527 virtualLinks.forEach(virtualLink -> {
yoonseon214963b2016-11-21 15:41:07 -0800528 if (isVirtualLinkInCluster(virtualNetwork.id(),
529 virtualLink, clusters)) {
530 store.updateLink(virtualLink, virtualLink.tunnelId(),
531 Link.State.ACTIVE);
Brian Stankefb61df42016-07-25 11:47:51 -0400532 } else {
yoonseon214963b2016-11-21 15:41:07 -0800533 store.updateLink(virtualLink, virtualLink.tunnelId(),
534 Link.State.INACTIVE);
Brian Stankefb61df42016-07-25 11:47:51 -0400535 }
536 });
537 });
538 });
539 }
540
541 /**
yoonseon214963b2016-11-21 15:41:07 -0800542 * Determines if the virtual link (both source and destination connect point)
543 * is in a cluster.
Brian Stankefb61df42016-07-25 11:47:51 -0400544 *
545 * @param networkId virtual network identifier
546 * @param virtualLink virtual link
547 * @param clusters topology clusters
548 * @return true if the virtual link is in a cluster.
549 */
550 private boolean isVirtualLinkInCluster(NetworkId networkId, VirtualLink virtualLink,
551 Set<Set<ConnectPoint>> clusters) {
yoonseon214963b2016-11-21 15:41:07 -0800552 ConnectPoint srcPhysicalCp =
553 mapVirtualToPhysicalPort(networkId, virtualLink.src());
554 ConnectPoint dstPhysicalCp =
555 mapVirtualToPhysicalPort(networkId, virtualLink.dst());
Brian Stankefb61df42016-07-25 11:47:51 -0400556
557 final boolean[] foundSrc = {false};
558 final boolean[] foundDst = {false};
559 clusters.forEach(connectPoints -> {
560 connectPoints.forEach(connectPoint -> {
561 if (connectPoint.equals(srcPhysicalCp)) {
562 foundSrc[0] = true;
563 } else if (connectPoint.equals(dstPhysicalCp)) {
564 foundDst[0] = true;
565 }
566 });
567 if (foundSrc[0] && foundDst[0]) {
568 return;
569 }
570 });
571 return foundSrc[0] && foundDst[0];
572 }
573
574 @Override
yoonseon214963b2016-11-21 15:41:07 -0800575 public void tunnelUp(NetworkId networkId, ConnectPoint src,
576 ConnectPoint dst, TunnelId tunnelId) {
Brian Stanke612cebf2016-05-02 10:21:33 -0400577 ConnectPoint srcVirtualCp = mapPhysicalToVirtualToPort(networkId, src);
578 ConnectPoint dstVirtualCp = mapPhysicalToVirtualToPort(networkId, dst);
579 if ((srcVirtualCp == null) || (dstVirtualCp == null)) {
580 log.error("Src or dst virtual connection point was not found.");
581 }
582
583 VirtualLink virtualLink = store.getLink(networkId, srcVirtualCp, dstVirtualCp);
584 if (virtualLink != null) {
585 store.updateLink(virtualLink, tunnelId, Link.State.ACTIVE);
586 }
Brian Stanke4d579882016-04-22 13:28:46 -0400587 }
588
589 @Override
yoonseon214963b2016-11-21 15:41:07 -0800590 public void tunnelDown(NetworkId networkId, ConnectPoint src,
591 ConnectPoint dst, TunnelId tunnelId) {
Brian Stanke612cebf2016-05-02 10:21:33 -0400592 ConnectPoint srcVirtualCp = mapPhysicalToVirtualToPort(networkId, src);
593 ConnectPoint dstVirtualCp = mapPhysicalToVirtualToPort(networkId, dst);
594 if ((srcVirtualCp == null) || (dstVirtualCp == null)) {
595 log.error("Src or dst virtual connection point was not found.");
596 }
Brian Stanke4d579882016-04-22 13:28:46 -0400597
Brian Stanke612cebf2016-05-02 10:21:33 -0400598 VirtualLink virtualLink = store.getLink(networkId, srcVirtualCp, dstVirtualCp);
599 if (virtualLink != null) {
600 store.updateLink(virtualLink, tunnelId, Link.State.INACTIVE);
601 }
Brian Stanke4d579882016-04-22 13:28:46 -0400602 }
Thomas Vachuska3d62fd72015-09-25 14:58:13 -0700603 }
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700604}