blob: ca0c311cee3fd3a782258f93a2acf7a29221724b [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.store.virtual.impl;
17
Brian Stanke0e5c94e2016-03-08 11:20:04 -050018import com.google.common.collect.ImmutableSet;
19import com.google.common.collect.Sets;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070020import org.apache.felix.scr.annotations.Activate;
21import org.apache.felix.scr.annotations.Component;
22import org.apache.felix.scr.annotations.Deactivate;
Brian Stanke0e5c94e2016-03-08 11:20:04 -050023import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070025import org.apache.felix.scr.annotations.Service;
Brian Stanke0e5c94e2016-03-08 11:20:04 -050026import org.onlab.util.KryoNamespace;
27import org.onosproject.core.CoreService;
28import org.onosproject.core.IdGenerator;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070029import org.onosproject.incubator.net.tunnel.TunnelId;
30import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
Brian Stanke0e5c94e2016-03-08 11:20:04 -050031import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070032import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
Brian Stanke0e5c94e2016-03-08 11:20:04 -050033import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070034import org.onosproject.incubator.net.virtual.NetworkId;
35import org.onosproject.incubator.net.virtual.TenantId;
36import org.onosproject.incubator.net.virtual.VirtualDevice;
37import org.onosproject.incubator.net.virtual.VirtualLink;
38import org.onosproject.incubator.net.virtual.VirtualNetwork;
39import org.onosproject.incubator.net.virtual.VirtualNetworkEvent;
Brian Stanke0e5c94e2016-03-08 11:20:04 -050040import org.onosproject.incubator.net.virtual.VirtualNetworkService;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070041import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
42import org.onosproject.incubator.net.virtual.VirtualNetworkStoreDelegate;
43import org.onosproject.incubator.net.virtual.VirtualPort;
44import org.onosproject.net.ConnectPoint;
Brian Stanke5df14472016-03-11 19:34:38 -050045import org.onosproject.net.DefaultDevice;
46import org.onosproject.net.DefaultPort;
Brian Stanke0e5c94e2016-03-08 11:20:04 -050047import org.onosproject.net.Device;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070048import org.onosproject.net.DeviceId;
49import org.onosproject.net.Port;
50import org.onosproject.net.PortNumber;
51import org.onosproject.store.AbstractStore;
Brian Stanke0e5c94e2016-03-08 11:20:04 -050052import org.onosproject.store.serializers.KryoNamespaces;
53import org.onosproject.store.service.ConsistentMap;
54import org.onosproject.store.service.DistributedSet;
55import org.onosproject.store.service.MapEvent;
56import org.onosproject.store.service.MapEventListener;
57import org.onosproject.store.service.Serializer;
58import org.onosproject.store.service.SetEvent;
59import org.onosproject.store.service.SetEventListener;
60import org.onosproject.store.service.StorageService;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070061import org.slf4j.Logger;
62
Brian Stanke0e5c94e2016-03-08 11:20:04 -050063import java.util.HashSet;
64import java.util.Map;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070065import java.util.Set;
66
Brian Stanke0e5c94e2016-03-08 11:20:04 -050067import static com.google.common.base.Preconditions.checkNotNull;
68import static com.google.common.base.Preconditions.checkState;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070069import static org.slf4j.LoggerFactory.getLogger;
70
71/**
Brian Stanke0e5c94e2016-03-08 11:20:04 -050072 * Implementation of the virtual network store.
Thomas Vachuska33979fd2015-07-31 11:41:14 -070073 */
74@Component(immediate = true)
75@Service
76public class DistributedVirtualNetworkStore
77 extends AbstractStore<VirtualNetworkEvent, VirtualNetworkStoreDelegate>
78 implements VirtualNetworkStore {
79
80 private final Logger log = getLogger(getClass());
81
Brian Stanke0e5c94e2016-03-08 11:20:04 -050082 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
83 protected StorageService storageService;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070084
Brian Stanke0e5c94e2016-03-08 11:20:04 -050085 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
86 protected CoreService coreService;
Thomas Vachuska33979fd2015-07-31 11:41:14 -070087
Brian Stanke0e5c94e2016-03-08 11:20:04 -050088 private IdGenerator idGenerator;
89
90 // Track tenants by ID
91 private DistributedSet<TenantId> tenantIdSet;
92
93 // Listener for tenant events
94 private final SetEventListener<TenantId> setListener = new InternalSetListener();
95
96 // Track virtual networks by network Id
97 private ConsistentMap<NetworkId, VirtualNetwork> networkIdVirtualNetworkConsistentMap;
98 private Map<NetworkId, VirtualNetwork> networkIdVirtualNetworkMap;
99
100 // Listener for virtual network events
101 private final MapEventListener<NetworkId, VirtualNetwork> virtualMapListener = new InternalMapListener();
102
103 // Track virtual network IDs by tenant Id
104 private ConsistentMap<TenantId, Set<NetworkId>> tenantIdNetworkIdSetConsistentMap;
105 private Map<TenantId, Set<NetworkId>> tenantIdNetworkIdSetMap;
106
107 // Track virtual devices by device Id
108 private ConsistentMap<DeviceId, VirtualDevice> deviceIdVirtualDeviceConsistentMap;
109 private Map<DeviceId, VirtualDevice> deviceIdVirtualDeviceMap;
110
111 // Track device IDs by network Id
112 private ConsistentMap<NetworkId, Set<DeviceId>> networkIdDeviceIdSetConsistentMap;
113 private Map<NetworkId, Set<DeviceId>> networkIdDeviceIdSetMap;
114
115 // Track virtual links by network Id
116 private ConsistentMap<NetworkId, Set<VirtualLink>> networkIdVirtualLinkSetConsistentMap;
117 private Map<NetworkId, Set<VirtualLink>> networkIdVirtualLinkSetMap;
118
119 // Track virtual ports by network Id
120 private ConsistentMap<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetConsistentMap;
121 private Map<NetworkId, Set<VirtualPort>> networkIdVirtualPortSetMap;
122
123 private static final Serializer SERIALIZER = Serializer
124 .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
125 .register(TenantId.class)
126 .register(NetworkId.class).register(DeviceId.class)
127 .register(VirtualNetwork.class)
Brian Stanke5df14472016-03-11 19:34:38 -0500128 .register(DefaultVirtualNetwork.class)
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500129 .register(VirtualDevice.class)
Brian Stanke5df14472016-03-11 19:34:38 -0500130 .register(DefaultVirtualDevice.class)
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500131 .register(VirtualLink.class)
Brian Stanke5df14472016-03-11 19:34:38 -0500132 .register(DefaultVirtualLink.class)
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500133 .register(VirtualPort.class)
Brian Stanke5df14472016-03-11 19:34:38 -0500134 .register(DefaultVirtualPort.class)
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500135 .register(DeviceId.class)
136 .register(Device.class)
Brian Stanke5df14472016-03-11 19:34:38 -0500137 .register(TunnelId.class)
138 .register(DefaultDevice.class)
139 .register(DefaultPort.class)
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500140 .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID).build());
141
142 /**
143 * Distributed network store service activate method.
144 */
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700145 @Activate
146 public void activate() {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500147 idGenerator = coreService.getIdGenerator(VirtualNetworkService.VIRTUAL_NETWORK_TOPIC);
148
149 tenantIdSet = storageService.<TenantId>setBuilder()
150 .withSerializer(SERIALIZER)
151 .withName("onos-tenantId")
152 .withRelaxedReadConsistency()
153 .build()
154 .asDistributedSet();
155 tenantIdSet.addListener(setListener);
156
157 networkIdVirtualNetworkConsistentMap = storageService.<NetworkId, VirtualNetwork>consistentMapBuilder()
158 .withSerializer(SERIALIZER)
159 .withName("onos-networkId-virtualnetwork")
160 .withRelaxedReadConsistency()
161 .build();
162 networkIdVirtualNetworkConsistentMap.addListener(virtualMapListener);
163 networkIdVirtualNetworkMap = networkIdVirtualNetworkConsistentMap.asJavaMap();
164
165 tenantIdNetworkIdSetConsistentMap = storageService.<TenantId, Set<NetworkId>>consistentMapBuilder()
166 .withSerializer(SERIALIZER)
167 .withName("onos-tenantId-networkIds")
168 .withRelaxedReadConsistency()
169 .build();
170 tenantIdNetworkIdSetMap = tenantIdNetworkIdSetConsistentMap.asJavaMap();
171
172 deviceIdVirtualDeviceConsistentMap = storageService.<DeviceId, VirtualDevice>consistentMapBuilder()
173 .withSerializer(SERIALIZER)
174 .withName("onos-deviceId-virtualdevice")
175 .withRelaxedReadConsistency()
176 .build();
177 deviceIdVirtualDeviceMap = deviceIdVirtualDeviceConsistentMap.asJavaMap();
178
179 networkIdDeviceIdSetConsistentMap = storageService.<NetworkId, Set<DeviceId>>consistentMapBuilder()
180 .withSerializer(SERIALIZER)
181 .withName("onos-networkId-deviceIds")
182 .withRelaxedReadConsistency()
183 .build();
184 networkIdDeviceIdSetMap = networkIdDeviceIdSetConsistentMap.asJavaMap();
185
186 networkIdVirtualLinkSetConsistentMap = storageService.<NetworkId, Set<VirtualLink>>consistentMapBuilder()
187 .withSerializer(SERIALIZER)
188 .withName("onos-networkId-virtuallinks")
189 .withRelaxedReadConsistency()
190 .build();
191 networkIdVirtualLinkSetMap = networkIdVirtualLinkSetConsistentMap.asJavaMap();
192
193 networkIdVirtualPortSetConsistentMap = storageService.<NetworkId, Set<VirtualPort>>consistentMapBuilder()
194 .withSerializer(SERIALIZER)
195 .withName("onos-networkId-virtualportss")
196 .withRelaxedReadConsistency()
197 .build();
198 networkIdVirtualPortSetMap = networkIdVirtualPortSetConsistentMap.asJavaMap();
199
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700200 log.info("Started");
201 }
202
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500203 /**
204 * Distributed network store service deactivate method.
205 */
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700206 @Deactivate
207 public void deactivate() {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500208 tenantIdSet.removeListener(setListener);
209 networkIdVirtualNetworkConsistentMap.removeListener(virtualMapListener);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700210 log.info("Stopped");
211 }
212
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500213 /**
214 * This method is used for Junit tests to set the CoreService instance, which
215 * is required to set the IdGenerator instance.
216 *
217 * @param coreService core service instance
218 */
219 public void setCoreService(CoreService coreService) {
220 this.coreService = coreService;
221 }
222
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700223 @Override
224 public void addTenantId(TenantId tenantId) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500225 tenantIdSet.add(tenantId);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700226 }
227
228 @Override
229 public void removeTenantId(TenantId tenantId) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500230 tenantIdSet.remove(tenantId);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700231 }
232
233 @Override
234 public Set<TenantId> getTenantIds() {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500235 return ImmutableSet.copyOf(tenantIdSet);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700236 }
237
238 @Override
239 public VirtualNetwork addNetwork(TenantId tenantId) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500240
241 checkState(tenantIdSet.contains(tenantId), "The tenant has not been registered. " + tenantId.id());
242 VirtualNetwork virtualNetwork = new DefaultVirtualNetwork(genNetworkId(), tenantId);
243 //TODO update both maps in one transaction.
244 networkIdVirtualNetworkMap.put(virtualNetwork.id(), virtualNetwork);
Brian Stanke5df14472016-03-11 19:34:38 -0500245
246 Set<NetworkId> networkIdSet = tenantIdNetworkIdSetMap.get(tenantId);
247 if (networkIdSet == null) {
248 networkIdSet = new HashSet<>();
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500249 }
Brian Stanke5df14472016-03-11 19:34:38 -0500250 networkIdSet.add(virtualNetwork.id());
251 tenantIdNetworkIdSetMap.put(tenantId, networkIdSet);
252
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500253 return virtualNetwork;
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700254 }
255
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500256 /**
257 * Returns a new network identifier from a virtual network block of identifiers.
258 *
259 * @return NetworkId network identifier
260 */
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700261 private NetworkId genNetworkId() {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500262 return NetworkId.networkId(idGenerator.getNewId());
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700263 }
264
265
266 @Override
267 public void removeNetwork(NetworkId networkId) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500268 // Make sure that the virtual network exists before attempting to remove it.
269 if (networkExists(networkId)) {
Brian Stanke5df14472016-03-11 19:34:38 -0500270 //TODO update both maps in one transaction.
271
272 VirtualNetwork virtualNetwork = networkIdVirtualNetworkMap.remove(networkId);
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500273 if (virtualNetwork == null) {
274 return;
275 }
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500276 TenantId tenantId = virtualNetwork.tenantId();
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500277
Brian Stanke5df14472016-03-11 19:34:38 -0500278 Set<NetworkId> networkIdSet = new HashSet<>();
279 tenantIdNetworkIdSetMap.get(tenantId).forEach(networkId1 -> {
280 if (networkId1.id().equals(networkId.id())) {
281 networkIdSet.add(networkId1);
282 }
283 });
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500284
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500285 tenantIdNetworkIdSetMap.compute(virtualNetwork.tenantId(), (id, existingNetworkIds) -> {
286 if (existingNetworkIds == null || existingNetworkIds.isEmpty()) {
Brian Stanke5df14472016-03-11 19:34:38 -0500287 return new HashSet<NetworkId>();
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500288 } else {
Brian Stanke5df14472016-03-11 19:34:38 -0500289 return new HashSet<NetworkId>(Sets.difference(existingNetworkIds, networkIdSet));
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500290 }
291 });
292 }
293 }
294
295 /**
296 * Returns if the network identifier exists.
297 *
298 * @param networkId network identifier
299 * @return true if the network identifier exists, false otherwise.
300 */
301 private boolean networkExists(NetworkId networkId) {
302 return (networkIdVirtualNetworkMap.containsKey(networkId));
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700303 }
304
305 @Override
306 public VirtualDevice addDevice(NetworkId networkId, DeviceId deviceId) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500307 checkState(networkExists(networkId), "The network has not been added.");
308 Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
309 if (deviceIdSet == null) {
310 deviceIdSet = new HashSet<>();
311 }
312 VirtualDevice virtualDevice = new DefaultVirtualDevice(networkId, deviceId);
313 //TODO update both maps in one transaction.
314 deviceIdVirtualDeviceMap.put(deviceId, virtualDevice);
315 deviceIdSet.add(deviceId);
316 networkIdDeviceIdSetMap.put(networkId, deviceIdSet);
317 return virtualDevice;
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700318 }
319
320 @Override
321 public void removeDevice(NetworkId networkId, DeviceId deviceId) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500322 checkState(networkExists(networkId), "The network has not been added.");
323 //TODO update both maps in one transaction.
Brian Stanke5df14472016-03-11 19:34:38 -0500324
325 Set<DeviceId> deviceIdSet = new HashSet<>();
326 networkIdDeviceIdSetMap.get(networkId).forEach(deviceId1 -> {
327 if (deviceId1.equals(deviceId)) {
328 deviceIdSet.add(deviceId1);
329 }
330 });
331
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500332 if (deviceIdSet != null) {
333 networkIdDeviceIdSetMap.compute(networkId, (id, existingDeviceIds) -> {
334 if (existingDeviceIds == null || existingDeviceIds.isEmpty()) {
Brian Stanke5df14472016-03-11 19:34:38 -0500335 return new HashSet<DeviceId>();
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500336 } else {
Brian Stanke5df14472016-03-11 19:34:38 -0500337 return new HashSet<DeviceId>(Sets.difference(existingDeviceIds, deviceIdSet));
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500338 }
339 });
340
Brian Stanke5df14472016-03-11 19:34:38 -0500341 deviceIdVirtualDeviceMap.remove(deviceId);
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500342 }
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700343 }
344
345 @Override
346 public VirtualLink addLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst, TunnelId realizedBy) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500347 checkState(networkExists(networkId), "The network has not been added.");
348 Set<VirtualLink> virtualLinkSet = networkIdVirtualLinkSetMap.get(networkId);
349 if (virtualLinkSet == null) {
350 virtualLinkSet = new HashSet<>();
351 }
352 VirtualLink virtualLink = new DefaultVirtualLink(networkId, src, dst, realizedBy);
353 virtualLinkSet.add(virtualLink);
354 networkIdVirtualLinkSetMap.put(networkId, virtualLinkSet);
355 return virtualLink;
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700356 }
357
358 @Override
359 public void removeLink(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500360 checkState(networkExists(networkId), "The network has not been added.");
Brian Stanke5df14472016-03-11 19:34:38 -0500361
362 Set<VirtualLink> virtualLinkSet = new HashSet<>();
363 networkIdVirtualLinkSetMap.get(networkId).forEach(link -> {
364 if (link.src().equals(src) && link.dst().equals(dst)) {
365 virtualLinkSet.add(link);
366 }
367 });
368
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500369 if (virtualLinkSet != null) {
370 networkIdVirtualLinkSetMap.compute(networkId, (id, existingVirtualLinks) -> {
371 if (existingVirtualLinks == null || existingVirtualLinks.isEmpty()) {
Brian Stanke5df14472016-03-11 19:34:38 -0500372 return new HashSet<VirtualLink>();
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500373 } else {
Brian Stanke5df14472016-03-11 19:34:38 -0500374 return new HashSet<VirtualLink>(Sets.difference(existingVirtualLinks, virtualLinkSet));
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500375 }
376 });
377 }
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700378 }
379
380 @Override
381 public VirtualPort addPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber, Port realizedBy) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500382 checkState(networkExists(networkId), "The network has not been added.");
383 Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap.get(networkId);
384 if (virtualPortSet == null) {
385 virtualPortSet = new HashSet<>();
386 }
387 Device device = deviceIdVirtualDeviceMap.get(deviceId);
388 checkNotNull(device, "The device has not been created for deviceId: " + deviceId);
389 VirtualPort virtualPort = new DefaultVirtualPort(networkId, device, portNumber, realizedBy);
390 virtualPortSet.add(virtualPort);
391 networkIdVirtualPortSetMap.put(networkId, virtualPortSet);
392 return virtualPort;
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700393 }
394
395 @Override
396 public void removePort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500397 checkState(networkExists(networkId), "The network has not been added.");
Brian Stanke5df14472016-03-11 19:34:38 -0500398
399 Set<VirtualPort> virtualPortSet = new HashSet<>();
400 networkIdVirtualPortSetMap.get(networkId).forEach(port -> {
401 if (port.element().id().equals(deviceId) && port.number().equals(portNumber)) {
402 virtualPortSet.add(port);
403 }
404 });
405
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500406 if (virtualPortSet != null) {
407 networkIdVirtualPortSetMap.compute(networkId, (id, existingVirtualPorts) -> {
408 if (existingVirtualPorts == null || existingVirtualPorts.isEmpty()) {
Brian Stanke5df14472016-03-11 19:34:38 -0500409 return new HashSet<VirtualPort>();
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500410 } else {
Brian Stanke5df14472016-03-11 19:34:38 -0500411 return new HashSet<VirtualPort>(Sets.difference(existingVirtualPorts, virtualPortSet));
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500412 }
413 });
414 }
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700415 }
416
417 @Override
418 public Set<VirtualNetwork> getNetworks(TenantId tenantId) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500419 Set<NetworkId> networkIdSet = tenantIdNetworkIdSetMap.get(tenantId);
420 Set<VirtualNetwork> virtualNetworkSet = new HashSet<>();
421 if (networkIdSet != null) {
422 networkIdSet.forEach(networkId -> virtualNetworkSet.add(networkIdVirtualNetworkMap.get(networkId)));
423 }
424 return ImmutableSet.copyOf(virtualNetworkSet);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700425 }
426
427 @Override
428 public Set<VirtualDevice> getDevices(NetworkId networkId) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500429 checkState(networkExists(networkId), "The network has not been added.");
430 Set<DeviceId> deviceIdSet = networkIdDeviceIdSetMap.get(networkId);
431 Set<VirtualDevice> virtualDeviceSet = new HashSet<>();
432 if (deviceIdSet != null) {
433 deviceIdSet.forEach(deviceId -> virtualDeviceSet.add(deviceIdVirtualDeviceMap.get(deviceId)));
434 }
435 return ImmutableSet.copyOf(virtualDeviceSet);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700436 }
437
438 @Override
439 public Set<VirtualLink> getLinks(NetworkId networkId) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500440 checkState(networkExists(networkId), "The network has not been added.");
Brian Stanke5df14472016-03-11 19:34:38 -0500441 Set<VirtualLink> virtualLinkSet = networkIdVirtualLinkSetMap.get(networkId);
442 if (virtualLinkSet == null) {
443 virtualLinkSet = new HashSet<>();
444 }
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500445 return ImmutableSet.copyOf(virtualLinkSet);
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700446 }
447
448 @Override
449 public Set<VirtualPort> getPorts(NetworkId networkId, DeviceId deviceId) {
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500450 checkState(networkExists(networkId), "The network has not been added.");
Brian Stanke5df14472016-03-11 19:34:38 -0500451 Set<VirtualPort> virtualPortSet = networkIdVirtualPortSetMap.get(networkId);
452 if (virtualPortSet == null) {
453 virtualPortSet = new HashSet<>();
454 }
455
456 Set<VirtualPort> portSet = new HashSet<>();
457 virtualPortSet.forEach(virtualPort -> {
458 if (virtualPort.element().id().equals(deviceId)) {
459 portSet.add(virtualPort);
460 }
461 });
462 return ImmutableSet.copyOf(portSet);
Brian Stanke0e5c94e2016-03-08 11:20:04 -0500463 }
464
465 /**
466 * Listener class to map listener set events to the virtual network events.
467 */
468 private class InternalSetListener implements SetEventListener<TenantId> {
469 @Override
470 public void event(SetEvent<TenantId> event) {
471 VirtualNetworkEvent.Type type = null;
472 switch (event.type()) {
473 case ADD:
474 type = VirtualNetworkEvent.Type.TENANT_REGISTERED;
475 break;
476 case REMOVE:
477 type = VirtualNetworkEvent.Type.TENANT_UNREGISTERED;
478 break;
479 default:
480 log.error("Unsupported event type: " + event.type());
481 }
482 notifyDelegate(new VirtualNetworkEvent(type, null));
483 }
484 }
485
486 /**
487 * Listener class to map listener map events to the virtual network events.
488 */
489 private class InternalMapListener implements MapEventListener<NetworkId, VirtualNetwork> {
490 @Override
491 public void event(MapEvent<NetworkId, VirtualNetwork> event) {
492 NetworkId networkId = checkNotNull(event.key());
493 VirtualNetworkEvent.Type type = null;
494 switch (event.type()) {
495 case INSERT:
496 type = VirtualNetworkEvent.Type.NETWORK_ADDED;
497 break;
498 case UPDATE:
499 if ((event.oldValue().value() != null) && (event.newValue().value() == null)) {
500 type = VirtualNetworkEvent.Type.NETWORK_REMOVED;
501 } else {
502 type = VirtualNetworkEvent.Type.NETWORK_UPDATED;
503 }
504 break;
505 case REMOVE:
506 type = VirtualNetworkEvent.Type.NETWORK_REMOVED;
507 break;
508 default:
509 log.error("Unsupported event type: " + event.type());
510 }
511 notifyDelegate(new VirtualNetworkEvent(type, networkId));
512 }
Thomas Vachuska33979fd2015-07-31 11:41:14 -0700513 }
514}