Removing Blind imports across the module
[netvirt.git] / vpnservice / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / netvirt / vpnmanager / VpnInterfaceOpListener.java
1 /*
2  * Copyright (c) 2015 - 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.vpnmanager;
9
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.concurrent.Callable;
16 import java.util.concurrent.ConcurrentHashMap;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.ExecutorService;
19 import java.util.concurrent.Executors;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
26 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
27 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
28 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
29 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
30 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
36 import org.opendaylight.yangtools.concepts.ListenerRegistration;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 public class VpnInterfaceOpListener extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable {
42     private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceOpListener.class);
43     private ListenerRegistration<DataChangeListener> listenerRegistration;
44     private final DataBroker dataBroker;
45     private final VpnInterfaceManager vpnInterfaceManager;
46     private ConcurrentHashMap<String, Runnable> vpnIntfMap = new ConcurrentHashMap<String, Runnable>();
47     private ExecutorService executorService = Executors.newSingleThreadExecutor();
48
49     /*public VpnInterfaceOpListener(final DataBroker dataBroker) {
50         super(VpnInterface.class);
51         this.dataBroker = dataBroker;
52     }*/
53
54     public VpnInterfaceOpListener(final DataBroker dataBroker, final VpnInterfaceManager vpnInterfaceManager) {
55         super(VpnInterface.class);
56         this.dataBroker = dataBroker;
57         this.vpnInterfaceManager = vpnInterfaceManager;
58     }
59
60     public void start() {
61         LOG.info("{} start", getClass().getSimpleName());
62         listenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
63                 getWildCardPath(), this, AsyncDataBroker.DataChangeScope.SUBTREE);
64     }
65
66     private InstanceIdentifier<VpnInterface> getWildCardPath() {
67         return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class);
68     }
69
70     @Override
71     public void close() throws Exception {
72         if (listenerRegistration != null) {
73             listenerRegistration.close();
74             listenerRegistration = null;
75         }
76         LOG.info("{} close", getClass().getSimpleName());
77     }
78
79     @Override
80     protected void remove(final InstanceIdentifier<VpnInterface> identifier, final VpnInterface del) {
81         final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
82         final String interfaceName = key.getName();
83         final String vpnName = del.getVpnInstanceName();
84         DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
85         dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
86                 new Callable<List<ListenableFuture<Void>>>() {
87                     @Override
88                     public List<ListenableFuture<Void>> call() throws Exception {
89                         WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
90                         postProcessVpnInterfaceRemoval(identifier, del, writeOperTxn);
91                         List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
92                         futures.add(writeOperTxn.submit());
93                         return futures;
94                     }
95                 });
96     }
97
98     private void postProcessVpnInterfaceRemoval(InstanceIdentifier<VpnInterface> identifier, VpnInterface del,
99                                                 WriteTransaction writeOperTxn) {
100         final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
101         String interfaceName = key.getName();
102         String vpnName = del.getVpnInstanceName();
103
104         LOG.info("VpnInterfaceOpListener removed: interface name {} vpnName {}", interfaceName, vpnName);
105         //decrement the vpn interface count in Vpn Instance Op Data
106         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to
107                 .vpn.id.VpnInstance>
108                 id = VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnName);
109         Optional<VpnInstance> vpnInstance
110                 = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
111
112         if (vpnInstance.isPresent()) {
113             String rd = null;
114             rd = vpnInstance.get().getVrfId();
115             //String rd = getRouteDistinguisher(del.getVpnInstanceName());
116
117             VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(dataBroker, rd);
118             LOG.trace("VpnInterfaceOpListener removed: interface name {} rd {} vpnName {}",
119                     interfaceName, rd, vpnName);
120
121             if (vpnInstOp != null) {
122                 // Vpn Interface removed => No more adjacencies from it.
123                 // Hence clean up interface from vpn-dpn-interface list.
124                 Adjacency adjacency = del.getAugmentation(Adjacencies.class).getAdjacency().get(0);
125                 List<Prefixes> prefixToInterface = new ArrayList<>();
126                 Optional<Prefixes> prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
127                         VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
128                                 VpnUtil.getIpPrefix(adjacency.getIpAddress())));
129                 if (prefix.isPresent()) {
130                     prefixToInterface.add(prefix.get());
131                 }
132                 if (prefixToInterface.isEmpty()) {
133                     for (String nh : adjacency.getNextHopIpList()) {
134                         prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
135                                 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
136                                         VpnUtil.getIpPrefix(nh)));
137                         if (prefix.isPresent())
138                             prefixToInterface.add(prefix.get());
139                     }
140                 }
141                 for (Prefixes pref : prefixToInterface) {
142                     if (writeOperTxn != null) {
143                         writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
144                                 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()));
145                     } else {
146                         VpnUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL,
147                                 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()),
148                                 VpnUtil.DEFAULT_CALLBACK);
149                     }
150                     vpnInterfaceManager.updateVpnToDpnMapping(pref.getDpnId(), del.getVpnInstanceName(),
151                             interfaceName, false /* delete */);
152                 }
153             }
154         } else {
155             LOG.error("rd not retrievable as vpninstancetovpnid for vpn {} is absent, trying rd as ", vpnName, vpnName);
156         }
157         notifyTaskIfRequired(interfaceName);
158     }
159
160     private void notifyTaskIfRequired(String intfName) {
161         Runnable notifyTask = vpnIntfMap.remove(intfName);
162         if (notifyTask == null) {
163             LOG.trace("VpnInterfaceOpListener update: No Notify Task queued for vpnInterface {}", intfName);
164             return;
165         }
166         executorService.execute(notifyTask);
167     }
168
169     @Override
170     protected void update(final InstanceIdentifier<VpnInterface> identifier, final VpnInterface original,
171                           final VpnInterface update) {
172         final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
173         final String interfaceName = key.getName();
174
175         if (original.getVpnInstanceName().equals(update.getVpnInstanceName())) {
176             return;
177         }
178
179         final String vpnName = update.getVpnInstanceName();
180         DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
181         dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
182                 new Callable<List<ListenableFuture<Void>>>() {
183                     @Override
184                     public List<ListenableFuture<Void>> call() throws Exception {
185                         postProcessVpnInterfaceUpdate(identifier, original, update);
186                         return null;
187                     }
188                 });
189     }
190
191     private void postProcessVpnInterfaceUpdate(InstanceIdentifier<VpnInterface> identifier, VpnInterface original,
192                                                VpnInterface update) {
193         final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
194         String interfaceName = key.getName();
195
196         //increment the vpn interface count in Vpn Instance Op Data
197         VpnInstanceOpDataEntry vpnInstOp = null;
198         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to
199                 .vpn.id.VpnInstance>
200                 origId = VpnUtil.getVpnInstanceToVpnIdIdentifier(original.getVpnInstanceName());
201         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
202                 .VpnInstance> origVpnInstance
203                 = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, origId);
204
205         if (origVpnInstance.isPresent()) {
206             String rd = null;
207             rd = origVpnInstance.get().getVrfId();
208
209             vpnInstOp = VpnUtil.getVpnInstanceOpData(dataBroker, rd);
210             LOG.trace("VpnInterfaceOpListener updated: interface name {} original rd {} original vpnName {}",
211                     interfaceName, rd, original.getVpnInstanceName());
212
213             if (vpnInstOp != null) {
214                 Adjacency adjacency = original.getAugmentation(Adjacencies.class).getAdjacency().get(0);
215                 List<Prefixes> prefixToInterfaceList = new ArrayList<>();
216                 Optional<Prefixes> prefixToInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
217                         VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
218                                 VpnUtil.getIpPrefix(adjacency.getIpAddress())));
219                 if (prefixToInterface.isPresent()) {
220                     prefixToInterfaceList.add(prefixToInterface.get());
221                 } else {
222                     for (String adj : adjacency.getNextHopIpList()) {
223                         prefixToInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
224                                 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
225                                         VpnUtil.getIpPrefix(adj)));
226                         if (prefixToInterface.isPresent()) {
227                             prefixToInterfaceList.add(prefixToInterface.get());
228                         }
229                     }
230                 }
231                 for (Prefixes prefix : prefixToInterfaceList) {
232                     vpnInterfaceManager.updateVpnToDpnMapping(prefix.getDpnId(), original.getVpnInstanceName(),
233                             interfaceName, false /* delete */);
234                 }
235             }
236         }
237         notifyTaskIfRequired(interfaceName);
238     }
239
240     @Override
241     protected void add(InstanceIdentifier<VpnInterface> identifier, VpnInterface add) {
242     }
243 }