2 * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.elan.internal;
10 import static java.util.Collections.emptyList;
12 import java.util.List;
13 import javax.annotation.PreDestroy;
14 import javax.inject.Inject;
15 import javax.inject.Singleton;
16 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
17 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
18 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
19 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
20 import org.opendaylight.infrautils.utils.concurrent.Executors;
21 import org.opendaylight.mdsal.binding.api.DataBroker;
22 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
23 import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
24 import org.opendaylight.netvirt.elan.cache.ElanInstanceDpnsCache;
25 import org.opendaylight.netvirt.elan.l2gw.jobs.BcGroupUpdateJob;
26 import org.opendaylight.netvirt.elan.l2gw.jobs.DpnDmacJob;
27 import org.opendaylight.netvirt.elan.l2gw.jobs.McastUpdateJob;
28 import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayMulticastUtils;
29 import org.opendaylight.netvirt.elan.l2gw.utils.ElanL2GatewayUtils;
30 import org.opendaylight.netvirt.elan.l2gw.utils.ElanRefUtil;
31 import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
32 import org.opendaylight.netvirt.elan.utils.ElanDmacUtils;
33 import org.opendaylight.netvirt.elan.utils.ElanItmUtils;
34 import org.opendaylight.netvirt.elan.utils.Scheduler;
35 import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
36 import org.opendaylight.serviceutils.tools.listener.AbstractClusteredAsyncDataTreeChangeListener;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
41 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
46 public class ElanDpnInterfaceClusteredListener
47 extends AbstractClusteredAsyncDataTreeChangeListener<DpnInterfaces> {
49 private static final Logger LOG = LoggerFactory.getLogger(ElanDpnInterfaceClusteredListener.class);
50 private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("NetvirtEventLogger");
52 private final DataBroker broker;
53 private final EntityOwnershipUtils entityOwnershipUtils;
54 private final ElanL2GatewayUtils elanL2GatewayUtils;
55 private final ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils;
56 private final ElanRefUtil elanRefUtil;
57 private final ElanDmacUtils elanDmacUtils;
58 private final ElanItmUtils elanItmUtils;
59 private final ElanClusterUtils elanClusterUtils;
60 private final JobCoordinator jobCoordinator;
61 private final ElanInstanceCache elanInstanceCache;
62 private final ElanInstanceDpnsCache elanInstanceDpnsCache;
63 private final IMdsalApiManager mdsalApiManager;
64 private final Scheduler scheduler;
67 public ElanDpnInterfaceClusteredListener(DataBroker broker, EntityOwnershipUtils entityOwnershipUtils,
68 ElanL2GatewayUtils elanL2GatewayUtils,
69 ElanClusterUtils elanClusterUtils, JobCoordinator jobCoordinator,
70 ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils,
71 ElanInstanceCache elanInstanceCache,
73 IMdsalApiManager mdsalApiManager,
74 ElanInstanceDpnsCache elanInstanceDpnsCache,
75 ElanRefUtil elanRefUtil, ElanDmacUtils elanDmacUtils,
76 ElanItmUtils elanItmUtils) {
77 super(broker, LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(ElanDpnInterfaces.class)
78 .child(ElanDpnInterfacesList.class).child(DpnInterfaces.class),
79 Executors.newListeningSingleThreadExecutor("ElanDpnInterfaceClusteredListener", LOG));
81 this.entityOwnershipUtils = entityOwnershipUtils;
82 this.elanL2GatewayUtils = elanL2GatewayUtils;
83 this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
84 this.elanRefUtil = elanRefUtil;
85 this.elanDmacUtils = elanDmacUtils;
86 this.elanItmUtils = elanItmUtils;
87 this.elanClusterUtils = elanClusterUtils;
88 this.jobCoordinator = jobCoordinator;
89 this.elanInstanceCache = elanInstanceCache;
90 this.elanInstanceDpnsCache = elanInstanceDpnsCache;
91 this.mdsalApiManager = mdsalApiManager;
92 this.scheduler = scheduler;
96 LOG.info("{} start", getClass().getSimpleName());
99 void handleUpdate(InstanceIdentifier<DpnInterfaces> id, DpnInterfaces dpnInterfaces) {
100 final String elanName = getElanName(id);
101 if (ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName).isEmpty()) {
102 LOG.debug("dpnInterface updation, no external l2 devices to update for elan {} with Dp Id {}", elanName,
103 dpnInterfaces.getDpId());
106 elanClusterUtils.runOnlyInOwnerNode(elanName, "updating mcast mac upon tunnel event",
108 elanL2GatewayMulticastUtils.updateRemoteMcastMacOnElanL2GwDevices(elanName);
114 public void remove(InstanceIdentifier<DpnInterfaces> identifier, final DpnInterfaces dpnInterfaces) {
115 // this is the last dpn interface on this elan
116 final String elanName = getElanName(identifier);
117 //Cache need to be updated in all cluster nodes and not only by leader node .
118 //Hence moved out from DJC job
120 jobCoordinator.enqueueJob(elanName + ":l2gw", () -> {
122 if (entityOwnershipUtils.isEntityOwner(HwvtepSouthboundConstants.ELAN_ENTITY_TYPE,
123 HwvtepSouthboundConstants.ELAN_ENTITY_NAME)) {
124 // deleting Elan L2Gw Devices UcastLocalMacs From Dpn
125 DpnDmacJob.uninstallDmacFromL2gws(elanName, dpnInterfaces, elanL2GatewayUtils, elanClusterUtils,
126 elanInstanceCache, elanDmacUtils, scheduler, jobCoordinator);
128 //Removing this dpn from cache to avoid race between this and local ucast mac listener
129 elanInstanceDpnsCache.remove(getElanName(identifier), dpnInterfaces);
131 // updating remote mcast mac on l2gw devices
132 McastUpdateJob.updateAllMcastsForDpnDelete(elanName, elanL2GatewayMulticastUtils, elanClusterUtils,
133 dpnInterfaces.getDpId().toJava(), elanItmUtils, scheduler, jobCoordinator);
134 BcGroupUpdateJob.updateAllBcGroups(elanName, false, dpnInterfaces.getDpId(),
135 null, elanRefUtil, elanL2GatewayMulticastUtils, mdsalApiManager,
136 elanInstanceDpnsCache, elanItmUtils);
139 elanInstanceDpnsCache.remove(getElanName(identifier), dpnInterfaces);
147 public void update(InstanceIdentifier<DpnInterfaces> identifier, DpnInterfaces original,
148 final DpnInterfaces dpnInterfaces) {
149 List<String> interfaces = dpnInterfaces.getInterfaces();
150 if (interfaces != null && !interfaces.isEmpty()) {
151 LOG.debug("dpninterfaces update fired new size {}", interfaces.size());
152 elanInstanceDpnsCache.remove(getElanName(identifier), original);
153 elanInstanceDpnsCache.add(getElanName(identifier), dpnInterfaces);
154 LOG.debug("dpninterfaces last dpn interface on this elan {} ", dpnInterfaces.key());
155 // this is the last dpn interface on this elan
156 handleUpdate(identifier, dpnInterfaces);
161 public void add(InstanceIdentifier<DpnInterfaces> identifier, final DpnInterfaces dpnInterfaces) {
162 final String elanName = getElanName(identifier);
163 EVENT_LOGGER.debug("ELAN-DpnInterface, ADD DPN {} Instance {}", dpnInterfaces.getDpId(), elanName);
164 jobCoordinator.enqueueJob(elanName + ":l2gw", () -> {
165 elanInstanceDpnsCache.add(getElanName(identifier), dpnInterfaces);
166 if (entityOwnershipUtils.isEntityOwner(HwvtepSouthboundConstants.ELAN_ENTITY_TYPE,
167 HwvtepSouthboundConstants.ELAN_ENTITY_NAME)) {
168 ElanInstance elanInstance = elanInstanceCache.get(elanName).orElse(null);
169 if (elanInstance != null) {
170 BcGroupUpdateJob.updateAllBcGroups(elanName, true, dpnInterfaces.getDpId(),
171 null, elanRefUtil, elanL2GatewayMulticastUtils, mdsalApiManager,
172 elanInstanceDpnsCache, elanItmUtils);
173 // updating remote mcast mac on l2gw devices
174 McastUpdateJob.updateAllMcastsForDpnAdd(elanName, elanL2GatewayMulticastUtils, elanClusterUtils,
175 scheduler, jobCoordinator);
176 DpnDmacJob.installDmacFromL2gws(elanName, dpnInterfaces, elanL2GatewayUtils, elanClusterUtils,
177 elanInstanceCache, elanDmacUtils, scheduler, jobCoordinator);
184 private static String getElanName(InstanceIdentifier<DpnInterfaces> identifier) {
185 return identifier.firstKeyOf(ElanDpnInterfacesList.class).getElanInstanceName();
190 public void close() {
192 Executors.shutdownAndAwaitTermination(getExecutorService());