2 * Copyright (c) 2015 - 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.vpnmanager;
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.concurrent.Callable;
15 import java.util.concurrent.ExecutorService;
16 import java.util.concurrent.Executors;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
21 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
22 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
23 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
24 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 public class VpnInterfaceOpListener extends AsyncDataTreeChangeListenerBase<VpnInterface, VpnInterfaceOpListener>
35 implements AutoCloseable {
36 private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceOpListener.class);
37 private final DataBroker dataBroker;
38 private final VpnInterfaceManager vpnInterfaceManager;
39 private final VpnFootprintService vpnFootprintService;
40 private ExecutorService executorService = Executors.newSingleThreadExecutor();
42 /*public VpnInterfaceOpListener(final DataBroker dataBroker) {
43 super(VpnInterface.class);
44 this.dataBroker = dataBroker;
47 public VpnInterfaceOpListener(final DataBroker dataBroker, final VpnInterfaceManager vpnInterfaceManager,
48 final VpnFootprintService vpnFootprintService) {
49 super(VpnInterface.class, VpnInterfaceOpListener.class);
50 this.dataBroker = dataBroker;
51 this.vpnInterfaceManager = vpnInterfaceManager;
52 this.vpnFootprintService = vpnFootprintService;
56 LOG.info("{} start", getClass().getSimpleName());
57 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
61 protected InstanceIdentifier<VpnInterface> getWildCardPath() {
62 return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class);
66 protected VpnInterfaceOpListener getDataTreeChangeListener() {
67 return VpnInterfaceOpListener.this;
72 protected void remove(final InstanceIdentifier<VpnInterface> identifier, final VpnInterface del) {
73 final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
74 final String interfaceName = key.getName();
75 final String vpnName = del.getVpnInstanceName();
76 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
77 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
78 new Callable<List<ListenableFuture<Void>>>() {
80 public List<ListenableFuture<Void>> call() throws Exception {
81 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
82 postProcessVpnInterfaceRemoval(identifier, del, writeOperTxn);
83 List<ListenableFuture<Void>> futures = new ArrayList<>();
84 futures.add(writeOperTxn.submit());
90 private void postProcessVpnInterfaceRemoval(InstanceIdentifier<VpnInterface> identifier, VpnInterface del,
91 WriteTransaction writeOperTxn) {
92 final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
93 String interfaceName = key.getName();
94 String vpnName = del.getVpnInstanceName();
96 LOG.info("VpnInterfaceOpListener removed: interface name {} vpnName {}", interfaceName, vpnName);
97 //decrement the vpn interface count in Vpn Instance Op Data
98 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to
100 id = VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnName);
101 Optional<VpnInstance> vpnInstance
102 = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
104 if (vpnInstance.isPresent()) {
106 rd = vpnInstance.get().getVrfId();
107 //String rd = getRouteDistinguisher(del.getVpnInstanceName());
109 VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(dataBroker, rd);
110 LOG.trace("VpnInterfaceOpListener removed: interface name {} rd {} vpnName {}",
111 interfaceName, rd, vpnName);
113 Adjacencies adjs = del.getAugmentation(Adjacencies.class);
114 List<Adjacency> adjList = (adjs != null) ? adjs.getAdjacency() : null;
116 if (vpnInstOp != null && adjList != null && adjList.size() > 0) {
117 // Vpn Interface removed => No more adjacencies from it.
118 // Hence clean up interface from vpn-dpn-interface list.
119 Adjacency adjacency = adjs.getAdjacency().get(0);
120 List<Prefixes> prefixToInterface = new ArrayList<>();
121 Optional<Prefixes> prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
122 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
123 VpnUtil.getIpPrefix(adjacency.getIpAddress())));
124 if (prefix.isPresent()) {
125 prefixToInterface.add(prefix.get());
127 if (prefixToInterface.isEmpty()) {
128 for (String nh : adjacency.getNextHopIpList()) {
129 prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
130 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
131 VpnUtil.getIpPrefix(nh)));
132 if (prefix.isPresent()) {
133 prefixToInterface.add(prefix.get());
137 for (Prefixes pref : prefixToInterface) {
138 if (writeOperTxn != null) {
139 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
140 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()));
142 VpnUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL,
143 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()),
144 VpnUtil.DEFAULT_CALLBACK);
146 vpnFootprintService.updateVpnToDpnMapping(pref.getDpnId(), del.getVpnInstanceName(),
147 interfaceName, false /* delete */);
151 LOG.error("rd not retrievable as vpninstancetovpnid for vpn {} is absent, trying rd as ", vpnName, vpnName);
153 notifyTaskIfRequired(interfaceName);
156 private void notifyTaskIfRequired(String intfName) {
157 Runnable notifyTask = vpnInterfaceManager.isNotifyTaskQueued(intfName);
158 if (notifyTask == null) {
159 LOG.trace("VpnInterfaceOpListener update: No Notify Task queued for vpnInterface {}", intfName);
162 executorService.execute(notifyTask);
166 protected void update(final InstanceIdentifier<VpnInterface> identifier, final VpnInterface original,
167 final VpnInterface update) {
168 final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
169 final String interfaceName = key.getName();
171 if (original.getVpnInstanceName().equals(update.getVpnInstanceName())) {
175 final String vpnName = update.getVpnInstanceName();
176 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
177 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
178 new Callable<List<ListenableFuture<Void>>>() {
180 public List<ListenableFuture<Void>> call() throws Exception {
181 postProcessVpnInterfaceUpdate(identifier, original, update);
187 private void postProcessVpnInterfaceUpdate(InstanceIdentifier<VpnInterface> identifier, VpnInterface original,
188 VpnInterface update) {
189 final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
190 String interfaceName = key.getName();
192 //increment the vpn interface count in Vpn Instance Op Data
193 VpnInstanceOpDataEntry vpnInstOp = null;
194 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to
196 origId = VpnUtil.getVpnInstanceToVpnIdIdentifier(original.getVpnInstanceName());
197 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
198 .VpnInstance> origVpnInstance
199 = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, origId);
201 if (origVpnInstance.isPresent()) {
202 String rd = origVpnInstance.get().getVrfId();
204 vpnInstOp = VpnUtil.getVpnInstanceOpData(dataBroker, rd);
205 LOG.trace("VpnInterfaceOpListener updated: interface name {} original rd {} original vpnName {}",
206 interfaceName, rd, original.getVpnInstanceName());
208 Adjacencies adjs = original.getAugmentation(Adjacencies.class);
209 List<Adjacency> adjList = (adjs != null) ? adjs.getAdjacency() : null;
211 if (vpnInstOp != null && adjList != null && adjList.size() > 0) {
212 Adjacency adjacency = adjs.getAdjacency().get(0);
213 List<Prefixes> prefixToInterfaceList = new ArrayList<>();
214 Optional<Prefixes> prefixToInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
215 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
216 VpnUtil.getIpPrefix(adjacency.getIpAddress())));
217 if (prefixToInterface.isPresent()) {
218 prefixToInterfaceList.add(prefixToInterface.get());
220 for (String adj : adjacency.getNextHopIpList()) {
221 prefixToInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
222 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
223 VpnUtil.getIpPrefix(adj)));
224 if (prefixToInterface.isPresent()) {
225 prefixToInterfaceList.add(prefixToInterface.get());
229 for (Prefixes prefix : prefixToInterfaceList) {
230 vpnFootprintService.updateVpnToDpnMapping(prefix.getDpnId(), original.getVpnInstanceName(),
231 interfaceName, false /* delete */);
235 notifyTaskIfRequired(interfaceName);
239 protected void add(InstanceIdentifier<VpnInterface> identifier, VpnInterface add) {