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 javax.inject.Inject;
21 import javax.inject.Singleton;
22 import org.apache.commons.lang3.tuple.ImmutablePair;
23 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
24 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
25 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
26 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
27 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
28 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEvent;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEventBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddInterfaceToDpnOnVpnEvent;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddInterfaceToDpnOnVpnEventBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveDpnEvent;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveDpnEventBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveInterfaceFromDpnOnVpnEvent;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveInterfaceFromDpnOnVpnEventBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add._interface.to.dpn.on.vpn.event.AddInterfaceEventData;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add._interface.to.dpn.on.vpn.event.AddInterfaceEventDataBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add.dpn.event.AddEventData;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add.dpn.event.AddEventDataBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove._interface.from.dpn.on.vpn.event.RemoveInterfaceEventData;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove._interface.from.dpn.on.vpn.event.RemoveInterfaceEventDataBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventData;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventDataBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
48 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;
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.IpAddressesBuilder;
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.IpAddressesKey;
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.VpnInterfaces;
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.VpnInterfacesBuilder;
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.VpnInterfacesKey;
54 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
55 import org.slf4j.Logger;
56 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 NotificationPublishService notificationPublishService;
69 public VpnFootprintService(final DataBroker dataBroker, final IFibManager fibManager,
70 final NotificationPublishService notificationPublishService, final VpnOpDataSyncer vpnOpDataSyncer) {
71 this.dataBroker = dataBroker;
72 this.fibManager = fibManager;
73 this.vpnOpDataSyncer = vpnOpDataSyncer;
74 this.notificationPublishService = notificationPublishService;
78 public void updateVpnToDpnMapping(BigInteger dpId, String vpnName, String primaryRd, String interfaceName,
79 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, boolean add) {
80 long vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
81 if (!dpId.equals(BigInteger.ZERO)) {
83 // Considering the possibility of VpnInstanceOpData not being ready yet cause
85 // still in its creation process
86 if (vpnId == VpnConstants.INVALID_ID) {
87 LOG.error("updateVpnToDpnMapping: Operational data for vpn not ready. Waiting to update vpn"
88 + " footprint for vpn {} on dpn {} interface {}", vpnName, dpId, interfaceName);
89 vpnOpDataSyncer.waitForVpnDataReady(VpnOpDataSyncer.VpnOpDataType.vpnInstanceToId, vpnName,
90 VpnConstants.PER_VPN_INSTANCE_OPDATA_MAX_WAIT_TIME_IN_MILLISECONDS);
91 vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
93 if (interfaceName != null) {
94 createOrUpdateVpnToDpnListForInterfaceName(vpnId, primaryRd, dpId, interfaceName, vpnName);
95 publishInterfaceAddedToVpnNotification(interfaceName, dpId, vpnName, vpnId);
97 createOrUpdateVpnToDpnListForIPAddress(vpnId, primaryRd, dpId, ipAddressSourceValuePair, vpnName);
100 if (interfaceName != null) {
101 removeOrUpdateVpnToDpnListForInterfaceName(vpnId, primaryRd, dpId, interfaceName, vpnName);
102 publishInterfaceRemovedFromVpnNotification(interfaceName, dpId, vpnName, vpnId);
104 removeOrUpdateVpnToDpnListForIpAddress(vpnId, primaryRd, dpId, ipAddressSourceValuePair, vpnName);
110 private void createOrUpdateVpnToDpnListForInterfaceName(long vpnId, String primaryRd, BigInteger dpnId,
111 String intfName, String vpnName) {
112 Boolean newDpnOnVpn = Boolean.FALSE;
114 synchronized (vpnName.intern()) {
115 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
116 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(primaryRd, dpnId);
117 Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
118 VpnInterfaces vpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
120 if (dpnInVpn.isPresent()) {
121 VpnToDpnList vpnToDpnList = dpnInVpn.get();
122 List<VpnInterfaces> vpnInterfaces = vpnToDpnList.getVpnInterfaces();
123 if (vpnInterfaces == null) {
124 vpnInterfaces = new ArrayList<>();
126 vpnInterfaces.add(vpnInterface);
127 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
128 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
130 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(),
131 WriteTransaction.CREATE_MISSING_PARENTS);
133 * If earlier state was inactive, it is considered new DPN coming back to the
136 if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
137 newDpnOnVpn = Boolean.TRUE;
139 LOG.debug("createOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} interface {}"
140 + " on dpn {}", vpnName, vpnId, intfName, dpnId);
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(),
148 WriteTransaction.CREATE_MISSING_PARENTS);
149 newDpnOnVpn = Boolean.TRUE;
150 LOG.debug("createOrUpdateVpnToDpnList: Creating vpn footprint for vpn {} vpnId {} interface {}"
151 + " on dpn {}", vpnName, vpnId, intfName, dpnId);
154 writeTxn.submit().get();
155 } catch (InterruptedException | ExecutionException e) {
156 LOG.error("createOrUpdateVpnToDpnList: Error adding to dpnToVpnList for vpn {} vpnId {} interface {}"
157 + " dpn {}", vpnName, vpnId, intfName, dpnId, e);
158 throw new RuntimeException(e.getMessage(), e);
161 LOG.info("createOrUpdateVpnToDpnList: Created/Updated vpn footprint for vpn {} vpnId {} interfacName{}"
162 + " on dpn {}", vpnName, vpnId, intfName, dpnId);
164 * Informing the FIB only after writeTxn is submitted successfully.
167 fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd,
168 new DpnEnterExitVpnWorker(dpnId, vpnName, primaryRd, true /* entered */));
169 LOG.info("createOrUpdateVpnToDpnList: Sent populateFib event for new dpn {} in VPN {} for interface {}",
170 dpnId, vpnName, intfName);
174 private void createOrUpdateVpnToDpnListForIPAddress(long vpnId, String primaryRd, BigInteger dpnId,
175 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
176 Boolean newDpnOnVpn = Boolean.FALSE;
178 synchronized (vpnName.intern()) {
179 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
180 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(primaryRd, dpnId);
181 Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
182 IpAddressesBuilder ipAddressesBldr = new IpAddressesBuilder()
183 .setIpAddressSource(ipAddressSourceValuePair.getKey());
184 ipAddressesBldr.setKey(new IpAddressesKey(ipAddressSourceValuePair.getValue()));
185 ipAddressesBldr.setIpAddress(ipAddressSourceValuePair.getValue());
187 if (dpnInVpn.isPresent()) {
188 VpnToDpnList vpnToDpnList = dpnInVpn.get();
189 List<IpAddresses> ipAddresses = vpnToDpnList.getIpAddresses();
190 if (ipAddresses == null) {
191 ipAddresses = new ArrayList<>();
193 ipAddresses.add(ipAddressesBldr.build());
194 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
195 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
197 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
199 * If earlier state was inactive, it is considered new DPN coming back to the
202 if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
203 newDpnOnVpn = Boolean.TRUE;
206 List<IpAddresses> ipAddresses = new ArrayList<>();
207 ipAddresses.add(ipAddressesBldr.build());
208 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
209 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
211 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
212 newDpnOnVpn = Boolean.TRUE;
215 writeTxn.submit().get();
216 } catch (InterruptedException | ExecutionException e) {
217 LOG.error("Error adding to dpnToVpnList for vpn {} ipAddresses {} dpn {}", vpnName,
218 ipAddressSourceValuePair.getValue(), dpnId, e);
219 throw new RuntimeException(e.getMessage(), e);
223 * Informing the Fib only after writeTxn is submitted successfuly.
226 LOG.debug("Sending populateFib event for new dpn {} in VPN {}", dpnId, vpnName);
227 fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd,
228 new DpnEnterExitVpnWorker(dpnId, vpnName, primaryRd, true /* entered */));
232 private void removeOrUpdateVpnToDpnListForInterfaceName(long vpnId, String rd, BigInteger dpnId, String intfName,
234 Boolean lastDpnOnVpn = Boolean.FALSE;
235 synchronized (vpnName.intern()) {
236 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
237 VpnToDpnList dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
238 if (dpnInVpn == null) {
239 LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} rd={} id={}]"
240 + " and dpnId={}", vpnName, rd, id, dpnId);
243 List<VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
244 if (vpnInterfaces == null) {
245 LOG.error("Could not find vpnInterfaces for DpnInVpn map for VPN=[name={} rd={} id={}] and dpnId={}",
246 vpnName, rd, id, dpnId);
250 VpnInterfaces currVpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
251 if (vpnInterfaces.remove(currVpnInterface)) {
252 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
253 if (vpnInterfaces.isEmpty()) {
254 List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
255 VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setVpnInterfaces(null);
256 if (ipAddresses == null || ipAddresses.isEmpty()) {
257 dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
258 lastDpnOnVpn = Boolean.TRUE;
260 LOG.error("removeOrUpdateVpnToDpnList: vpn interfaces are empty but ip addresses are present"
261 + " for the vpn {} in dpn {} interface {}", vpnName, dpnId, intfName);
263 LOG.debug("removeOrUpdateVpnToDpnList: Removing vpn footprint for vpn {} vpnId {} interface {},"
264 + " on dpn {}", vpnName, vpnName, intfName, dpnId);
265 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(),
266 WriteTransaction.CREATE_MISSING_PARENTS);
269 writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
270 id.child(VpnInterfaces.class, new VpnInterfacesKey(intfName)));
271 LOG.debug("removeOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} interface {},"
272 + " on dpn {}", vpnName, vpnName, intfName, dpnId);
275 writeTxn.submit().get();
276 } catch (InterruptedException | ExecutionException e) {
277 LOG.error("removeOrUpdateVpnToDpnList: Error removing from dpnToVpnList for vpn {} vpnId {}"
278 + " interface {} dpn {}", vpnName, vpnId, intfName, dpnId, e);
279 throw new RuntimeException(e.getMessage(), e);
282 } // Ends synchronized block
283 LOG.info("removeOrUpdateVpnToDpnList: Updated/Removed vpn footprint for vpn {} vpnId {} interface {},"
284 + " on dpn {}", vpnName, vpnName, intfName, dpnId);
287 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd,
288 new DpnEnterExitVpnWorker(dpnId, vpnName, rd, false /* exited */));
289 LOG.info("removeOrUpdateVpnToDpnList: Sent cleanup event for dpn {} in VPN {} vpnId {} interface {}", dpnId,
290 vpnName, vpnId, intfName);
294 private void removeOrUpdateVpnToDpnListForIpAddress(long vpnId, String rd, BigInteger dpnId,
295 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
296 Boolean lastDpnOnVpn = Boolean.FALSE;
297 synchronized (vpnName.intern()) {
298 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
299 VpnToDpnList dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
300 if (dpnInVpn == null) {
301 LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} rd={} id={}]"
302 + " and dpnId={}", vpnName, rd, id, dpnId);
305 List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
306 if (ipAddresses == null) {
307 LOG.info("Could not find ipAddresses for DpnInVpn map for VPN=[name={} rd={} id={}] and dpnId={}",
308 vpnName, rd, id, dpnId);
312 IpAddresses currIpAddress = new IpAddressesBuilder()
313 .setKey(new IpAddressesKey(ipAddressSourceValuePair.getValue()))
314 .setIpAddressSource(ipAddressSourceValuePair.getKey()).build();
315 if (ipAddresses.remove(currIpAddress)) {
316 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
317 if (ipAddresses.isEmpty()) {
318 List<VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
319 VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setIpAddresses(null);
320 if (vpnInterfaces == null || vpnInterfaces.isEmpty()) {
321 dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
322 lastDpnOnVpn = Boolean.TRUE;
324 LOG.warn("ip addresses are empty but vpn interfaces are present for the vpn {} in dpn {}",
327 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(), true);
330 writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
331 id.child(IpAddresses.class, new IpAddressesKey(ipAddressSourceValuePair.getValue())));
334 writeTxn.submit().get();
335 } catch (InterruptedException | ExecutionException e) {
336 LOG.error("Error removing from dpnToVpnList for vpn {} Ipaddress {} dpn {}", vpnName,
337 ipAddressSourceValuePair.getValue(), dpnId, e);
338 throw new RuntimeException(e.getMessage(), e);
341 } // Ends synchronized block
344 LOG.debug("Sending cleanup event for dpn {} in VPN {}", dpnId, vpnName);
345 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd,
346 new DpnEnterExitVpnWorker(dpnId, vpnName, rd, false /* exited */));
350 private void publishAddNotification(final BigInteger dpnId, final String vpnName, final String rd) {
351 LOG.debug("publishAddNotification: Sending notification for add dpn {} in vpn {} rd {} event ", dpnId, vpnName,
353 AddEventData data = new AddEventDataBuilder().setVpnName(vpnName).setRd(rd).setDpnId(dpnId).build();
354 AddDpnEvent event = new AddDpnEventBuilder().setAddEventData(data).build();
355 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
356 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
358 public void onFailure(Throwable error) {
359 LOG.error("publishAddNotification: Error in notifying listeners for add dpn {} in vpn {} rd {} event ",
360 dpnId, vpnName, rd, error);
364 public void onSuccess(Object arg) {
365 LOG.info("publishAddNotification: Successful in notifying listeners for add dpn {} in vpn {} rd {}"
366 + " event ", dpnId, vpnName, rd);
368 }, MoreExecutors.directExecutor());
371 private void publishRemoveNotification(final BigInteger dpnId, final String vpnName, final String rd) {
372 LOG.debug("publishRemoveNotification: Sending notification for remove dpn {} in vpn {} rd {} event ", dpnId,
374 RemoveEventData data = new RemoveEventDataBuilder().setVpnName(vpnName).setRd(rd).setDpnId(dpnId).build();
375 RemoveDpnEvent event = new RemoveDpnEventBuilder().setRemoveEventData(data).build();
376 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
377 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
379 public void onFailure(Throwable error) {
380 LOG.error("publishRemoveNotification: Error in notifying listeners for remove dpn {} in vpn {} rd {}"
381 + " event ", dpnId, vpnName, rd, error);
385 public void onSuccess(Object arg) {
386 LOG.info("publishRemoveNotification: Successful in notifying listeners for remove dpn {} in vpn {}"
387 + " rd {} event ", dpnId, vpnName, rd);
389 }, MoreExecutors.directExecutor());
392 private void publishInterfaceAddedToVpnNotification(String interfaceName, BigInteger dpnId, String vpnName,
394 LOG.debug("publishInterfaceAddedToVpnNotification: Sending notification for addition of interface {} on dpn {}"
395 + " for vpn {}", interfaceName, dpnId, vpnName);
396 AddInterfaceEventData data = new AddInterfaceEventDataBuilder().setInterfaceName(interfaceName).setVpnId(vpnId)
397 .setDpnId(dpnId).build();
398 AddInterfaceToDpnOnVpnEvent event = new AddInterfaceToDpnOnVpnEventBuilder().setAddInterfaceEventData(data)
400 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
401 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
403 public void onFailure(Throwable error) {
404 LOG.warn("publishInterfaceAddedToVpnNotification: Error in notifying listeners for add interface {}"
405 + " on dpn {} in vpn {} event ", interfaceName, dpnId, vpnName, error);
409 public void onSuccess(Object arg) {
410 LOG.trace("publishInterfaceAddedToVpnNotification: Successful in notifying listeners for add"
411 + " interface {} on dpn {} in vpn {} event ", interfaceName, dpnId, vpnName);
413 }, MoreExecutors.directExecutor());
416 private void publishInterfaceRemovedFromVpnNotification(String interfaceName, BigInteger dpnId, String vpnName,
418 LOG.debug("publishInterfaceAddedToVpnNotification: Sending notification for removal of interface {}"
419 + " from dpn {} for vpn {}", interfaceName, dpnId, vpnName);
420 RemoveInterfaceEventData data = new RemoveInterfaceEventDataBuilder().setInterfaceName(interfaceName)
421 .setVpnId(vpnId).setDpnId(dpnId).build();
422 RemoveInterfaceFromDpnOnVpnEvent event = new RemoveInterfaceFromDpnOnVpnEventBuilder()
423 .setRemoveInterfaceEventData(data).build();
424 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
425 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
427 public void onFailure(Throwable error) {
429 "publishInterfaceAddedToVpnNotification: Error in notifying listeners"
430 + " for removing interface {} from dpn {} in vpn {} event ",
431 interfaceName, dpnId, vpnName, error);
435 public void onSuccess(Object arg) {
436 LOG.trace("publishInterfaceAddedToVpnNotification: Successful in notifying listeners for removing"
437 + " interface {} from dpn {} in vpn {} event ", interfaceName, dpnId, vpnName);
439 }, MoreExecutors.directExecutor());
443 * JobCallback class is used as a future callback for main and rollback workers
444 * to handle success and failure.
446 private class DpnEnterExitVpnWorker implements FutureCallback<List<Void>> {
447 private final Logger log = LoggerFactory.getLogger(DpnEnterExitVpnWorker.class);
453 DpnEnterExitVpnWorker(BigInteger dpnId, String vpnName, String rd, boolean entered) {
454 this.entered = entered;
456 this.vpnName = vpnName;
461 * This implies that all the future instances have returned success. -- TODO:
465 public void onSuccess(List<Void> voids) {
467 publishAddNotification(dpnId, vpnName, rd);
468 log.info("onSuccess: FootPrint established for vpn {} rd {} on dpn {}", vpnName, rd, dpnId);
470 publishRemoveNotification(dpnId, vpnName, rd);
471 log.info("onSuccess: FootPrint cleared for vpn {} rd {} on dpn {}", vpnName, rd, dpnId);
476 * This method is used to handle failure callbacks. If more retry needed, the
477 * retrycount is decremented and mainworker is executed again. After retries
478 * completed, rollbackworker is executed. If rollbackworker fails, this is a
479 * double-fault. Double fault is logged and ignored.
482 public void onFailure(Throwable throwable) {
483 log.info("onFailure: Failed to establish/clear footprint for vpn {} rd {} on dpn {} ", vpnName, rd, dpnId,
488 boolean isVpnFootPrintCleared(VpnInstanceOpDataEntry vpnInstanceOpData) {
489 return vpnInstanceOpData.getVpnToDpnList() == null || vpnInstanceOpData.getVpnToDpnList().isEmpty();