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 java.math.BigInteger;
16 import java.util.ArrayList;
17 import java.util.List;
18 import java.util.concurrent.ExecutionException;
19 import org.apache.commons.lang3.tuple.ImmutablePair;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
25 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
26 import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEvent;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEventBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddInterfaceToDpnOnVpnEvent;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddInterfaceToDpnOnVpnEventBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveDpnEvent;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveDpnEventBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveInterfaceFromDpnOnVpnEvent;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RemoveInterfaceFromDpnOnVpnEventBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add._interface.to.dpn.on.vpn.event.AddInterfaceEventData;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add._interface.to.dpn.on.vpn.event.AddInterfaceEventDataBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add.dpn.event.AddEventData;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.add.dpn.event.AddEventDataBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove._interface.from.dpn.on.vpn.event.RemoveInterfaceEventData;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove._interface.from.dpn.on.vpn.event.RemoveInterfaceEventDataBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventData;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.remove.dpn.event.RemoveEventDataBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
47 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;
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.IpAddressesBuilder;
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.IpAddressesKey;
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.VpnInterfaces;
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.VpnInterfacesBuilder;
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.VpnInterfacesKey;
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
57 public class VpnFootprintService implements IVpnFootprintService {
59 private static final Logger LOG = LoggerFactory.getLogger(VpnFootprintService.class);
61 private final DataBroker dataBroker;
62 private final IFibManager fibManager;
63 private final VpnOpDataSyncer vpnOpDataSyncer;
64 private final OdlInterfaceRpcService ifaceMgrRpcService;
65 private final NotificationPublishService notificationPublishService;
67 public VpnFootprintService(final DataBroker dataBroker, final IFibManager fibManager,
68 final OdlInterfaceRpcService ifaceRpcService, final NotificationPublishService notificationPublishService,
69 final VpnOpDataSyncer vpnOpDataSyncer) {
70 this.dataBroker = dataBroker;
71 this.fibManager = fibManager;
72 this.vpnOpDataSyncer = vpnOpDataSyncer;
73 this.ifaceMgrRpcService = ifaceRpcService;
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);
82 dpId = InterfaceUtils.getDpnForInterface(ifaceMgrRpcService, interfaceName);
84 if (!dpId.equals(BigInteger.ZERO)) {
86 // Considering the possibility of VpnInstanceOpData not being ready yet cause
88 // still in its creation process
89 if (vpnId == VpnConstants.INVALID_ID) {
90 LOG.error("updateVpnToDpnMapping: Operational data for vpn not ready. Waiting to update vpn"
91 + " footprint for vpn {} on dpn {} interface {}", vpnName, dpId, interfaceName);
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, primaryRd, dpId, interfaceName, vpnName);
98 publishInterfaceAddedToVpnNotification(interfaceName, dpId, vpnName, vpnId);
100 createOrUpdateVpnToDpnListForIPAddress(vpnId, primaryRd, dpId, ipAddressSourceValuePair, vpnName);
103 if (interfaceName != null) {
104 removeOrUpdateVpnToDpnListForInterfaceName(vpnId, primaryRd, dpId, interfaceName, vpnName);
105 publishInterfaceRemovedFromVpnNotification(interfaceName, dpId, vpnName, vpnId);
107 removeOrUpdateVpnToDpnListForIpAddress(vpnId, primaryRd, dpId, ipAddressSourceValuePair, vpnName);
113 private void createOrUpdateVpnToDpnListForInterfaceName(long vpnId, String primaryRd, BigInteger dpnId,
114 String intfName, String vpnName) {
115 Boolean newDpnOnVpn = Boolean.FALSE;
117 synchronized (vpnName.intern()) {
118 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
119 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(primaryRd, dpnId);
120 Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
121 VpnInterfaces vpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
123 if (dpnInVpn.isPresent()) {
124 VpnToDpnList vpnToDpnList = dpnInVpn.get();
125 List<VpnInterfaces> vpnInterfaces = vpnToDpnList.getVpnInterfaces();
126 if (vpnInterfaces == null) {
127 vpnInterfaces = new ArrayList<>();
129 vpnInterfaces.add(vpnInterface);
130 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
131 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
133 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(),
134 WriteTransaction.CREATE_MISSING_PARENTS);
136 * If earlier state was inactive, it is considered new DPN coming back to the
139 if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
140 newDpnOnVpn = Boolean.TRUE;
142 LOG.debug("createOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} interface {}"
143 + " on dpn {}", vpnName, vpnId, intfName, dpnId);
145 List<VpnInterfaces> vpnInterfaces = new ArrayList<>();
146 vpnInterfaces.add(vpnInterface);
147 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
148 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
150 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(),
151 WriteTransaction.CREATE_MISSING_PARENTS);
152 newDpnOnVpn = Boolean.TRUE;
153 LOG.debug("createOrUpdateVpnToDpnList: Creating vpn footprint for vpn {} vpnId {} interface {}"
154 + " on dpn {}", vpnName, vpnId, intfName, dpnId);
157 writeTxn.submit().get();
158 } catch (InterruptedException | ExecutionException e) {
159 LOG.error("createOrUpdateVpnToDpnList: Error adding to dpnToVpnList for vpn {} vpnId {} interface {}"
160 + " dpn {}", vpnName, vpnId, intfName, dpnId, e);
161 throw new RuntimeException(e.getMessage());
164 LOG.info("createOrUpdateVpnToDpnList: Created/Updated vpn footprint for vpn {} vpnId {} interfacName{}"
165 + " on dpn {}", vpnName, vpnId, intfName, dpnId);
167 * Informing the FIB only after writeTxn is submitted successfully.
170 fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd,
171 new DpnEnterExitVpnWorker(dpnId, vpnName, primaryRd, true /* entered */));
172 LOG.info("createOrUpdateVpnToDpnList: Sent populateFib event for new dpn {} in VPN {} for interface {}",
173 dpnId, vpnName, intfName);
177 private void createOrUpdateVpnToDpnListForIPAddress(long vpnId, String primaryRd, BigInteger dpnId,
178 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
179 Boolean newDpnOnVpn = Boolean.FALSE;
181 synchronized (vpnName.intern()) {
182 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
183 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(primaryRd, dpnId);
184 Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
185 IpAddressesBuilder ipAddressesBldr = new IpAddressesBuilder()
186 .setIpAddressSource(ipAddressSourceValuePair.getKey());
187 ipAddressesBldr.setKey(new IpAddressesKey(ipAddressSourceValuePair.getValue()));
188 ipAddressesBldr.setIpAddress(ipAddressSourceValuePair.getValue());
190 if (dpnInVpn.isPresent()) {
191 VpnToDpnList vpnToDpnList = dpnInVpn.get();
192 List<IpAddresses> ipAddresses = vpnToDpnList.getIpAddresses();
193 if (ipAddresses == null) {
194 ipAddresses = new ArrayList<>();
196 ipAddresses.add(ipAddressesBldr.build());
197 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
198 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
200 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
202 * If earlier state was inactive, it is considered new DPN coming back to the
205 if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
206 newDpnOnVpn = Boolean.TRUE;
209 List<IpAddresses> ipAddresses = new ArrayList<>();
210 ipAddresses.add(ipAddressesBldr.build());
211 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
212 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
214 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
215 newDpnOnVpn = Boolean.TRUE;
218 writeTxn.submit().get();
219 } catch (InterruptedException | ExecutionException e) {
220 LOG.error("Error adding to dpnToVpnList for vpn {} ipAddresses {} dpn {}", vpnName,
221 ipAddressSourceValuePair.getValue(), dpnId, e);
222 throw new RuntimeException(e.getMessage());
226 * Informing the Fib only after writeTxn is submitted successfuly.
229 LOG.debug("Sending populateFib event for new dpn {} in VPN {}", dpnId, vpnName);
230 fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd,
231 new DpnEnterExitVpnWorker(dpnId, vpnName, primaryRd, true /* entered */));
235 private void removeOrUpdateVpnToDpnListForInterfaceName(long vpnId, String rd, BigInteger dpnId, String intfName,
237 Boolean lastDpnOnVpn = Boolean.FALSE;
238 synchronized (vpnName.intern()) {
239 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
240 VpnToDpnList dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
241 if (dpnInVpn == null) {
242 LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} rd={} id={}]"
243 + " and dpnId={}", vpnName, rd, id, dpnId);
246 List<VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
247 if (vpnInterfaces == null) {
248 LOG.error("Could not find vpnInterfaces for DpnInVpn map for VPN=[name={} rd={} id={}] and dpnId={}",
249 vpnName, rd, id, dpnId);
253 VpnInterfaces currVpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
254 if (vpnInterfaces.remove(currVpnInterface)) {
255 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
256 if (vpnInterfaces.isEmpty()) {
257 List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
258 VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setVpnInterfaces(null);
259 if (ipAddresses == null || ipAddresses.isEmpty()) {
260 dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
261 lastDpnOnVpn = Boolean.TRUE;
263 LOG.error("removeOrUpdateVpnToDpnList: vpn interfaces are empty but ip addresses are present"
264 + " for the vpn {} in dpn {} interface {}", vpnName, dpnId, intfName);
266 LOG.debug("removeOrUpdateVpnToDpnList: Removing vpn footprint for vpn {} vpnId {} interface {},"
267 + " on dpn {}", vpnName, vpnName, intfName, dpnId);
268 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(),
269 WriteTransaction.CREATE_MISSING_PARENTS);
272 writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
273 id.child(VpnInterfaces.class, new VpnInterfacesKey(intfName)));
274 LOG.debug("removeOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} interface {},"
275 + " on dpn {}", vpnName, vpnName, intfName, dpnId);
278 writeTxn.submit().get();
279 } catch (InterruptedException | ExecutionException e) {
280 LOG.error("removeOrUpdateVpnToDpnList: Error removing from dpnToVpnList for vpn {} vpnId {}"
281 + " interface {} dpn {}", vpnName, vpnId, intfName, dpnId, e);
282 throw new RuntimeException(e.getMessage());
285 } // Ends synchronized block
286 LOG.info("removeOrUpdateVpnToDpnList: Updated/Removed vpn footprint for vpn {} vpnId {} interface {},"
287 + " on dpn {}", vpnName, vpnName, intfName, dpnId);
290 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd,
291 new DpnEnterExitVpnWorker(dpnId, vpnName, rd, false /* exited */));
292 LOG.info("removeOrUpdateVpnToDpnList: Sent cleanup event for dpn {} in VPN {} vpnId {} interface {}", dpnId,
293 vpnName, vpnId, intfName);
297 private void removeOrUpdateVpnToDpnListForIpAddress(long vpnId, String rd, BigInteger dpnId,
298 ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
299 Boolean lastDpnOnVpn = Boolean.FALSE;
300 synchronized (vpnName.intern()) {
301 InstanceIdentifier<VpnToDpnList> id = VpnUtil.getVpnToDpnListIdentifier(rd, dpnId);
302 VpnToDpnList dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
303 if (dpnInVpn == null) {
304 LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} rd={} id={}]"
305 + " and dpnId={}", vpnName, rd, id, dpnId);
308 List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
309 if (ipAddresses == null) {
310 LOG.error("Could not find ipAddresses for DpnInVpn map for VPN=[name={} rd={} id={}] and dpnId={}",
311 vpnName, rd, id, dpnId);
315 IpAddresses currIpAddress = new IpAddressesBuilder()
316 .setKey(new IpAddressesKey(ipAddressSourceValuePair.getValue()))
317 .setIpAddressSource(ipAddressSourceValuePair.getKey()).build();
318 if (ipAddresses.remove(currIpAddress)) {
319 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
320 if (ipAddresses.isEmpty()) {
321 List<VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
322 VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setIpAddresses(null);
323 if (vpnInterfaces == null || vpnInterfaces.isEmpty()) {
324 dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
325 lastDpnOnVpn = Boolean.TRUE;
327 LOG.warn("ip addresses are empty but vpn interfaces are present for the vpn {} in dpn {}",
330 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(), true);
333 writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
334 id.child(IpAddresses.class, new IpAddressesKey(ipAddressSourceValuePair.getValue())));
337 writeTxn.submit().get();
338 } catch (InterruptedException | ExecutionException e) {
339 LOG.error("Error removing from dpnToVpnList for vpn {} Ipaddress {} dpn {}", vpnName,
340 ipAddressSourceValuePair.getValue(), dpnId, e);
341 throw new RuntimeException(e.getMessage());
344 } // Ends synchronized block
347 LOG.debug("Sending cleanup event for dpn {} in VPN {}", dpnId, vpnName);
348 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd,
349 new DpnEnterExitVpnWorker(dpnId, vpnName, rd, false /* exited */));
353 private void publishAddNotification(final BigInteger dpnId, final String vpnName, final String rd) {
354 LOG.debug("publishAddNotification: Sending notification for add dpn {} in vpn {} rd {} event ", dpnId, vpnName,
356 AddEventData data = new AddEventDataBuilder().setVpnName(vpnName).setRd(rd).setDpnId(dpnId).build();
357 AddDpnEvent event = new AddDpnEventBuilder().setAddEventData(data).build();
358 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
359 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
361 public void onFailure(Throwable error) {
362 LOG.error("publishAddNotification: Error in notifying listeners for add dpn {} in vpn {} rd {} event ",
363 dpnId, vpnName, rd, error);
367 public void onSuccess(Object arg) {
368 LOG.info("publishAddNotification: Successful in notifying listeners for add dpn {} in vpn {} rd {}"
369 + " event ", dpnId, vpnName, rd);
374 private void publishRemoveNotification(final BigInteger dpnId, final String vpnName, final String rd) {
375 LOG.debug("publishRemoveNotification: Sending notification for remove dpn {} in vpn {} rd {} event ", dpnId,
377 RemoveEventData data = new RemoveEventDataBuilder().setVpnName(vpnName).setRd(rd).setDpnId(dpnId).build();
378 RemoveDpnEvent event = new RemoveDpnEventBuilder().setRemoveEventData(data).build();
379 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
380 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
382 public void onFailure(Throwable error) {
383 LOG.error("publishRemoveNotification: Error in notifying listeners for remove dpn {} in vpn {} rd {}"
384 + " event ", dpnId, vpnName, rd, error);
388 public void onSuccess(Object arg) {
389 LOG.info("publishRemoveNotification: Successful in notifying listeners for remove dpn {} in vpn {}"
390 + " rd {} event ", dpnId, vpnName, rd);
395 private void publishInterfaceAddedToVpnNotification(String interfaceName, BigInteger dpnId, String vpnName,
397 LOG.debug("publishInterfaceAddedToVpnNotification: Sending notification for addition of interface {} on dpn {}"
398 + " for vpn {}", interfaceName, dpnId, vpnName);
399 AddInterfaceEventData data = new AddInterfaceEventDataBuilder().setInterfaceName(interfaceName).setVpnId(vpnId)
400 .setDpnId(dpnId).build();
401 AddInterfaceToDpnOnVpnEvent event = new AddInterfaceToDpnOnVpnEventBuilder().setAddInterfaceEventData(data)
403 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
404 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
406 public void onFailure(Throwable error) {
407 LOG.warn("publishInterfaceAddedToVpnNotification: Error in notifying listeners for add interface {}"
408 + " on dpn {} in vpn {} event ", interfaceName, dpnId, vpnName, error);
412 public void onSuccess(Object arg) {
413 LOG.trace("publishInterfaceAddedToVpnNotification: Successful in notifying listeners for add"
414 + " interface {} on dpn {} in vpn {} event ", interfaceName, dpnId, vpnName);
419 private void publishInterfaceRemovedFromVpnNotification(String interfaceName, BigInteger dpnId, String vpnName,
421 LOG.debug("publishInterfaceAddedToVpnNotification: Sending notification for removal of interface {}"
422 + " from dpn {} for vpn {}", interfaceName, dpnId, vpnName);
423 RemoveInterfaceEventData data = new RemoveInterfaceEventDataBuilder().setInterfaceName(interfaceName)
424 .setVpnId(vpnId).setDpnId(dpnId).build();
425 RemoveInterfaceFromDpnOnVpnEvent event = new RemoveInterfaceFromDpnOnVpnEventBuilder()
426 .setRemoveInterfaceEventData(data).build();
427 final ListenableFuture<?> eventFuture = notificationPublishService.offerNotification(event);
428 Futures.addCallback(eventFuture, new FutureCallback<Object>() {
430 public void onFailure(Throwable error) {
432 "publishInterfaceAddedToVpnNotification: Error in notifying listeners"
433 + " for removing interface {} from dpn {} in vpn {} event ",
434 interfaceName, dpnId, vpnName, error);
438 public void onSuccess(Object arg) {
439 LOG.trace("publishInterfaceAddedToVpnNotification: Successful in notifying listeners for removing"
440 + " interface {} from dpn {} in vpn {} event ", interfaceName, dpnId, vpnName);
446 * JobCallback class is used as a future callback for main and rollback workers
447 * to handle success and failure.
449 private class DpnEnterExitVpnWorker implements FutureCallback<List<Void>> {
450 private final Logger log = LoggerFactory.getLogger(DpnEnterExitVpnWorker.class);
456 DpnEnterExitVpnWorker(BigInteger dpnId, String vpnName, String rd, boolean entered) {
457 this.entered = entered;
459 this.vpnName = vpnName;
464 * This implies that all the future instances have returned success. -- TODO:
468 public void onSuccess(List<Void> voids) {
470 publishAddNotification(dpnId, vpnName, rd);
471 log.info("onSuccess: FootPrint established for vpn {} rd {} on dpn {}", vpnName, rd, dpnId);
473 publishRemoveNotification(dpnId, vpnName, rd);
474 log.info("onSuccess: FootPrint cleared for vpn {} rd {} on dpn {}", vpnName, rd, dpnId);
479 * This method is used to handle failure callbacks. If more retry needed, the
480 * retrycount is decremented and mainworker is executed again. After retries
481 * completed, rollbackworker is executed. If rollbackworker fails, this is a
482 * double-fault. Double fault is logged and ignored.
485 public void onFailure(Throwable throwable) {
486 log.error("onFailure: Failed to establish/clear footprint for vpn {} rd {} on dpn {} ", vpnName, rd, dpnId,
491 boolean isVpnFootPrintCleared(VpnInstanceOpDataEntry vpnInstanceOpData) {
492 return vpnInstanceOpData.getVpnToDpnList() == null || vpnInstanceOpData.getVpnToDpnList().isEmpty();