VpnPortIpToPort Listener for ELAN
[netvirt.git] / vpnservice / elanmanager / elanmanager-impl / src / main / java / org / opendaylight / netvirt / elan / internal / ElanVpnPortIpToPortListener.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.netvirt.elan.internal;
9
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.concurrent.Callable;
13
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;
28
29 import com.google.common.util.concurrent.ListenableFuture;
30
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;
37
38     public ElanVpnPortIpToPortListener(DataBroker broker, IInterfaceManager interfaceManager, ElanUtils elanUtils) {
39         super(VpnPortipToPort.class, ElanVpnPortIpToPortListener.class);
40         this.broker = broker;
41         this.interfaceManager = interfaceManager;
42         this.elanUtils = elanUtils;
43     }
44
45     public void init() {
46         registerListener(LogicalDatastoreType.OPERATIONAL, broker);
47     }
48
49     public void close() throws Exception {
50         super.close();
51         logger.debug("ElanVpnPortIpToPort Listener Closed");
52     }
53
54     @Override
55     protected InstanceIdentifier<VpnPortipToPort> getWildCardPath() {
56         return InstanceIdentifier.create(NeutronVpnPortipPortData.class).child(VpnPortipToPort.class);
57     }
58
59     @Override
60     protected void remove(InstanceIdentifier<VpnPortipToPort> key, VpnPortipToPort dataObjectModification) {
61         String macAddress = dataObjectModification.getMacAddress();
62         String interfaceName = dataObjectModification.getPortName();
63         boolean isLearnt = dataObjectModification.isLearnt();
64         if (!isLearnt) {
65             logger.trace("Not learnt mac {}. Not performing action", macAddress);
66             return;
67         }
68         logger.trace("Removing mac address {} from interface {} ", macAddress, interfaceName);
69         DataStoreJobCoordinator.getInstance().enqueueJob(buildJobKey(macAddress, interfaceName),
70                 new StaticMacRemoveWorker(macAddress, interfaceName));
71     }
72
73     @Override
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,
85                     newInterfaceName);
86             return;
87         }
88         if (isLearntOld) {
89             logger.trace("Removing mac address {} from interface {} due to update event", oldMac, oldInterfaceName);
90             coordinator.enqueueJob(buildJobKey(oldMac, oldInterfaceName), new StaticMacRemoveWorker(oldMac,
91                     oldInterfaceName));
92         }
93         if (isLearntNew) {
94             logger.trace("Adding mac address {} to interface {} due to update event", newMac, newInterfaceName);
95             coordinator.enqueueJob(buildJobKey(newMac, newInterfaceName), new StaticMacAddWorker(newMac,
96                     newInterfaceName));
97         }
98     }
99
100     @Override
101     protected void add(InstanceIdentifier<VpnPortipToPort> key, VpnPortipToPort dataObjectModification) {
102         String macAddress = dataObjectModification.getMacAddress();
103         String interfaceName = dataObjectModification.getPortName();
104         boolean isLearnt = dataObjectModification.isLearnt();
105         if (isLearnt) {
106             logger.trace("Adding mac address {} to interface {} ", macAddress, interfaceName);
107             DataStoreJobCoordinator.getInstance().enqueueJob(buildJobKey(macAddress, interfaceName),
108                     new StaticMacAddWorker(macAddress, interfaceName));
109         }
110     }
111
112     @Override
113     protected ElanVpnPortIpToPortListener getDataTreeChangeListener() {
114         return this;
115     }
116
117     private class StaticMacAddWorker implements Callable<List<ListenableFuture<Void>>> {
118         String macAddress, interfaceName;
119
120         public StaticMacAddWorker(String macAddress, String interfaceName) {
121             this.macAddress = macAddress;
122             this.interfaceName = interfaceName;
123         }
124
125         @Override
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);
133                 return futures;
134             }
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());
139             return futures;
140         }
141     }
142
143     private class StaticMacRemoveWorker implements Callable<List<ListenableFuture<Void>>> {
144         String macAddress, interfaceName;
145
146         public StaticMacRemoveWorker(String macAddress, String interfaceName) {
147             this.macAddress = macAddress;
148             this.interfaceName = interfaceName;
149         }
150
151         @Override
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);
159                 return futures;
160             }
161             elanUtils.deleteMacEntryFromDsAndRemoveFlows(interfaceManager, interfaceName, macAddress,
162                     elanInterface.getElanInstanceName(), tx, deleteFlowTx);
163             futures.add(tx.submit());
164             futures.add(deleteFlowTx.submit());
165             return futures;
166         }
167     }
168
169     private String buildJobKey(String mac, String interfaceName) {
170         return "ENTERPRISEMACJOB"+ mac + interfaceName;
171     }
172
173
174 }