blob: 417881c85f840d482faf92f2072e94c921ef762e [file] [log] [blame]
jiangruif675cd42015-11-27 15:03:59 +08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.vtnrsc.service.impl;
17
18import static com.google.common.base.Preconditions.checkNotNull;
19import static org.slf4j.LoggerFactory.getLogger;
20
21import java.util.HashSet;
22import java.util.Iterator;
23import java.util.Set;
24
25import org.apache.felix.scr.annotations.Activate;
26import org.apache.felix.scr.annotations.Component;
27import org.apache.felix.scr.annotations.Deactivate;
28import org.apache.felix.scr.annotations.Reference;
29import org.apache.felix.scr.annotations.ReferenceCardinality;
30import org.apache.felix.scr.annotations.Service;
31import org.onlab.packet.IpAddress;
32import org.onlab.packet.MacAddress;
33import org.onlab.util.KryoNamespace;
34import org.onosproject.core.CoreService;
Mahesh Poojary Scc11f722015-11-29 16:09:56 +053035import org.onosproject.event.AbstractListenerManager;
jiangruif675cd42015-11-27 15:03:59 +080036import org.onosproject.net.Device;
37import org.onosproject.net.DeviceId;
38import org.onosproject.net.Host;
39import org.onosproject.net.HostId;
jiangruif675cd42015-11-27 15:03:59 +080040import org.onosproject.net.device.DeviceService;
lishuaib43dbf72016-01-06 11:11:35 +080041import org.onosproject.net.host.HostService;
jiangruif675cd42015-11-27 15:03:59 +080042import org.onosproject.store.serializers.KryoNamespaces;
43import org.onosproject.store.service.EventuallyConsistentMap;
44import org.onosproject.store.service.LogicalClockService;
45import org.onosproject.store.service.StorageService;
46import org.onosproject.vtnrsc.FixedIp;
47import org.onosproject.vtnrsc.FloatingIp;
lishuaib43dbf72016-01-06 11:11:35 +080048import org.onosproject.vtnrsc.FlowClassifier;
49import org.onosproject.vtnrsc.PortChain;
50import org.onosproject.vtnrsc.PortPair;
51import org.onosproject.vtnrsc.PortPairGroup;
52import org.onosproject.vtnrsc.PortPairId;
jiangruif675cd42015-11-27 15:03:59 +080053import org.onosproject.vtnrsc.Router;
54import org.onosproject.vtnrsc.RouterInterface;
55import org.onosproject.vtnrsc.SegmentationId;
56import org.onosproject.vtnrsc.Subnet;
57import org.onosproject.vtnrsc.SubnetId;
58import org.onosproject.vtnrsc.TenantId;
59import org.onosproject.vtnrsc.VirtualPort;
60import org.onosproject.vtnrsc.VirtualPortId;
61import org.onosproject.vtnrsc.event.VtnRscEvent;
62import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
63import org.onosproject.vtnrsc.event.VtnRscListener;
64import org.onosproject.vtnrsc.floatingip.FloatingIpEvent;
65import org.onosproject.vtnrsc.floatingip.FloatingIpListener;
66import org.onosproject.vtnrsc.floatingip.FloatingIpService;
lishuaib43dbf72016-01-06 11:11:35 +080067import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent;
68import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener;
69import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
70import org.onosproject.vtnrsc.portchain.PortChainEvent;
71import org.onosproject.vtnrsc.portchain.PortChainListener;
72import org.onosproject.vtnrsc.portchain.PortChainService;
73import org.onosproject.vtnrsc.portpair.PortPairEvent;
74import org.onosproject.vtnrsc.portpair.PortPairListener;
75import org.onosproject.vtnrsc.portpair.PortPairService;
76import org.onosproject.vtnrsc.portpairgroup.PortPairGroupEvent;
77import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener;
78import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService;
jiangruif675cd42015-11-27 15:03:59 +080079import org.onosproject.vtnrsc.router.RouterEvent;
80import org.onosproject.vtnrsc.router.RouterListener;
81import org.onosproject.vtnrsc.router.RouterService;
82import org.onosproject.vtnrsc.routerinterface.RouterInterfaceEvent;
83import org.onosproject.vtnrsc.routerinterface.RouterInterfaceListener;
84import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService;
85import org.onosproject.vtnrsc.service.VtnRscService;
86import org.onosproject.vtnrsc.subnet.SubnetService;
87import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
88import org.onosproject.vtnrsc.virtualport.VirtualPortService;
89import org.slf4j.Logger;
90
jiangruif675cd42015-11-27 15:03:59 +080091/**
92 * Provides implementation of the VtnRsc service.
93 */
94@Component(immediate = true)
95@Service
Mahesh Poojary Scc11f722015-11-29 16:09:56 +053096public class VtnRscManager extends AbstractListenerManager<VtnRscEvent, VtnRscListener>
97 implements VtnRscService {
jiangruif675cd42015-11-27 15:03:59 +080098 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
99 protected CoreService coreService;
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected StorageService storageService;
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 protected LogicalClockService clockService;
104
105 private final Logger log = getLogger(getClass());
jiangruif675cd42015-11-27 15:03:59 +0800106 private FloatingIpListener floatingIpListener = new InnerFloatingIpListener();
107 private RouterListener routerListener = new InnerRouterListener();
108 private RouterInterfaceListener routerInterfaceListener = new InnerRouterInterfaceListener();
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530109 private PortPairListener portPairListener = new InnerPortPairListener();
110 private PortPairGroupListener portPairGroupListener = new InnerPortPairGroupListener();
111 private FlowClassifierListener flowClassifierListener = new InnerFlowClassifierListener();
112 private PortChainListener portChainListener = new InnerPortChainListener();
jiangruif675cd42015-11-27 15:03:59 +0800113
114 private EventuallyConsistentMap<TenantId, SegmentationId> l3vniMap;
115 private EventuallyConsistentMap<TenantId, Set<DeviceId>> classifierOvsMap;
116 private EventuallyConsistentMap<TenantId, Set<DeviceId>> sffOvsMap;
117
118 private static final String IFACEID = "ifaceid";
119 private static final String RUNNELOPTOPOIC = "tunnel-ops-ids";
jiangruif675cd42015-11-27 15:03:59 +0800120 private static final String EVENT_NOT_NULL = "event cannot be null";
121 private static final String TENANTID_NOT_NULL = "tenantId cannot be null";
122 private static final String DEVICEID_NOT_NULL = "deviceId cannot be null";
lishuaib43dbf72016-01-06 11:11:35 +0800123 private static final String VIRTUALPORTID_NOT_NULL = "virtualPortId cannot be null";
124 private static final String HOST_NOT_NULL = "host cannot be null";
jiangruif675cd42015-11-27 15:03:59 +0800125 private static final String L3VNIMAP = "l3vniMap";
126 private static final String CLASSIFIEROVSMAP = "classifierOvsMap";
127 private static final String SFFOVSMAP = "sffOvsMap";
128
129 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
130 protected RouterService routerService;
131 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
132 protected FloatingIpService floatingIpService;
133 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
134 protected RouterInterfaceService routerInterfaceService;
135 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
136 protected VirtualPortService virtualPortService;
137 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
138 protected HostService hostService;
139 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
140 protected SubnetService subnetService;
141 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
142 protected TenantNetworkService tenantNetworkService;
143 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
144 protected DeviceService deviceService;
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530145 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
146 protected PortPairService portPairService;
147 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
148 protected PortPairGroupService portPairGroupService;
149 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
150 protected FlowClassifierService flowClassifierService;
151 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
152 protected PortChainService portChainService;
jiangruif675cd42015-11-27 15:03:59 +0800153
154 @Activate
155 public void activate() {
Phaneendra Manda5f326872015-12-07 19:25:09 +0530156 eventDispatcher.addSink(VtnRscEvent.class, listenerRegistry);
jiangruif675cd42015-11-27 15:03:59 +0800157 floatingIpService.addListener(floatingIpListener);
158 routerService.addListener(routerListener);
159 routerInterfaceService.addListener(routerInterfaceListener);
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530160 portPairService.addListener(portPairListener);
161 portPairGroupService.addListener(portPairGroupListener);
162 flowClassifierService.addListener(flowClassifierListener);
163 portChainService.addListener(portChainListener);
jiangruif675cd42015-11-27 15:03:59 +0800164
165 KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
166 .register(KryoNamespaces.API)
167 .register(TenantId.class, DeviceId.class);
168 l3vniMap = storageService
169 .<TenantId, SegmentationId>eventuallyConsistentMapBuilder()
170 .withName(L3VNIMAP).withSerializer(serializer)
171 .withTimestampProvider((k, v) -> clockService.getTimestamp())
172 .build();
173
174 classifierOvsMap = storageService
175 .<TenantId, Set<DeviceId>>eventuallyConsistentMapBuilder()
176 .withName(CLASSIFIEROVSMAP).withSerializer(serializer)
177 .withTimestampProvider((k, v) -> clockService.getTimestamp())
178 .build();
179
180 sffOvsMap = storageService
181 .<TenantId, Set<DeviceId>>eventuallyConsistentMapBuilder()
182 .withName(SFFOVSMAP).withSerializer(serializer)
183 .withTimestampProvider((k, v) -> clockService.getTimestamp())
184 .build();
185 }
186
187 @Deactivate
188 public void deactivate() {
Phaneendra Manda5f326872015-12-07 19:25:09 +0530189 eventDispatcher.removeSink(VtnRscEvent.class);
jiangruif675cd42015-11-27 15:03:59 +0800190 floatingIpService.removeListener(floatingIpListener);
191 routerService.removeListener(routerListener);
192 routerInterfaceService.removeListener(routerInterfaceListener);
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530193 portPairService.removeListener(portPairListener);
194 portPairGroupService.removeListener(portPairGroupListener);
195 flowClassifierService.removeListener(flowClassifierListener);
196 portChainService.removeListener(portChainListener);
197
jiangruif675cd42015-11-27 15:03:59 +0800198 l3vniMap.destroy();
199 classifierOvsMap.destroy();
200 sffOvsMap.destroy();
jiangruif675cd42015-11-27 15:03:59 +0800201 log.info("Stopped");
202 }
203
204 @Override
jiangruif675cd42015-11-27 15:03:59 +0800205 public SegmentationId getL3vni(TenantId tenantId) {
206 checkNotNull(tenantId, "tenantId cannot be null");
207 SegmentationId l3vni = l3vniMap.get(tenantId);
208 if (l3vni == null) {
209 long segmentationId = coreService.getIdGenerator(RUNNELOPTOPOIC)
210 .getNewId();
211 l3vni = SegmentationId.segmentationId(String
212 .valueOf(segmentationId));
213 l3vniMap.put(tenantId, l3vni);
214 }
215 return l3vni;
216 }
217
jiangruif675cd42015-11-27 15:03:59 +0800218 private class InnerFloatingIpListener implements FloatingIpListener {
219
220 @Override
221 public void event(FloatingIpEvent event) {
222 checkNotNull(event, EVENT_NOT_NULL);
223 FloatingIp floatingIp = event.subject();
224 if (FloatingIpEvent.Type.FLOATINGIP_PUT == event.type()) {
225 notifyListeners(new VtnRscEvent(
226 VtnRscEvent.Type.FLOATINGIP_PUT,
227 new VtnRscEventFeedback(
228 floatingIp)));
229 }
230 if (FloatingIpEvent.Type.FLOATINGIP_DELETE == event.type()) {
231 notifyListeners(new VtnRscEvent(
232 VtnRscEvent.Type.FLOATINGIP_DELETE,
233 new VtnRscEventFeedback(
234 floatingIp)));
235 }
lishuai762df812016-01-08 11:51:15 +0800236 if (FloatingIpEvent.Type.FLOATINGIP_BIND == event.type()) {
237 notifyListeners(new VtnRscEvent(
238 VtnRscEvent.Type.FLOATINGIP_BIND,
239 new VtnRscEventFeedback(
240 floatingIp)));
241 }
242 if (FloatingIpEvent.Type.FLOATINGIP_UNBIND == event.type()) {
243 notifyListeners(new VtnRscEvent(
244 VtnRscEvent.Type.FLOATINGIP_UNBIND,
245 new VtnRscEventFeedback(
246 floatingIp)));
247 }
jiangruif675cd42015-11-27 15:03:59 +0800248 }
249 }
250
251 private class InnerRouterListener implements RouterListener {
252
253 @Override
254 public void event(RouterEvent event) {
255 checkNotNull(event, EVENT_NOT_NULL);
256 Router router = event.subject();
257 if (RouterEvent.Type.ROUTER_PUT == event.type()) {
258 notifyListeners(new VtnRscEvent(VtnRscEvent.Type.ROUTER_PUT,
259 new VtnRscEventFeedback(router)));
260 }
261 if (RouterEvent.Type.ROUTER_DELETE == event.type()) {
262 notifyListeners(new VtnRscEvent(VtnRscEvent.Type.ROUTER_DELETE,
263 new VtnRscEventFeedback(router)));
264 }
265 }
266 }
267
268 private class InnerRouterInterfaceListener
269 implements RouterInterfaceListener {
270
271 @Override
272 public void event(RouterInterfaceEvent event) {
273 checkNotNull(event, EVENT_NOT_NULL);
274 RouterInterface routerInterface = event.subject();
275 if (RouterInterfaceEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
276 notifyListeners(new VtnRscEvent(
277 VtnRscEvent.Type.ROUTER_INTERFACE_PUT,
278 new VtnRscEventFeedback(
279 routerInterface)));
280 }
281 if (RouterInterfaceEvent.Type.ROUTER_INTERFACE_DELETE == event
282 .type()) {
283 notifyListeners(new VtnRscEvent(
284 VtnRscEvent.Type.ROUTER_INTERFACE_DELETE,
285 new VtnRscEventFeedback(
286 routerInterface)));
287 }
288 }
289 }
290
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530291 private class InnerPortPairListener implements PortPairListener {
292
293 @Override
294 public void event(PortPairEvent event) {
295 checkNotNull(event, EVENT_NOT_NULL);
296 PortPair portPair = event.subject();
297 if (PortPairEvent.Type.PORT_PAIR_PUT == event.type()) {
298 notifyListeners(new VtnRscEvent(VtnRscEvent.Type.PORT_PAIR_PUT,
299 new VtnRscEventFeedback(portPair)));
300 } else if (PortPairEvent.Type.PORT_PAIR_DELETE == event.type()) {
301 notifyListeners(new VtnRscEvent(
302 VtnRscEvent.Type.PORT_PAIR_DELETE,
303 new VtnRscEventFeedback(portPair)));
304 } else if (PortPairEvent.Type.PORT_PAIR_UPDATE == event.type()) {
305 notifyListeners(new VtnRscEvent(
306 VtnRscEvent.Type.PORT_PAIR_UPDATE,
307 new VtnRscEventFeedback(portPair)));
308 }
309 }
310 }
311
312 private class InnerPortPairGroupListener implements PortPairGroupListener {
313
314 @Override
315 public void event(PortPairGroupEvent event) {
316 checkNotNull(event, EVENT_NOT_NULL);
317 PortPairGroup portPairGroup = event.subject();
318 if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) {
319 notifyListeners(new VtnRscEvent(
320 VtnRscEvent.Type.PORT_PAIR_GROUP_PUT,
321 new VtnRscEventFeedback(portPairGroup)));
322 } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) {
323 notifyListeners(new VtnRscEvent(
324 VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE,
325 new VtnRscEventFeedback(portPairGroup)));
326 } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) {
327 notifyListeners(new VtnRscEvent(
328 VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE,
329 new VtnRscEventFeedback(portPairGroup)));
330 }
331 }
332 }
333
334 private class InnerFlowClassifierListener implements FlowClassifierListener {
335
336 @Override
337 public void event(FlowClassifierEvent event) {
338 checkNotNull(event, EVENT_NOT_NULL);
339 FlowClassifier flowClassifier = event.subject();
340 if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) {
341 notifyListeners(new VtnRscEvent(
342 VtnRscEvent.Type.FLOW_CLASSIFIER_PUT,
343 new VtnRscEventFeedback(flowClassifier)));
344 } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) {
345 notifyListeners(new VtnRscEvent(
346 VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE,
347 new VtnRscEventFeedback(flowClassifier)));
348 } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) {
349 notifyListeners(new VtnRscEvent(
350 VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE,
351 new VtnRscEventFeedback(flowClassifier)));
352 }
353 }
354 }
355
356 private class InnerPortChainListener implements PortChainListener {
357
358 @Override
359 public void event(PortChainEvent event) {
360 checkNotNull(event, EVENT_NOT_NULL);
361 PortChain portChain = event.subject();
362 if (PortChainEvent.Type.PORT_CHAIN_PUT == event.type()) {
363 notifyListeners(new VtnRscEvent(
364 VtnRscEvent.Type.PORT_CHAIN_PUT,
365 new VtnRscEventFeedback(portChain)));
366 } else if (PortChainEvent.Type.PORT_CHAIN_DELETE == event.type()) {
367 notifyListeners(new VtnRscEvent(
368 VtnRscEvent.Type.PORT_CHAIN_DELETE,
369 new VtnRscEventFeedback(portChain)));
370 } else if (PortChainEvent.Type.PORT_CHAIN_UPDATE == event.type()) {
371 notifyListeners(new VtnRscEvent(
372 VtnRscEvent.Type.PORT_CHAIN_UPDATE,
373 new VtnRscEventFeedback(portChain)));
374 }
375 }
376 }
377
jiangruif675cd42015-11-27 15:03:59 +0800378 @Override
379 public Iterator<Device> getClassifierOfTenant(TenantId tenantId) {
380 checkNotNull(tenantId, TENANTID_NOT_NULL);
381 Set<DeviceId> deviceIdSet = classifierOvsMap.get(tenantId);
382 Set<Device> deviceSet = new HashSet<>();
383 if (deviceIdSet != null) {
384 for (DeviceId deviceId : deviceIdSet) {
385 deviceSet.add(deviceService.getDevice(deviceId));
386 }
387 }
388 return deviceSet.iterator();
389 }
390
391 @Override
392 public Iterator<Device> getSFFOfTenant(TenantId tenantId) {
393 checkNotNull(tenantId, TENANTID_NOT_NULL);
394 Set<DeviceId> deviceIdSet = sffOvsMap.get(tenantId);
395 Set<Device> deviceSet = new HashSet<>();
396 if (deviceIdSet != null) {
397 for (DeviceId deviceId : deviceIdSet) {
398 deviceSet.add(deviceService.getDevice(deviceId));
399 }
400 }
401 return deviceSet.iterator();
402 }
403
404 @Override
405 public MacAddress getGatewayMac(HostId hostId) {
406 checkNotNull(hostId, "hostId cannot be null");
407 Host host = hostService.getHost(hostId);
408 String ifaceId = host.annotations().value(IFACEID);
409 VirtualPortId hPortId = VirtualPortId.portId(ifaceId);
410 VirtualPort hPort = virtualPortService.getPort(hPortId);
411 SubnetId subnetId = hPort.fixedIps().iterator().next().subnetId();
412 Subnet subnet = subnetService.getSubnet(subnetId);
413 IpAddress gatewayIp = subnet.gatewayIp();
414 Iterable<VirtualPort> virtualPorts = virtualPortService.getPorts();
415 MacAddress macAddress = null;
416 for (VirtualPort port : virtualPorts) {
417 Set<FixedIp> fixedIpSet = port.fixedIps();
418 for (FixedIp fixedIp : fixedIpSet) {
419 if (fixedIp.ip().equals(gatewayIp)) {
420 macAddress = port.macAddress();
421 }
422 }
423 }
424 return macAddress;
425 }
426
427 @Override
428 public boolean isServiceFunction(VirtualPortId portId) {
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530429 return portPairService.exists(PortPairId.of(portId.portId()));
jiangruif675cd42015-11-27 15:03:59 +0800430 }
431
432 @Override
433 public DeviceId getSFToSFFMaping(VirtualPortId portId) {
434 checkNotNull(portId, "portId cannot be null");
435 VirtualPort vmPort = virtualPortService.getPort(portId);
436 Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
437 for (Host host : hostSet) {
Satish K01a60f22015-11-28 15:21:42 +0530438 if (host.annotations().value(IFACEID).equals(vmPort.portId().portId())) {
jiangruif675cd42015-11-27 15:03:59 +0800439 return host.location().deviceId();
440 }
441 }
442 return null;
443 }
444
lishuaib43dbf72016-01-06 11:11:35 +0800445 @Override
446 public void addDeviceIdOfOvsMap(VirtualPortId virtualPortId,
447 TenantId tenantId, DeviceId deviceId) {
448 checkNotNull(virtualPortId, VIRTUALPORTID_NOT_NULL);
449 checkNotNull(tenantId, TENANTID_NOT_NULL);
450 checkNotNull(deviceId, DEVICEID_NOT_NULL);
451 if (isServiceFunction(virtualPortId)) {
452 addDeviceIdToSpecificMap(tenantId, deviceId, sffOvsMap);
453 } else {
454 addDeviceIdToSpecificMap(tenantId, deviceId, classifierOvsMap);
455 }
456 }
457
458 @Override
459 public void removeDeviceIdOfOvsMap(Host host, TenantId tenantId, DeviceId deviceId) {
460 checkNotNull(host, HOST_NOT_NULL);
461 checkNotNull(tenantId, TENANTID_NOT_NULL);
462 checkNotNull(deviceId, DEVICEID_NOT_NULL);
463 if (isLastSFHostOfTenant(host, deviceId, tenantId)) {
464 removeDeviceIdToSpecificMap(tenantId, deviceId, sffOvsMap);
465 }
466 if (isLastClassifierHostOfTenant(host, deviceId, tenantId)) {
467 removeDeviceIdToSpecificMap(tenantId, deviceId, classifierOvsMap);
468 }
469 }
470
jiangruif675cd42015-11-27 15:03:59 +0800471 /**
472 * Checks whether the last Service Function host of a specific tenant in
473 * this device.
474 *
475 * @param host the host on device
476 * @param deviceId the device identifier
477 * @param tenantId the tenant identifier
478 * @return true or false
479 */
480 private boolean isLastSFHostOfTenant(Host host, DeviceId deviceId,
481 TenantId tenantId) {
jiangruif675cd42015-11-27 15:03:59 +0800482 Set<Host> hostSet = hostService.getConnectedHosts(deviceId);
lishuai1fbd41b2015-12-10 16:44:57 +0800483 if (hostSet != null) {
484 for (Host h : hostSet) {
485 String ifaceId = h.annotations().value(IFACEID);
486 if (ifaceId != null) {
487 VirtualPortId hPortId = VirtualPortId.portId(ifaceId);
488 if (virtualPortService.getPort(hPortId).tenantId().tenantId()
489 .equals(tenantId.tenantId())
490 && isServiceFunction(hPortId)) {
lishuaib43dbf72016-01-06 11:11:35 +0800491 if (!h.equals(host)) {
492 return false;
493 }
lishuai1fbd41b2015-12-10 16:44:57 +0800494 }
jiangruif675cd42015-11-27 15:03:59 +0800495 }
496 }
497 }
lishuaib43dbf72016-01-06 11:11:35 +0800498 return true;
jiangruif675cd42015-11-27 15:03:59 +0800499 }
500
501 /**
502 * Checks whether the last Classifier host of a specific tenant in this
503 * device.
504 *
505 * @param host the host on device
506 * @param deviceId the device identifier
507 * @param tenantId the tenant identifier
508 * @return true or false
509 */
510 private boolean isLastClassifierHostOfTenant(Host host, DeviceId deviceId,
511 TenantId tenantId) {
jiangruif675cd42015-11-27 15:03:59 +0800512 Set<Host> hostSet = hostService.getConnectedHosts(deviceId);
lishuai1fbd41b2015-12-10 16:44:57 +0800513 if (hostSet != null) {
514 for (Host h : hostSet) {
515 String ifaceId = h.annotations().value(IFACEID);
516 if (ifaceId != null) {
517 VirtualPortId hPortId = VirtualPortId.portId(ifaceId);
518 if (virtualPortService.getPort(hPortId).tenantId().tenantId()
519 .equals(tenantId.tenantId())
520 && !isServiceFunction(hPortId)) {
lishuaib43dbf72016-01-06 11:11:35 +0800521 if (!h.equals(host)) {
522 return false;
523 }
lishuai1fbd41b2015-12-10 16:44:57 +0800524 }
jiangruif675cd42015-11-27 15:03:59 +0800525 }
526 }
527 }
lishuaib43dbf72016-01-06 11:11:35 +0800528 return true;
jiangruif675cd42015-11-27 15:03:59 +0800529 }
530
531 /**
532 * Adds specify Device identifier to OvsMap.
533 *
534 * @param tenantId the tenant identifier
535 * @param deviceId the device identifier
536 * @param ovsMap the instance of map to store device identifier
537 */
lishuaib43dbf72016-01-06 11:11:35 +0800538 private void addDeviceIdToSpecificMap(TenantId tenantId,
jiangruif675cd42015-11-27 15:03:59 +0800539 DeviceId deviceId,
540 EventuallyConsistentMap<TenantId, Set<DeviceId>> ovsMap) {
jiangruif675cd42015-11-27 15:03:59 +0800541 if (ovsMap.containsKey(tenantId)) {
542 Set<DeviceId> deviceIdSet = ovsMap.get(tenantId);
543 deviceIdSet.add(deviceId);
544 ovsMap.put(tenantId, deviceIdSet);
545 } else {
546 Set<DeviceId> deviceIdSet = new HashSet<>();
547 deviceIdSet.add(deviceId);
548 ovsMap.put(tenantId, deviceIdSet);
549 }
550 }
551
552 /**
553 * Removes specify Device identifier from OvsMap.
554 *
555 * @param tenantId the tenant identifier
556 * @param deviceId the device identifier
557 * @param ovsMap the instance of map to store device identifier
558 */
lishuaib43dbf72016-01-06 11:11:35 +0800559 private void removeDeviceIdToSpecificMap(TenantId tenantId,
jiangruif675cd42015-11-27 15:03:59 +0800560 DeviceId deviceId,
561 EventuallyConsistentMap<TenantId, Set<DeviceId>> ovsMap) {
jiangruif675cd42015-11-27 15:03:59 +0800562 Set<DeviceId> deviceIdSet = ovsMap.get(tenantId);
lishuaib43dbf72016-01-06 11:11:35 +0800563 if (deviceIdSet != null && deviceIdSet.size() > 1) {
jiangruif675cd42015-11-27 15:03:59 +0800564 deviceIdSet.remove(deviceId);
565 ovsMap.put(tenantId, deviceIdSet);
566 } else {
567 ovsMap.remove(tenantId);
568 }
569 }
570
571 /**
572 * Notifies specify event to all listeners.
573 *
574 * @param event VtnRsc event
575 */
576 private void notifyListeners(VtnRscEvent event) {
577 checkNotNull(event, EVENT_NOT_NULL);
Mahesh Poojary Scc11f722015-11-29 16:09:56 +0530578 post(event);
jiangruif675cd42015-11-27 15:03:59 +0800579 }
580}