2 * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.vpnmanager;
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.CheckedFuture;
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.ThreadFactoryBuilder;
16 import java.util.ArrayList;
17 import java.util.List;
18 import java.util.concurrent.Callable;
19 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.concurrent.ConcurrentMap;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.ExecutorService;
23 import java.util.concurrent.Executors;
24 import java.util.concurrent.ThreadFactory;
25 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
26 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
27 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
28 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
31 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
32 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
33 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
34 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
35 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
36 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
37 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
38 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnTargetsBuilder;
44 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.vpntargets.VpnTargetBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTargetKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.Vpn;
49 import org.opendaylight.yangtools.concepts.ListenerRegistration;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
54 public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase<VpnInstance, VpnInstanceListener>
55 implements AutoCloseable {
56 private static final Logger LOG = LoggerFactory.getLogger(VpnInstanceListener.class);
57 private ListenerRegistration<DataChangeListener> listenerRegistration;
58 private final DataBroker dataBroker;
59 private final IBgpManager bgpManager;
60 private final IdManagerService idManager;
61 private final VpnInterfaceManager vpnInterfaceManager;
62 private final IFibManager fibManager;
63 private static final ThreadFactory threadFactory = new ThreadFactoryBuilder()
64 .setNameFormat("NV-VpnMgr-%d").build();
65 private ExecutorService executorService = Executors.newSingleThreadExecutor(threadFactory);
66 private ConcurrentMap<String, Runnable> vpnOpMap = new ConcurrentHashMap<String, Runnable>();
68 public VpnInstanceListener(final DataBroker dataBroker, final IBgpManager bgpManager,
69 final IdManagerService idManager,
70 final VpnInterfaceManager vpnInterfaceManager,
71 final IFibManager fibManager) {
72 super(VpnInstance.class, VpnInstanceListener.class);
73 this.dataBroker = dataBroker;
74 this.bgpManager = bgpManager;
75 this.idManager = idManager;
76 this.vpnInterfaceManager = vpnInterfaceManager;
77 this.fibManager = fibManager;
81 LOG.info("{} start", getClass().getSimpleName());
82 registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
86 protected InstanceIdentifier<VpnInstance> getWildCardPath() {
87 return InstanceIdentifier.create(VpnInstances.class).child(VpnInstance.class);
91 protected VpnInstanceListener getDataTreeChangeListener() {
92 return VpnInstanceListener.this;
95 void notifyTaskIfRequired(String vpnName) {
96 Runnable notifyTask = vpnOpMap.remove(vpnName);
97 if (notifyTask == null) {
98 LOG.trace("VpnInstanceListener update: No Notify Task queued for vpnName {}", vpnName);
101 executorService.execute(notifyTask);
104 private void waitForOpRemoval(String rd, String vpnName) {
105 //wait till DCN for update on VPN Instance Op Data signals that vpn interfaces linked to this vpn instance is zero
106 //TODO(vpnteam): Entire code would need refactoring to listen only on the parent object - VPNInstance
107 VpnInstanceOpDataEntry vpnOpEntry = null;
109 Long currentIntfCount = 0L;
110 Integer retryCount = 3;
111 long timeout = VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS;
112 Optional<VpnInstanceOpDataEntry> vpnOpValue = null;
113 vpnOpValue = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
114 VpnUtil.getVpnInstanceOpDataIdentifier(rd));
116 if ((vpnOpValue != null) && (vpnOpValue.isPresent())) {
117 vpnOpEntry = vpnOpValue.get();
118 List<VpnToDpnList> dpnToVpns = vpnOpEntry.getVpnToDpnList();
119 if (dpnToVpns != null) {
120 for (VpnToDpnList dpn : dpnToVpns) {
121 if (dpn.getVpnInterfaces() != null) {
122 intfCount = intfCount + dpn.getVpnInterfaces().size();
126 //intfCount = vpnOpEntry.getVpnInterfaceCount();
129 // Minimum wait time of 5 seconds for one VPN Interface clearance (inclusive of full trace on)
130 timeout = intfCount * VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS;
131 // Maximum wait time of 90 seconds for all VPN Interfaces clearance (inclusive of full trace on)
132 if (timeout > VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS) {
133 timeout = VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS;
135 LOG.info("VPNInstance removal count of interface at {} for for rd {}, vpnname {}",
136 intfCount, rd, vpnName);
138 LOG.info("VPNInstance removal thread waiting for {} seconds for rd {}, vpnname {}",
139 (timeout / 1000), rd, vpnName);
142 Thread.sleep(timeout);
143 } catch (InterruptedException e) {
146 // Check current interface count
147 vpnOpValue = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
148 VpnUtil.getVpnInstanceOpDataIdentifier(rd));
149 if ((vpnOpValue != null) && (vpnOpValue.isPresent())) {
150 vpnOpEntry = vpnOpValue.get();
151 dpnToVpns = vpnOpEntry.getVpnToDpnList();
152 currentIntfCount = 0L;
153 if (dpnToVpns != null) {
154 for (VpnToDpnList dpn : dpnToVpns) {
155 if (dpn.getVpnInterfaces() != null) {
156 currentIntfCount = currentIntfCount + dpn.getVpnInterfaces().size();
160 if ((currentIntfCount == 0) || (currentIntfCount >= intfCount)) {
161 // Either the FibManager completed its job to cleanup all vpnInterfaces in VPN
163 // There is no progress by FibManager in removing all the interfaces even after good time!
164 // In either case, let us quit and take our chances.
165 //TODO(vpnteam): L3VPN refactoring to take care of this case.
166 if ((dpnToVpns == null) || dpnToVpns.size() <= 0) {
167 LOG.info("VPN Instance vpn {} rd {} ready for removal, exiting wait loop", vpnName, rd);
170 if (retryCount > 0) {
172 LOG.info("Retrying clearing vpn with vpnname {} rd {} since current interface count {} ", vpnName, rd, currentIntfCount);
173 if (currentIntfCount > 0) {
174 intfCount = currentIntfCount;
176 LOG.info("Current interface count is zero, but instance Op for vpn {} and rd {} not cleared yet. Waiting for 5 more seconds.", vpnName, rd);
180 LOG.info("VPNInstance bailing out of wait loop as current interface count is {} and max retries exceeded for for vpnName {}, rd {}",
181 currentIntfCount, vpnName, rd);
187 // There is no VPNOPEntry. Something else happened on the system !
188 // So let us quit and take our chances.
189 //TODO(vpnteam): L3VPN refactoring to take care of this case.
194 LOG.info("Returned out of waiting for Op Data removal for rd {}, vpnname {}", rd, vpnName);
197 protected void remove(InstanceIdentifier<VpnInstance> identifier, VpnInstance del) {
198 LOG.trace("Remove VPN event key: {}, value: {}", identifier, del);
199 final String vpnName = del.getVpnInstanceName();
200 final String rd = del.getIpv4Family().getRouteDistinguisher();
201 final long vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
202 Optional<VpnInstanceOpDataEntry> vpnOpValue = null;
204 //TODO(vpnteam): Entire code would need refactoring to listen only on the parent object - VPNInstance
206 if ((rd != null) && (!rd.isEmpty())) {
207 vpnOpValue = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
208 VpnUtil.getVpnInstanceOpDataIdentifier(rd));
210 vpnOpValue = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
211 VpnUtil.getVpnInstanceOpDataIdentifier(vpnName));
213 } catch (Exception e) {
214 LOG.error("Exception when attempting to retrieve VpnInstanceOpDataEntry for VPN {}. ", vpnName, e);
218 if (vpnOpValue == null || !vpnOpValue.isPresent()) {
219 LOG.error("Unable to retrieve VpnInstanceOpDataEntry for VPN {}. ", vpnName);
223 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
224 dataStoreCoordinator.enqueueJob("VPN-" + vpnName,
225 new DeleteVpnInstanceWorker(idManager, dataBroker, del));
228 private class DeleteVpnInstanceWorker implements Callable<List<ListenableFuture<Void>>> {
229 IdManagerService idManager;
231 VpnInstance vpnInstance;
233 public DeleteVpnInstanceWorker(IdManagerService idManager,
236 this.idManager = idManager;
237 this.broker = broker;
238 this.vpnInstance = value;
242 public List<ListenableFuture<Void>> call() throws Exception {
243 final String vpnName = vpnInstance.getVpnInstanceName();
244 final String rd = vpnInstance.getIpv4Family().getRouteDistinguisher();
245 final long vpnId = VpnUtil.getVpnId(broker, vpnName);
246 WriteTransaction writeTxn = broker.newWriteOnlyTransaction();
247 if ((rd != null) && (!rd.isEmpty())) {
248 waitForOpRemoval(rd, vpnName);
250 waitForOpRemoval(vpnName, vpnName);
253 // Clean up VpnInstanceToVpnId from Config DS
254 VpnUtil.removeVpnIdToVpnInstance(broker, vpnId, writeTxn);
255 VpnUtil.removeVpnInstanceToVpnId(broker, vpnName, writeTxn);
256 LOG.trace("Removed vpnIdentifier for rd{} vpnname {}", rd, vpnName);
258 synchronized (vpnName.intern()) {
259 fibManager.removeVrfTable(broker, rd, null);
262 bgpManager.deleteVrf(rd, false);
263 } catch (Exception e) {
264 LOG.error("Exception when removing VRF from BGP for RD {} in VPN {} exception " + e, rd, vpnName);
267 // Clean up VPNExtraRoutes Operational DS
268 InstanceIdentifier<Vpn> vpnToExtraroute = VpnUtil.getVpnToExtrarouteIdentifier(rd);
269 Optional<Vpn> optVpnToExtraroute = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, vpnToExtraroute);
270 if (optVpnToExtraroute.isPresent()) {
271 VpnUtil.removeVpnExtraRouteForVpn(broker, rd, writeTxn);
274 // Clean up VPNInstanceOpDataEntry
275 VpnUtil.removeVpnOpInstance(broker, rd, writeTxn);
277 // Clean up FIB Entries Config DS
278 synchronized (vpnName.intern()) {
279 fibManager.removeVrfTable(broker, vpnName, null);
281 // Clean up VPNExtraRoutes Operational DS
282 InstanceIdentifier<Vpn> vpnToExtraroute = VpnUtil.getVpnToExtrarouteIdentifier(vpnName);
283 Optional<Vpn> optVpnToExtraroute = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, vpnToExtraroute);
284 if (optVpnToExtraroute.isPresent()) {
285 VpnUtil.removeVpnExtraRouteForVpn(broker, vpnName, writeTxn);
288 // Clean up VPNInstanceOpDataEntry
289 VpnUtil.removeVpnOpInstance(broker, vpnName, writeTxn);
291 // Clean up PrefixToInterface Operational DS
292 VpnUtil.removePrefixToInterfaceForVpnId(broker, vpnId, writeTxn);
294 // Clean up L3NextHop Operational DS
295 VpnUtil.removeL3nexthopForVpnId(broker, vpnId, writeTxn);
297 // Release the ID used for this VPN back to IdManager
298 VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME, vpnName);
300 List<ListenableFuture<Void>> futures = new ArrayList<>();
301 futures.add(writeTxn.submit());
307 protected void update(InstanceIdentifier<VpnInstance> identifier,
308 VpnInstance original, VpnInstance update) {
309 LOG.trace("Update VPN event key: {}, value: {}", identifier, update);
313 protected void add(final InstanceIdentifier<VpnInstance> identifier, final VpnInstance value) {
314 LOG.trace("Add VPN event key: {}, value: {}", identifier, value);
315 final VpnAfConfig config = value.getIpv4Family();
316 final String rd = config.getRouteDistinguisher();
317 final String vpnName = value.getVpnInstanceName();
319 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
320 dataStoreCoordinator.enqueueJob("VPN-" + vpnName,
321 new AddVpnInstanceWorker(idManager, vpnInterfaceManager, dataBroker, value));
324 private class AddVpnInstanceWorker implements Callable<List<ListenableFuture<Void>>> {
325 IdManagerService idManager;
326 VpnInterfaceManager vpnInterfaceManager;
327 VpnInstance vpnInstance;
330 public AddVpnInstanceWorker(IdManagerService idManager,
331 VpnInterfaceManager vpnInterfaceManager,
334 this.idManager = idManager;
335 this.vpnInterfaceManager = vpnInterfaceManager;
336 this.broker = broker;
337 this.vpnInstance = value;
341 public List<ListenableFuture<Void>> call() throws Exception {
342 // If another renderer(for eg : CSS) needs to be supported, check can be performed here
343 // to call the respective helpers.
344 final VpnAfConfig config = vpnInstance.getIpv4Family();
345 final String rd = config.getRouteDistinguisher();
346 WriteTransaction writeConfigTxn = broker.newWriteOnlyTransaction();
347 WriteTransaction writeOperTxn = broker.newWriteOnlyTransaction();
348 addVpnInstance(vpnInstance, writeConfigTxn, writeOperTxn);
349 CheckedFuture<Void, TransactionCommitFailedException> checkFutures = writeOperTxn.submit();
352 } catch (InterruptedException | ExecutionException e) {
353 LOG.error("Error creating vpn {} ", vpnInstance.getVpnInstanceName());
354 throw new RuntimeException(e.getMessage());
356 List<ListenableFuture<Void>> futures = new ArrayList<>();
357 futures.add(writeConfigTxn.submit());
358 ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
360 Futures.addCallback(listenableFuture,
361 new AddBgpVrfWorker(config , vpnInstance.getVpnInstanceName()));
367 private void addVpnInstance(VpnInstance value, WriteTransaction writeConfigTxn,
368 WriteTransaction writeOperTxn) {
369 VpnAfConfig config = value.getIpv4Family();
370 String rd = config.getRouteDistinguisher();
371 String vpnInstanceName = value.getVpnInstanceName();
373 long vpnId = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, vpnInstanceName);
375 LOG.error("Unable to fetch label from Id Manager. Bailing out of adding operational data for Vpn Instance {}", value.getVpnInstanceName());
378 LOG.trace("VPN instance to ID generated.");
379 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance
380 vpnInstanceToVpnId = VpnUtil.getVpnInstanceToVpnId(vpnInstanceName, vpnId, (rd != null) ? rd
383 if (writeConfigTxn != null) {
384 writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION,
385 VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnInstanceName),
386 vpnInstanceToVpnId, true);
388 TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
389 VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnInstanceName),
390 vpnInstanceToVpnId, TransactionUtil.DEFAULT_CALLBACK);
393 VpnIds vpnIdToVpnInstance = VpnUtil.getVpnIdToVpnInstance(vpnId, value.getVpnInstanceName(),
394 (rd != null) ? rd : value.getVpnInstanceName(), (rd != null)/*isExternalVpn*/);
396 if (writeConfigTxn != null) {
397 writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION,
398 VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId),
399 vpnIdToVpnInstance, true);
401 TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
402 VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId),
403 vpnIdToVpnInstance, TransactionUtil.DEFAULT_CALLBACK);
407 String cachedTransType = fibManager.getConfTransType();
408 LOG.trace("Value for confTransportType is " + cachedTransType);
409 if (cachedTransType.equals("Invalid")) {
411 fibManager.setConfTransType("L3VPN", "VXLAN");
412 } catch (Exception e) {
413 LOG.trace("Exception caught setting the cached value for transportType");
414 LOG.error(e.getMessage());
417 LOG.trace(":cached val is neither unset/invalid. NO-op.");
419 } catch (Exception e) {
420 LOG.error(e.getMessage());
424 VpnInstanceOpDataEntryBuilder builder =
425 new VpnInstanceOpDataEntryBuilder().setVrfId(vpnInstanceName).setVpnId(vpnId)
426 .setVpnInstanceName(vpnInstanceName);
427 if (writeOperTxn != null) {
428 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
429 VpnUtil.getVpnInstanceOpDataIdentifier(vpnInstanceName),
430 builder.build(), true);
432 TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
433 VpnUtil.getVpnInstanceOpDataIdentifier(vpnInstanceName),
434 builder.build(), TransactionUtil.DEFAULT_CALLBACK);
437 VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder()
438 .setVrfId(rd).setVpnId(vpnId).setVpnInstanceName(vpnInstanceName);
440 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget> opVpnTargetList = new ArrayList<>();
441 VpnTargets vpnTargets = config.getVpnTargets();
442 if (vpnTargets != null) {
443 List<VpnTarget> vpnTargetList = vpnTargets.getVpnTarget();
444 if (vpnTargetList != null) {
445 for (VpnTarget vpnTarget : vpnTargetList) {
446 VpnTargetBuilder vpnTargetBuilder = new VpnTargetBuilder().setKey(new VpnTargetKey(vpnTarget.getKey().getVrfRTValue()))
447 .setVrfRTType(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
448 .instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget.VrfRTType
449 .forValue(vpnTarget.getVrfRTType().getIntValue())).setVrfRTValue(vpnTarget.getVrfRTValue());
450 opVpnTargetList.add(vpnTargetBuilder.build());
454 VpnTargetsBuilder vpnTargetsBuilder = new VpnTargetsBuilder().setVpnTarget(opVpnTargetList);
455 builder.setVpnTargets(vpnTargetsBuilder.build());
457 if (writeOperTxn != null) {
458 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
459 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
460 builder.build(), true);
462 TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
463 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
464 builder.build(), TransactionUtil.DEFAULT_CALLBACK);
470 private class AddBgpVrfWorker implements FutureCallback<List<Void>> {
474 public AddBgpVrfWorker(VpnAfConfig config, String vpnName) {
475 this.config = config;
476 this.vpnName = vpnName;
481 * This implies that all the future instances have returned success. -- TODO: Confirm this
484 public void onSuccess(List<Void> voids) {
485 String rd = config.getRouteDistinguisher();
487 List<VpnTarget> vpnTargetList = config.getVpnTargets().getVpnTarget();
489 List<String> ertList = new ArrayList<String>();
490 List<String> irtList = new ArrayList<String>();
492 for (VpnTarget vpnTarget : vpnTargetList) {
493 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
494 ertList.add(vpnTarget.getVrfRTValue());
496 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
497 irtList.add(vpnTarget.getVrfRTValue());
499 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
500 ertList.add(vpnTarget.getVrfRTValue());
501 irtList.add(vpnTarget.getVrfRTValue());
506 bgpManager.addVrf(rd, irtList, ertList);
507 } catch (Exception e) {
508 LOG.error("Exception when adding VRF to BGP", e);
511 vpnInterfaceManager.handleVpnsExportingRoutes(this.vpnName, rd);
517 * This method is used to handle failure callbacks.
518 * If more retry needed, the retrycount is decremented and mainworker is executed again.
519 * After retries completed, rollbackworker is executed.
520 * If rollbackworker fails, this is a double-fault. Double fault is logged and ignored.
524 public void onFailure(Throwable throwable) {
525 LOG.warn("Job: failed with exception: ", throwable);
529 public boolean isVPNConfigured() {
531 InstanceIdentifier<VpnInstances> vpnsIdentifier =
532 InstanceIdentifier.builder(VpnInstances.class).build();
533 Optional<VpnInstances> optionalVpns = TransactionUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
535 if (!optionalVpns.isPresent() ||
536 optionalVpns.get().getVpnInstance() == null ||
537 optionalVpns.get().getVpnInstance().isEmpty()) {
538 LOG.trace("No VPNs configured.");
541 LOG.trace("VPNs are configured on the system.");
545 protected VpnInstanceOpDataEntry getVpnInstanceOpData(String rd) {
546 InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(rd);
547 Optional<VpnInstanceOpDataEntry> vpnInstanceOpData =
548 TransactionUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
549 if(vpnInstanceOpData.isPresent()) {
550 return vpnInstanceOpData.get();