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.CheckedFuture;
13 import com.google.common.util.concurrent.FutureCallback;
14 import com.google.common.util.concurrent.Futures;
15 import com.google.common.util.concurrent.ListenableFuture;
16 import java.math.BigInteger;
17 import java.util.ArrayList;
18 import java.util.List;
19 import java.util.concurrent.ExecutionException;
21 import org.apache.commons.lang3.tuple.ImmutablePair;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
27 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
28 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
29 import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEvent;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEventBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddInterfaceToDpnOnVpnEvent;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddInterfaceToDpnOnVpnEventBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveDpnEvent;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveDpnEventBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveInterfaceFromDpnOnVpnEvent;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveInterfaceFromDpnOnVpnEventBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add._interface.to.dpn.on.vpn.event.AddInterfaceEventData;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add._interface.to.dpn.on.vpn.event.AddInterfaceEventDataBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add.dpn.event.AddEventData;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add.dpn.event.AddEventDataBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove._interface.from.dpn.on.vpn.event.RemoveInterfaceEventData;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove._interface.from.dpn.on.vpn.event.RemoveInterfaceEventDataBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventData;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventDataBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
49 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;
50 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;
51 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;
52 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;
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.VpnInterfacesBuilder;
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.VpnInterfacesKey;
55 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
59 public class VpnFootprintService implements IVpnFootprintService {
61 private static final Logger LOG = LoggerFactory.getLogger(VpnFootprintService.class);
63 private final DataBroker dataBroker;
64 private final IFibManager fibManager;
65 private final VpnOpDataSyncer vpnOpDataSyncer;
66 private final OdlInterfaceRpcService ifaceMgrRpcService;
67 private final NotificationPublishService notificationPublishService;
69 public VpnFootprintService(final DataBroker dataBroker, final IFibManager fibManager,
70 final OdlInterfaceRpcService ifaceRpcService, final NotificationPublishService notificationPublishService,
71 final VpnOpDataSyncer vpnOpDataSyncer) {
72 this.dataBroker = dataBroker;
73 this.fibManager = fibManager;
74 this.vpnOpDataSyncer = vpnOpDataSyncer;
75 this.ifaceMgrRpcService = ifaceRpcService;
76 this.notificationPublishService = notificationPublishService;
80 public void updateVpnToDpnMapping(BigInteger dpId, String vpnName, String interfaceName,
81 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair,
83 long vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
85 dpId = InterfaceUtils.getDpnForInterface(ifaceMgrRpcService, interfaceName);
87 if (!dpId.equals(BigInteger.ZERO)) {
89 // Considering the possibility of VpnInstanceOpData not being ready yet cause the VPN is
90 // still in its creation process
91 if (vpnId == VpnConstants.INVALID_ID) {
92 vpnOpDataSyncer.waitForVpnDataReady(VpnOpDataSyncer.VpnOpDataType.vpnInstanceToId, vpnName,
93 VpnConstants.PER_VPN_INSTANCE_OPDATA_MAX_WAIT_TIME_IN_MILLISECONDS);
94 vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
96 if (interfaceName != null) {
97 createOrUpdateVpnToDpnListForInterfaceName(vpnId, dpId, interfaceName, vpnName);
98 publishInterfaceAddedToVpnNotification(interfaceName, dpId, vpnName, vpnId);
100 createOrUpdateVpnToDpnListForIPAddress(vpnId, dpId, ipAddressSourceValuePair, vpnName);
103 if (interfaceName != null) {
104 removeOrUpdateVpnToDpnListForInterfaceName(vpnId, dpId, interfaceName, vpnName);
105 publishInterfaceRemovedFromVpnNotification(interfaceName, dpId, vpnName, vpnId);
107 removeOrUpdateVpnToDpnListForIpAddress(vpnId, dpId, ipAddressSourceValuePair, vpnName);
113 private void createOrUpdateVpnToDpnListForInterfaceName(long vpnId, BigInteger dpnId, String intfName,
115 String primaryRd = VpnUtil.getPrimaryRd(dataBroker, vpnName);
116 Boolean newDpnOnVpn = Boolean.FALSE;
118 synchronized (vpnName.intern()) {
119 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
120 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(primaryRd, dpnId);
121 Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
122 VpnInterfaces vpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
124 if (dpnInVpn.isPresent()) {
125 VpnToDpnList vpnToDpnList = dpnInVpn.get();
126 List<VpnInterfaces> vpnInterfaces = vpnToDpnList.getVpnInterfaces();
127 if (vpnInterfaces == null) {
128 vpnInterfaces = new ArrayList<>();
130 vpnInterfaces.add(vpnInterface);
131 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
132 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
134 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
135 /* If earlier state was inactive, it is considered new DPN coming back to the
138 if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
139 newDpnOnVpn = Boolean.TRUE;
142 List<VpnInterfaces> vpnInterfaces = new ArrayList<>();
143 vpnInterfaces.add(vpnInterface);
144 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
145 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
147 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
148 newDpnOnVpn = Boolean.TRUE;
150 CheckedFuture<Void, TransactionCommitFailedException> futures = writeTxn.submit();
153 } catch (InterruptedException | ExecutionException e) {
154 LOG.error("Error adding to dpnToVpnList for vpn {} interface {} dpn {}", vpnName, intfName, dpnId, e);
155 throw new RuntimeException(e.getMessage());
159 * Informing the Fib only after writeTxn is submitted successfuly.
162 LOG.debug("Sending populateFib event for new dpn {} in VPN {}", dpnId, vpnName);
163 fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd, new DpnEnterExitVpnWorker(dpnId, vpnName, primaryRd,
164 true /* entered */));
168 private void createOrUpdateVpnToDpnListForIPAddress(long vpnId, BigInteger dpnId,
169 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
170 String primaryRd = VpnUtil.getPrimaryRd(dataBroker, vpnName);
171 Boolean newDpnOnVpn = Boolean.FALSE;
173 synchronized (vpnName.intern()) {
174 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
175 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(primaryRd, dpnId);
176 Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
177 IpAddressesBuilder ipAddressesBldr = new IpAddressesBuilder()
178 .setIpAddressSource(ipAddressSourceValuePair.getKey());
179 ipAddressesBldr.setKey(new IpAddressesKey(ipAddressSourceValuePair.getValue()));
180 ipAddressesBldr.setIpAddress(ipAddressSourceValuePair.getValue());
182 if (dpnInVpn.isPresent()) {
183 VpnToDpnList vpnToDpnList = dpnInVpn.get();
184 List<IpAddresses> ipAddresses = vpnToDpnList.getIpAddresses();
185 if (ipAddresses == null) {
186 ipAddresses = new ArrayList<>();
188 ipAddresses.add(ipAddressesBldr.build());
189 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
190 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
192 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
193 /* If earlier state was inactive, it is considered new DPN coming back to the
196 if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
197 newDpnOnVpn = Boolean.TRUE;
200 List<IpAddresses> ipAddresses = new ArrayList<>();
201 ipAddresses.add(ipAddressesBldr.build());
202 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
203 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
205 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
206 newDpnOnVpn = Boolean.TRUE;
208 CheckedFuture<Void, TransactionCommitFailedException> futures = writeTxn.submit();
211 } catch (InterruptedException | ExecutionException e) {
212 LOG.error("Error adding to dpnToVpnList for vpn {} ipAddresses {} dpn {}", vpnName,
213 ipAddressSourceValuePair.getValue(), dpnId, e);
214 throw new RuntimeException(e.getMessage());
218 * Informing the Fib only after writeTxn is submitted successfuly.
221 LOG.debug("Sending populateFib event for new dpn {} in VPN {}", dpnId, vpnName);
222 fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd, new DpnEnterExitVpnWorker(dpnId, vpnName, primaryRd,
223 true /* entered */));
227 private void removeOrUpdateVpnToDpnListForInterfaceName(long vpnId, BigInteger dpnId, String intfName,
229 Boolean lastDpnOnVpn = Boolean.FALSE;
230 String rd = VpnUtil.getVpnRd(dataBroker, vpnName);
231 synchronized (vpnName.intern()) {
232 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
233 VpnToDpnList dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
234 if (dpnInVpn == null) {
235 LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} rd={} id={}]"
236 + " and dpnId={}", vpnName, rd, id, dpnId);
239 List<VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
240 if (vpnInterfaces == null) {
241 LOG.error("Could not find vpnInterfaces for DpnInVpn map for VPN=[name={} rd={} id={}] and dpnId={}",
242 vpnName, rd, id, dpnId);
246 VpnInterfaces currVpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
247 if (vpnInterfaces.remove(currVpnInterface)) {
248 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
249 if (vpnInterfaces.isEmpty()) {
250 List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
251 VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setVpnInterfaces(null);
252 if (ipAddresses == null || ipAddresses.isEmpty()) {
253 dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
254 lastDpnOnVpn = Boolean.TRUE;
256 LOG.warn("vpn interfaces are empty but ip addresses are present for the vpn {} in dpn {}",
259 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(), true);
262 writeTxn.delete(LogicalDatastoreType.OPERATIONAL, id.child(VpnInterfaces.class,
263 new VpnInterfacesKey(intfName)));
265 CheckedFuture<Void, TransactionCommitFailedException> futures = writeTxn.submit();
268 } catch (InterruptedException | ExecutionException e) {
269 LOG.error("Error removing from dpnToVpnList for vpn {} interface {} dpn {}",
270 vpnName, intfName, dpnId, e);
271 throw new RuntimeException(e.getMessage());
274 } // Ends synchronized block
277 LOG.debug("Sending cleanup event for dpn {} in VPN {}", dpnId, vpnName);
278 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd, new DpnEnterExitVpnWorker(dpnId, vpnName, rd,
279 false /* exited */));
283 private void removeOrUpdateVpnToDpnListForIpAddress(long vpnId, BigInteger dpnId,
284 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
285 Boolean lastDpnOnVpn = Boolean.FALSE;
286 String rd = VpnUtil.getVpnRd(dataBroker, vpnName);
287 synchronized (vpnName.intern()) {
288 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
289 VpnToDpnList dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
290 if (dpnInVpn == null) {
291 LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} rd={} id={}]"
292 + " and dpnId={}", vpnName, rd, id, dpnId);
295 List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
296 if (ipAddresses == null) {
297 LOG.error("Could not find ipAddresses for DpnInVpn map for VPN=[name={} rd={} id={}] and dpnId={}",
298 vpnName, rd, id, dpnId);
302 IpAddresses currIpAddress = new IpAddressesBuilder()
303 .setKey(new IpAddressesKey(ipAddressSourceValuePair.getValue()))
304 .setIpAddressSource(ipAddressSourceValuePair.getKey())
306 if (ipAddresses.remove(currIpAddress)) {
307 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
308 if (ipAddresses.isEmpty()) {
309 List<VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
310 VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setIpAddresses(null);
311 if (vpnInterfaces == null || vpnInterfaces.isEmpty()) {
312 dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
313 lastDpnOnVpn = Boolean.TRUE;
315 LOG.warn("ip addresses are empty but vpn interfaces are present for the vpn {} in dpn {}",
318 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(), true);
321 writeTxn.delete(LogicalDatastoreType.OPERATIONAL, id.child(IpAddresses.class,
322 new IpAddressesKey(ipAddressSourceValuePair.getValue())));
324 CheckedFuture<Void, TransactionCommitFailedException> futures = writeTxn.submit();
327 } catch (InterruptedException | ExecutionException e) {
328 LOG.error("Error removing from dpnToVpnList for vpn {} Ipaddress {} dpn {}",
329 vpnName, ipAddressSourceValuePair.getValue(), dpnId, e);
330 throw new RuntimeException(e.getMessage());
333 } // Ends synchronized block
336 LOG.debug("Sending cleanup event for dpn {} in VPN {}", dpnId, vpnName);
337 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd, new DpnEnterExitVpnWorker(dpnId, vpnName, rd,
338 false /* exited */));
342 private void publishAddNotification(final BigInteger dpnId, final String vpnName, final String rd) {
343 LOG.debug("Sending notification for add dpn {} in vpn {} event ", dpnId, vpnName);
344 AddEventData data = new AddEventDataBuilder().setVpnName(vpnName).setRd(rd).setDpnId(dpnId).build();
345 AddDpnEvent event = new AddDpnEventBuilder().setAddEventData(data).build();
346 final ListenableFuture<? extends Object> eventFuture = notificationPublishService.offerNotification(event);
347 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
349 public void onFailure(Throwable error) {
350 LOG.warn("Error in notifying listeners for add dpn {} in vpn {} event ", dpnId, vpnName, error);
354 public void onSuccess(Object arg) {
355 LOG.trace("Successful in notifying listeners for add dpn {} in vpn {} event ", dpnId, vpnName);
360 private void publishRemoveNotification(final BigInteger dpnId, final String vpnName, final String rd) {
361 LOG.debug("Sending notification for remove dpn {} in vpn {} event ", dpnId, vpnName);
362 RemoveEventData data = new RemoveEventDataBuilder().setVpnName(vpnName).setRd(rd).setDpnId(dpnId).build();
363 RemoveDpnEvent event = new RemoveDpnEventBuilder().setRemoveEventData(data).build();
364 final ListenableFuture<? extends Object> eventFuture = notificationPublishService.offerNotification(event);
365 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
367 public void onFailure(Throwable error) {
368 LOG.warn("Error in notifying listeners for remove dpn {} in vpn {} event ", dpnId, vpnName, error);
372 public void onSuccess(Object arg) {
373 LOG.trace("Successful in notifying listeners for remove dpn {} in vpn {} event ", dpnId, vpnName);
378 private void publishInterfaceAddedToVpnNotification(String interfaceName, BigInteger dpnId, String vpnName,
380 LOG.debug("Sending notification for addition of interface {} on dpn {} for vpn {}", interfaceName,
382 AddInterfaceEventData data = new AddInterfaceEventDataBuilder().setInterfaceName(interfaceName)
383 .setVpnId(vpnId).setDpnId(dpnId).build();
384 AddInterfaceToDpnOnVpnEvent event = new AddInterfaceToDpnOnVpnEventBuilder()
385 .setAddInterfaceEventData(data).build();
386 final ListenableFuture<? extends Object> eventFuture = notificationPublishService.offerNotification(event);
387 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
389 public void onFailure(Throwable error) {
390 LOG.warn("Error in notifying listeners for add interface {} on dpn {} in vpn {} event ",
391 interfaceName, dpnId, vpnName, error);
395 public void onSuccess(Object arg) {
396 LOG.trace("Successful in notifying listeners for add interface {} on dpn {} in vpn {} event ",
397 interfaceName, dpnId, vpnName);
402 private void publishInterfaceRemovedFromVpnNotification(String interfaceName, BigInteger dpnId, String vpnName,
404 LOG.debug("Sending notification for removal of interface {} from dpn {} for vpn {}", interfaceName,
406 RemoveInterfaceEventData data = new RemoveInterfaceEventDataBuilder().setInterfaceName(interfaceName)
407 .setVpnId(vpnId).setDpnId(dpnId).build();
408 RemoveInterfaceFromDpnOnVpnEvent event = new RemoveInterfaceFromDpnOnVpnEventBuilder()
409 .setRemoveInterfaceEventData(data).build();
410 final ListenableFuture<? extends Object> eventFuture = notificationPublishService.offerNotification(event);
411 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
413 public void onFailure(Throwable error) {
414 LOG.warn("Error in notifying listeners for removing interface {} from dpn {} in vpn {} event ",
415 interfaceName, dpnId, vpnName, error);
419 public void onSuccess(Object arg) {
420 LOG.trace("Successful in notifying listeners for removing interface {} from dpn {} in vpn {} event ",
421 interfaceName, dpnId, vpnName);
428 * JobCallback class is used as a future callback for
429 * main and rollback workers to handle success and failure.
431 private class DpnEnterExitVpnWorker implements FutureCallback<List<Void>> {
437 DpnEnterExitVpnWorker(BigInteger dpnId, String vpnName, String rd, boolean entered) {
438 this.entered = entered;
440 this.vpnName = vpnName;
445 * This implies that all the future instances have returned success. -- TODO: Confirm this
448 public void onSuccess(List<Void> voids) {
450 publishAddNotification(dpnId, vpnName, rd);
452 publishRemoveNotification(dpnId, vpnName, rd);
457 * This method is used to handle failure callbacks.
458 * If more retry needed, the retrycount is decremented and mainworker is executed again.
459 * After retries completed, rollbackworker is executed.
460 * If rollbackworker fails, this is a double-fault. Double fault is logged and ignored.
463 public void onFailure(Throwable throwable) {
464 LOG.warn("Job: failed with exception: ", throwable);