2 * Copyright (c) 2016 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 java.util.ArrayList;
11 import java.util.List;
12 import java.util.concurrent.Callable;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
18 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
19 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
20 import org.opendaylight.netvirt.elan.utils.ElanConstants;
21 import org.opendaylight.netvirt.elan.utils.ElanUtils;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
25 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 import com.google.common.util.concurrent.ListenableFuture;
31 public class ElanVpnPortIpToPortListener extends
32 AsyncDataTreeChangeListenerBase<VpnPortipToPort, ElanVpnPortIpToPortListener> {
33 private static final Logger logger = LoggerFactory.getLogger(ElanVpnPortIpToPortListener.class);
34 private final DataBroker broker;
35 private final IInterfaceManager interfaceManager;
36 private final ElanUtils elanUtils;
38 public ElanVpnPortIpToPortListener(DataBroker broker, IInterfaceManager interfaceManager, ElanUtils elanUtils) {
39 super(VpnPortipToPort.class, ElanVpnPortIpToPortListener.class);
41 this.interfaceManager = interfaceManager;
42 this.elanUtils = elanUtils;
46 registerListener(LogicalDatastoreType.OPERATIONAL, broker);
49 public void close() throws Exception {
51 logger.debug("ElanVpnPortIpToPort Listener Closed");
55 protected InstanceIdentifier<VpnPortipToPort> getWildCardPath() {
56 return InstanceIdentifier.create(NeutronVpnPortipPortData.class).child(VpnPortipToPort.class);
60 protected void remove(InstanceIdentifier<VpnPortipToPort> key, VpnPortipToPort dataObjectModification) {
61 String macAddress = dataObjectModification.getMacAddress();
62 String interfaceName = dataObjectModification.getPortName();
63 boolean isLearnt = dataObjectModification.isLearnt();
65 logger.trace("Not learnt mac {}. Not performing action", macAddress);
68 logger.trace("Removing mac address {} from interface {} ", macAddress, interfaceName);
69 DataStoreJobCoordinator.getInstance().enqueueJob(buildJobKey(macAddress, interfaceName),
70 new StaticMacRemoveWorker(macAddress, interfaceName));
74 protected void update(InstanceIdentifier<VpnPortipToPort> key, VpnPortipToPort dataObjectModificationBefore,
75 VpnPortipToPort dataObjectModificationAfter) {
76 String oldMac = dataObjectModificationBefore.getMacAddress();
77 String oldInterfaceName = dataObjectModificationBefore.getPortName();
78 String newMac = dataObjectModificationAfter.getMacAddress();
79 String newInterfaceName = dataObjectModificationAfter.getPortName();
80 boolean isLearntOld = dataObjectModificationBefore.isLearnt();
81 boolean isLearntNew = dataObjectModificationAfter.isLearnt();
82 DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
83 if (oldMac.equals(newMac) && oldInterfaceName.equals(newInterfaceName)) {
84 logger.trace("No change in Mac Address {} and InterfaceName {}. No actions performed", newMac,
89 logger.trace("Removing mac address {} from interface {} due to update event", oldMac, oldInterfaceName);
90 coordinator.enqueueJob(buildJobKey(oldMac, oldInterfaceName), new StaticMacRemoveWorker(oldMac,
94 logger.trace("Adding mac address {} to interface {} due to update event", newMac, newInterfaceName);
95 coordinator.enqueueJob(buildJobKey(newMac, newInterfaceName), new StaticMacAddWorker(newMac,
101 protected void add(InstanceIdentifier<VpnPortipToPort> key, VpnPortipToPort dataObjectModification) {
102 String macAddress = dataObjectModification.getMacAddress();
103 String interfaceName = dataObjectModification.getPortName();
104 boolean isLearnt = dataObjectModification.isLearnt();
106 logger.trace("Adding mac address {} to interface {} ", macAddress, interfaceName);
107 DataStoreJobCoordinator.getInstance().enqueueJob(buildJobKey(macAddress, interfaceName),
108 new StaticMacAddWorker(macAddress, interfaceName));
113 protected ElanVpnPortIpToPortListener getDataTreeChangeListener() {
117 private class StaticMacAddWorker implements Callable<List<ListenableFuture<Void>>> {
118 String macAddress, interfaceName;
120 public StaticMacAddWorker(String macAddress, String interfaceName) {
121 this.macAddress = macAddress;
122 this.interfaceName = interfaceName;
126 public List<ListenableFuture<Void>> call() throws Exception {
127 List<ListenableFuture<Void>> futures = new ArrayList<>();
128 WriteTransaction flowWritetx = broker.newWriteOnlyTransaction();
129 WriteTransaction tx = broker.newWriteOnlyTransaction();
130 ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
131 if (elanInterface == null) {
132 logger.debug("ElanInterface Not present for interfaceName {} for add event", interfaceName);
135 elanUtils.addMacEntryToDsAndSetupFlows(interfaceManager, interfaceName, macAddress, elanInterface.getElanInstanceName(), tx,
136 flowWritetx, ElanConstants.STATIC_MAC_TIMEOUT);
137 futures.add(tx.submit());
138 futures.add(flowWritetx.submit());
143 private class StaticMacRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
144 String macAddress, interfaceName;
146 public StaticMacRemoveWorker(String macAddress, String interfaceName) {
147 this.macAddress = macAddress;
148 this.interfaceName = interfaceName;
152 public List<ListenableFuture<Void>> call() throws Exception {
153 List<ListenableFuture<Void>> futures = new ArrayList<>();
154 WriteTransaction deleteFlowTx = broker.newWriteOnlyTransaction();
155 WriteTransaction tx = broker.newWriteOnlyTransaction();
156 ElanInterface elanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
157 if (elanInterface == null) {
158 logger.debug("ElanInterface Not present for interfaceName {} for delete event", interfaceName);
161 elanUtils.deleteMacEntryFromDsAndRemoveFlows(interfaceManager, interfaceName, macAddress,
162 elanInterface.getElanInstanceName(), tx, deleteFlowTx);
163 futures.add(tx.submit());
164 futures.add(deleteFlowTx.submit());
169 private String buildJobKey(String mac, String interfaceName) {
170 return "ENTERPRISEMACJOB"+ mac + interfaceName;