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
9 package org.opendaylight.netvirt.vpnmanager;
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import java.math.BigInteger;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.atomic.AtomicBoolean;
21 import javax.inject.Inject;
22 import javax.inject.Singleton;
23 import org.apache.commons.lang3.tuple.ImmutablePair;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
26 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
29 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
30 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
31 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
32 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
33 import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEvent;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEventBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddInterfaceToDpnOnVpnEvent;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddInterfaceToDpnOnVpnEventBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveDpnEvent;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveDpnEventBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveInterfaceFromDpnOnVpnEvent;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveInterfaceFromDpnOnVpnEventBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add._interface.to.dpn.on.vpn.event.AddInterfaceEventData;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add._interface.to.dpn.on.vpn.event.AddInterfaceEventDataBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add.dpn.event.AddEventData;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add.dpn.event.AddEventDataBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove._interface.from.dpn.on.vpn.event.RemoveInterfaceEventData;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove._interface.from.dpn.on.vpn.event.RemoveInterfaceEventDataBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventData;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventDataBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddressesBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddressesKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
64 public class VpnFootprintService implements IVpnFootprintService {
66 private static final Logger LOG = LoggerFactory.getLogger(VpnFootprintService.class);
68 private final DataBroker dataBroker;
69 private final ManagedNewTransactionRunner txRunner;
70 private final IFibManager fibManager;
71 private final VpnOpDataSyncer vpnOpDataSyncer;
72 private final NotificationPublishService notificationPublishService;
73 private final IInterfaceManager interfaceManager;
76 public VpnFootprintService(final DataBroker dataBroker, final IFibManager fibManager,
77 final NotificationPublishService notificationPublishService, final VpnOpDataSyncer vpnOpDataSyncer,
78 final IInterfaceManager interfaceManager) {
79 this.dataBroker = dataBroker;
80 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
81 this.fibManager = fibManager;
82 this.vpnOpDataSyncer = vpnOpDataSyncer;
83 this.notificationPublishService = notificationPublishService;
84 this.interfaceManager = interfaceManager;
88 public void updateVpnToDpnMapping(BigInteger dpId, String vpnName, String primaryRd, String interfaceName,
89 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, boolean add) {
90 long vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
91 if (!dpId.equals(BigInteger.ZERO)) {
93 // Considering the possibility of VpnInstanceOpData not being ready yet cause
95 // still in its creation process
96 if (vpnId == VpnConstants.INVALID_ID) {
97 LOG.error("updateVpnToDpnMapping: Operational data for vpn not ready. Waiting to update vpn"
98 + " footprint for vpn {} on dpn {} interface {}", vpnName, dpId, interfaceName);
99 vpnOpDataSyncer.waitForVpnDataReady(VpnOpDataSyncer.VpnOpDataType.vpnInstanceToId, vpnName,
100 VpnConstants.PER_VPN_INSTANCE_OPDATA_MAX_WAIT_TIME_IN_MILLISECONDS);
101 vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
103 if (interfaceName != null) {
104 createOrUpdateVpnToDpnListForInterfaceName(vpnId, primaryRd, dpId, interfaceName, vpnName);
105 publishInterfaceAddedToVpnNotification(interfaceName, dpId, vpnName, vpnId);
107 createOrUpdateVpnToDpnListForIPAddress(vpnId, primaryRd, dpId, ipAddressSourceValuePair, vpnName);
110 if (interfaceName != null) {
111 removeOrUpdateVpnToDpnListForInterfaceName(vpnId, primaryRd, dpId, interfaceName, vpnName);
112 publishInterfaceRemovedFromVpnNotification(interfaceName, dpId, vpnName, vpnId);
114 removeOrUpdateVpnToDpnListForIpAddress(vpnId, primaryRd, dpId, ipAddressSourceValuePair, vpnName);
120 private void createOrUpdateVpnToDpnListForInterfaceName(long vpnId, String primaryRd, BigInteger dpnId,
121 String intfName, String vpnName) {
122 AtomicBoolean newDpnOnVpn = new AtomicBoolean(false);
124 synchronized (vpnName.intern()) {
125 InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(primaryRd, dpnId);
126 Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
127 VpnInterfaces vpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
129 ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
130 if (dpnInVpn.isPresent()) {
131 VpnToDpnList vpnToDpnList = dpnInVpn.get();
132 List<VpnInterfaces> vpnInterfaces = vpnToDpnList.getVpnInterfaces();
133 if (vpnInterfaces == null) {
134 vpnInterfaces = new ArrayList<>();
136 vpnInterfaces.add(vpnInterface);
137 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
138 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
140 tx.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(),
141 WriteTransaction.CREATE_MISSING_PARENTS);
143 * If earlier state was inactive, it is considered new DPN coming back to the
146 if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
147 newDpnOnVpn.set(true);
149 LOG.debug("createOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} interface {}"
150 + " on dpn {}", vpnName, vpnId, intfName, dpnId);
152 List<VpnInterfaces> vpnInterfaces = new ArrayList<>();
153 vpnInterfaces.add(vpnInterface);
154 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
155 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
157 tx.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(),
158 WriteTransaction.CREATE_MISSING_PARENTS);
159 newDpnOnVpn.set(true);
160 LOG.debug("createOrUpdateVpnToDpnList: Creating vpn footprint for vpn {} vpnId {} interface {}"
161 + " on dpn {}", vpnName, vpnId, intfName, dpnId);
167 } catch (InterruptedException | ExecutionException e) {
168 LOG.error("createOrUpdateVpnToDpnList: Error adding to dpnToVpnList for vpn {} vpnId {} interface {}"
169 + " dpn {}", vpnName, vpnId, intfName, dpnId, e);
170 throw new RuntimeException(e.getMessage(), e);
173 LOG.info("createOrUpdateVpnToDpnList: Created/Updated vpn footprint for vpn {} vpnId {} interfacName{}"
174 + " on dpn {}", vpnName, vpnId, intfName, dpnId);
176 * Informing the FIB only after writeTxn is submitted successfully.
178 if (newDpnOnVpn.get()) {
179 if (VpnUtil.isVlan(dataBroker ,intfName)) {
180 if (!VpnUtil.shouldPopulateFibForVlan(dataBroker, vpnName, null, dpnId, interfaceManager)) {
184 fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd,
185 new DpnEnterExitVpnWorker(dpnId, vpnName, primaryRd, true /* entered */));
186 LOG.info("createOrUpdateVpnToDpnList: Sent populateFib event for new dpn {} in VPN {} for interface {}",
187 dpnId, vpnName, intfName);
191 private void createOrUpdateVpnToDpnListForIPAddress(long vpnId, String primaryRd, BigInteger dpnId,
192 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
193 AtomicBoolean newDpnOnVpn = new AtomicBoolean(false);
195 synchronized (vpnName.intern()) {
196 InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(primaryRd, dpnId);
197 Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
198 IpAddressesBuilder ipAddressesBldr = new IpAddressesBuilder()
199 .setIpAddressSource(ipAddressSourceValuePair.getKey());
200 ipAddressesBldr.setKey(new IpAddressesKey(ipAddressSourceValuePair.getValue()));
201 ipAddressesBldr.setIpAddress(ipAddressSourceValuePair.getValue());
203 ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
204 if (dpnInVpn.isPresent()) {
205 VpnToDpnList vpnToDpnList = dpnInVpn.get();
206 List<IpAddresses> ipAddresses = vpnToDpnList.getIpAddresses();
207 if (ipAddresses == null) {
208 ipAddresses = new ArrayList<>();
210 ipAddresses.add(ipAddressesBldr.build());
211 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
212 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
214 tx.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
216 * If earlier state was inactive, it is considered new DPN coming back to the
219 if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
220 newDpnOnVpn.set(true);
223 List<IpAddresses> ipAddresses = new ArrayList<>();
224 ipAddresses.add(ipAddressesBldr.build());
225 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
226 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
228 tx.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
229 newDpnOnVpn.set(true);
234 } catch (InterruptedException | ExecutionException e) {
235 LOG.error("Error adding to dpnToVpnList for vpn {} ipAddresses {} dpn {}", vpnName,
236 ipAddressSourceValuePair.getValue(), dpnId, e);
237 throw new RuntimeException(e.getMessage(), e);
241 * Informing the Fib only after writeTxn is submitted successfuly.
243 if (newDpnOnVpn.get()) {
244 LOG.debug("Sending populateFib event for new dpn {} in VPN {}", dpnId, vpnName);
245 fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd,
246 new DpnEnterExitVpnWorker(dpnId, vpnName, primaryRd, true /* entered */));
250 private void removeOrUpdateVpnToDpnListForInterfaceName(long vpnId, String rd, BigInteger dpnId, String intfName,
252 AtomicBoolean lastDpnOnVpn = new AtomicBoolean(false);
253 synchronized (vpnName.intern()) {
254 InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(rd, dpnId);
255 VpnToDpnList dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
256 if (dpnInVpn == null) {
257 LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} rd={} id={}]"
258 + " and dpnId={}", vpnName, rd, id, dpnId);
261 List<VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
262 if (vpnInterfaces == null) {
263 LOG.error("Could not find vpnInterfaces for DpnInVpn map for VPN=[name={} rd={} id={}] and dpnId={}",
264 vpnName, rd, id, dpnId);
268 VpnInterfaces currVpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
269 if (vpnInterfaces.remove(currVpnInterface)) {
271 txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
272 if (vpnInterfaces.isEmpty()) {
273 List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
274 VpnToDpnListBuilder dpnInVpnBuilder =
275 new VpnToDpnListBuilder(dpnInVpn).setVpnInterfaces(null);
276 if (ipAddresses == null || ipAddresses.isEmpty()) {
277 dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
278 lastDpnOnVpn.set(true);
280 LOG.error("removeOrUpdateVpnToDpnList: vpn interfaces are empty but ip addresses are "
281 + "present for the vpn {} in dpn {} interface {}", vpnName, dpnId, intfName);
283 LOG.debug("removeOrUpdateVpnToDpnList: Removing vpn footprint for vpn {} vpnId {} "
284 + "interface {}, on dpn {}", vpnName, vpnName, intfName, dpnId);
285 tx.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(),
286 WriteTransaction.CREATE_MISSING_PARENTS);
289 tx.delete(LogicalDatastoreType.OPERATIONAL,
290 id.child(VpnInterfaces.class, new VpnInterfacesKey(intfName)));
291 LOG.debug("removeOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} "
292 + "interface {}, on dpn {}", vpnName, vpnName, intfName, dpnId);
295 } catch (InterruptedException | ExecutionException e) {
296 LOG.error("removeOrUpdateVpnToDpnList: Error removing from dpnToVpnList for vpn {} vpnId {}"
297 + " interface {} dpn {}", vpnName, vpnId, intfName, dpnId, e);
298 throw new RuntimeException(e.getMessage(), e);
301 } // Ends synchronized block
302 LOG.info("removeOrUpdateVpnToDpnList: Updated/Removed vpn footprint for vpn {} vpnId {} interface {},"
303 + " on dpn {}", vpnName, vpnName, intfName, dpnId);
305 if (lastDpnOnVpn.get()) {
306 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd,
307 new DpnEnterExitVpnWorker(dpnId, vpnName, rd, false /* exited */));
308 LOG.info("removeOrUpdateVpnToDpnList: Sent cleanup event for dpn {} in VPN {} vpnId {} interface {}", dpnId,
309 vpnName, vpnId, intfName);
313 private void removeOrUpdateVpnToDpnListForIpAddress(long vpnId, String rd, BigInteger dpnId,
314 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
315 AtomicBoolean lastDpnOnVpn = new AtomicBoolean(false);
316 synchronized (vpnName.intern()) {
317 InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(rd, dpnId);
318 VpnToDpnList dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
319 if (dpnInVpn == null) {
320 LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} rd={} id={}]"
321 + " and dpnId={}", vpnName, rd, id, dpnId);
324 List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
325 if (ipAddresses == null) {
326 LOG.info("Could not find ipAddresses for DpnInVpn map for VPN=[name={} rd={} id={}] and dpnId={}",
327 vpnName, rd, id, dpnId);
331 IpAddresses currIpAddress = new IpAddressesBuilder()
332 .setKey(new IpAddressesKey(ipAddressSourceValuePair.getValue()))
333 .setIpAddressSource(ipAddressSourceValuePair.getKey()).build();
334 if (ipAddresses.remove(currIpAddress)) {
336 txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
337 if (ipAddresses.isEmpty()) {
338 List<VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
339 VpnToDpnListBuilder dpnInVpnBuilder =
340 new VpnToDpnListBuilder(dpnInVpn).setIpAddresses(null);
341 if (vpnInterfaces == null || vpnInterfaces.isEmpty()) {
342 dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
343 lastDpnOnVpn.set(true);
345 LOG.warn("ip addresses are empty but vpn interfaces are present for the vpn {} in "
346 + "dpn {}", vpnName, dpnId);
348 tx.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(), true);
351 tx.delete(LogicalDatastoreType.OPERATIONAL, id.child(IpAddresses.class,
352 new IpAddressesKey(ipAddressSourceValuePair.getValue())));
355 } catch (InterruptedException | ExecutionException e) {
356 LOG.error("Error removing from dpnToVpnList for vpn {} Ipaddress {} dpn {}", vpnName,
357 ipAddressSourceValuePair.getValue(), dpnId, e);
358 throw new RuntimeException(e.getMessage(), e);
361 } // Ends synchronized block
363 if (lastDpnOnVpn.get()) {
364 LOG.debug("Sending cleanup event for dpn {} in VPN {}", dpnId, vpnName);
365 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd,
366 new DpnEnterExitVpnWorker(dpnId, vpnName, rd, false /* exited */));
370 private void publishAddNotification(final BigInteger dpnId, final String vpnName, final String rd) {
371 LOG.debug("publishAddNotification: Sending notification for add dpn {} in vpn {} rd {} event ", dpnId, vpnName,
373 AddEventData data = new AddEventDataBuilder().setVpnName(vpnName).setRd(rd).setDpnId(dpnId).build();
374 AddDpnEvent event = new AddDpnEventBuilder().setAddEventData(data).build();
375 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
376 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
378 public void onFailure(Throwable error) {
379 LOG.error("publishAddNotification: Error in notifying listeners for add dpn {} in vpn {} rd {} event ",
380 dpnId, vpnName, rd, error);
384 public void onSuccess(Object arg) {
385 LOG.info("publishAddNotification: Successful in notifying listeners for add dpn {} in vpn {} rd {}"
386 + " event ", dpnId, vpnName, rd);
388 }, MoreExecutors.directExecutor());
391 private void publishRemoveNotification(final BigInteger dpnId, final String vpnName, final String rd) {
392 LOG.debug("publishRemoveNotification: Sending notification for remove dpn {} in vpn {} rd {} event ", dpnId,
394 RemoveEventData data = new RemoveEventDataBuilder().setVpnName(vpnName).setRd(rd).setDpnId(dpnId).build();
395 RemoveDpnEvent event = new RemoveDpnEventBuilder().setRemoveEventData(data).build();
396 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
397 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
399 public void onFailure(Throwable error) {
400 LOG.error("publishRemoveNotification: Error in notifying listeners for remove dpn {} in vpn {} rd {}"
401 + " event ", dpnId, vpnName, rd, error);
405 public void onSuccess(Object arg) {
406 LOG.info("publishRemoveNotification: Successful in notifying listeners for remove dpn {} in vpn {}"
407 + " rd {} event ", dpnId, vpnName, rd);
409 }, MoreExecutors.directExecutor());
412 private void publishInterfaceAddedToVpnNotification(String interfaceName, BigInteger dpnId, String vpnName,
414 LOG.debug("publishInterfaceAddedToVpnNotification: Sending notification for addition of interface {} on dpn {}"
415 + " for vpn {}", interfaceName, dpnId, vpnName);
416 AddInterfaceEventData data = new AddInterfaceEventDataBuilder().setInterfaceName(interfaceName).setVpnId(vpnId)
417 .setDpnId(dpnId).build();
418 AddInterfaceToDpnOnVpnEvent event = new AddInterfaceToDpnOnVpnEventBuilder().setAddInterfaceEventData(data)
420 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
421 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
423 public void onFailure(Throwable error) {
424 LOG.warn("publishInterfaceAddedToVpnNotification: Error in notifying listeners for add interface {}"
425 + " on dpn {} in vpn {} event ", interfaceName, dpnId, vpnName, error);
429 public void onSuccess(Object arg) {
430 LOG.trace("publishInterfaceAddedToVpnNotification: Successful in notifying listeners for add"
431 + " interface {} on dpn {} in vpn {} event ", interfaceName, dpnId, vpnName);
433 }, MoreExecutors.directExecutor());
436 private void publishInterfaceRemovedFromVpnNotification(String interfaceName, BigInteger dpnId, String vpnName,
438 LOG.debug("publishInterfaceAddedToVpnNotification: Sending notification for removal of interface {}"
439 + " from dpn {} for vpn {}", interfaceName, dpnId, vpnName);
440 RemoveInterfaceEventData data = new RemoveInterfaceEventDataBuilder().setInterfaceName(interfaceName)
441 .setVpnId(vpnId).setDpnId(dpnId).build();
442 RemoveInterfaceFromDpnOnVpnEvent event = new RemoveInterfaceFromDpnOnVpnEventBuilder()
443 .setRemoveInterfaceEventData(data).build();
444 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
445 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
447 public void onFailure(Throwable error) {
449 "publishInterfaceAddedToVpnNotification: Error in notifying listeners"
450 + " for removing interface {} from dpn {} in vpn {} event ",
451 interfaceName, dpnId, vpnName, error);
455 public void onSuccess(Object arg) {
456 LOG.trace("publishInterfaceAddedToVpnNotification: Successful in notifying listeners for removing"
457 + " interface {} from dpn {} in vpn {} event ", interfaceName, dpnId, vpnName);
459 }, MoreExecutors.directExecutor());
463 * JobCallback class is used as a future callback for main and rollback workers
464 * to handle success and failure.
466 private class DpnEnterExitVpnWorker implements FutureCallback<List<Void>> {
467 private final Logger log = LoggerFactory.getLogger(DpnEnterExitVpnWorker.class);
473 DpnEnterExitVpnWorker(BigInteger dpnId, String vpnName, String rd, boolean entered) {
474 this.entered = entered;
476 this.vpnName = vpnName;
481 * This implies that all the future instances have returned success. -- TODO:
485 public void onSuccess(List<Void> voids) {
487 publishAddNotification(dpnId, vpnName, rd);
488 log.info("onSuccess: FootPrint established for vpn {} rd {} on dpn {}", vpnName, rd, dpnId);
490 publishRemoveNotification(dpnId, vpnName, rd);
491 log.info("onSuccess: FootPrint cleared for vpn {} rd {} on dpn {}", vpnName, rd, dpnId);
496 * This method is used to handle failure callbacks. If more retry needed, the
497 * retrycount is decremented and mainworker is executed again. After retries
498 * completed, rollbackworker is executed. If rollbackworker fails, this is a
499 * double-fault. Double fault is logged and ignored.
502 public void onFailure(Throwable throwable) {
503 log.info("onFailure: Failed to establish/clear footprint for vpn {} rd {} on dpn {} ", vpnName, rd, dpnId,
508 boolean isVpnFootPrintCleared(VpnInstanceOpDataEntry vpnInstanceOpData) {
509 return vpnInstanceOpData.getVpnToDpnList() == null || vpnInstanceOpData.getVpnToDpnList().isEmpty();