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 java.util.ArrayList;
16 import java.util.List;
17 import java.util.concurrent.Callable;
18 import java.util.concurrent.ExecutionException;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
23 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
24 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
25 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
26 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
27 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
28 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
29 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
30 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
31 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
32 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
33 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnTargetsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTargetBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTargetKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.Vpn;
43 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
47 public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase<VpnInstance, VpnInstanceListener>
48 implements AutoCloseable {
49 private static final Logger LOG = LoggerFactory.getLogger(VpnInstanceListener.class);
50 private final DataBroker dataBroker;
51 private final IBgpManager bgpManager;
52 private final IdManagerService idManager;
53 private final VpnInterfaceManager vpnInterfaceManager;
54 private final IFibManager fibManager;
55 private final VpnOpDataSyncer vpnOpDataNotifier;
57 public VpnInstanceListener(final DataBroker dataBroker, final IBgpManager bgpManager,
58 final IdManagerService idManager, final VpnInterfaceManager vpnInterfaceManager, final IFibManager fibManager,
59 final VpnOpDataSyncer vpnOpDataSyncer) {
60 super(VpnInstance.class, VpnInstanceListener.class);
61 this.dataBroker = dataBroker;
62 this.bgpManager = bgpManager;
63 this.idManager = idManager;
64 this.vpnInterfaceManager = vpnInterfaceManager;
65 this.fibManager = fibManager;
66 this.vpnOpDataNotifier = vpnOpDataSyncer;
70 LOG.info("{} start", getClass().getSimpleName());
71 registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
75 protected InstanceIdentifier<VpnInstance> getWildCardPath() {
76 return InstanceIdentifier.create(VpnInstances.class).child(VpnInstance.class);
80 protected VpnInstanceListener getDataTreeChangeListener() {
81 return VpnInstanceListener.this;
84 private void waitForOpRemoval(String rd, String vpnName) {
85 //wait till DCN for update on VPN Instance Op Data signals that vpn interfaces linked to this vpn instance is
87 //TODO(vpnteam): Entire code would need refactoring to listen only on the parent object - VPNInstance
88 VpnInstanceOpDataEntry vpnOpEntry = null;
90 Long currentIntfCount = 0L;
91 Integer retryCount = 3;
92 long timeout = VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS;
93 Optional<VpnInstanceOpDataEntry> vpnOpValue = null;
94 vpnOpValue = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
95 VpnUtil.getVpnInstanceOpDataIdentifier(rd));
97 if ((vpnOpValue != null) && (vpnOpValue.isPresent())) {
98 vpnOpEntry = vpnOpValue.get();
99 List<VpnToDpnList> dpnToVpns = vpnOpEntry.getVpnToDpnList();
100 if (dpnToVpns != null) {
101 for (VpnToDpnList dpn : dpnToVpns) {
102 if (dpn.getVpnInterfaces() != null) {
103 intfCount = intfCount + dpn.getVpnInterfaces().size();
107 //intfCount = vpnOpEntry.getVpnInterfaceCount();
110 // Minimum wait time of 5 seconds for one VPN Interface clearance (inclusive of full trace on)
111 timeout = intfCount * VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS;
112 // Maximum wait time of 90 seconds for all VPN Interfaces clearance (inclusive of full trace on)
113 if (timeout > VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS) {
114 timeout = VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS;
116 LOG.info("VPNInstance removal count of interface at {} for for rd {}, vpnname {}",
117 intfCount, rd, vpnName);
119 LOG.info("VPNInstance removal thread waiting for {} seconds for rd {}, vpnname {}",
120 (timeout / 1000), rd, vpnName);
123 Thread.sleep(timeout);
124 } catch (InterruptedException e) {
128 // Check current interface count
129 vpnOpValue = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
130 VpnUtil.getVpnInstanceOpDataIdentifier(rd));
131 if ((vpnOpValue != null) && (vpnOpValue.isPresent())) {
132 vpnOpEntry = vpnOpValue.get();
133 dpnToVpns = vpnOpEntry.getVpnToDpnList();
134 currentIntfCount = 0L;
135 if (dpnToVpns != null) {
136 for (VpnToDpnList dpn : dpnToVpns) {
137 if (dpn.getVpnInterfaces() != null) {
138 currentIntfCount = currentIntfCount + dpn.getVpnInterfaces().size();
142 if ((currentIntfCount == 0) || (currentIntfCount >= intfCount)) {
143 // Either the FibManager completed its job to cleanup all vpnInterfaces in VPN
145 // There is no progress by FibManager in removing all the interfaces even after good time!
146 // In either case, let us quit and take our chances.
147 //TODO(vpnteam): L3VPN refactoring to take care of this case.
148 if ((dpnToVpns == null) || dpnToVpns.size() <= 0) {
149 LOG.info("VPN Instance vpn {} rd {} ready for removal, exiting wait loop", vpnName, rd);
152 if (retryCount > 0) {
155 "Retrying clearing vpn with vpnname {} rd {} since current interface count {} ",
156 vpnName, rd, currentIntfCount);
157 if (currentIntfCount > 0) {
158 intfCount = currentIntfCount;
161 "Current interface count is zero, but instance Op for vpn {} and rd {} not "
162 + "cleared yet. Waiting for 5 more seconds.",
168 "VPNInstance bailing out of wait loop as current interface count is {} and max "
169 + "retries exceeded for for vpnName {}, rd {}",
170 currentIntfCount, vpnName, rd);
175 LOG.info("Retrying clearing because not all vpnInterfaces removed : current interface count {},"
176 + " initial count {} for rd {}, vpnname {}", currentIntfCount, intfCount, rd, vpnName);
177 intfCount = currentIntfCount;
180 // There is no VPNOPEntry. Something else happened on the system !
181 // So let us quit and take our chances.
182 //TODO(vpnteam): L3VPN refactoring to take care of this case.
183 LOG.error("VpnInstanceOpData is not present in the operational DS for rd {}, vpnname {}", rd,
189 LOG.info("Returned out of waiting for Op Data removal for rd {}, vpnname {}", rd, vpnName);
193 protected void remove(InstanceIdentifier<VpnInstance> identifier, VpnInstance del) {
194 LOG.trace("Remove VPN event key: {}, value: {}", identifier, del);
195 final String vpnName = del.getVpnInstanceName();
196 final String rd = del.getIpv4Family().getRouteDistinguisher();
197 Optional<VpnInstanceOpDataEntry> vpnOpValue = null;
199 //TODO(vpnteam): Entire code would need refactoring to listen only on the parent object - VPNInstance
201 if ((rd != null) && (!rd.isEmpty())) {
202 vpnOpValue = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL,
203 VpnUtil.getVpnInstanceOpDataIdentifier(rd));
205 vpnOpValue = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL,
206 VpnUtil.getVpnInstanceOpDataIdentifier(vpnName));
208 } catch (ReadFailedException e) {
209 LOG.error("Exception when attempting to retrieve VpnInstanceOpDataEntry for VPN {}. ", vpnName, e);
213 if (vpnOpValue == null || !vpnOpValue.isPresent()) {
214 LOG.error("Unable to retrieve VpnInstanceOpDataEntry for VPN {}. ", vpnName);
218 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
219 dataStoreCoordinator.enqueueJob("VPN-" + vpnName,
220 new DeleteVpnInstanceWorker(idManager, dataBroker, del));
223 private class DeleteVpnInstanceWorker implements Callable<List<ListenableFuture<Void>>> {
224 IdManagerService idManager;
226 VpnInstance vpnInstance;
228 DeleteVpnInstanceWorker(IdManagerService idManager,
231 this.idManager = idManager;
232 this.broker = broker;
233 this.vpnInstance = value;
236 // TODO Clean up the exception handling
237 @SuppressWarnings("checkstyle:IllegalCatch")
239 public List<ListenableFuture<Void>> call() {
240 final String vpnName = vpnInstance.getVpnInstanceName();
241 final String rd = vpnInstance.getIpv4Family().getRouteDistinguisher();
242 final long vpnId = VpnUtil.getVpnId(broker, vpnName);
243 WriteTransaction writeTxn = broker.newWriteOnlyTransaction();
244 if ((rd != null) && (!rd.isEmpty())) {
245 waitForOpRemoval(rd, vpnName);
247 waitForOpRemoval(vpnName, vpnName);
250 // Clean up VpnInstanceToVpnId from Config DS
251 VpnUtil.removeVpnIdToVpnInstance(broker, vpnId, writeTxn);
252 VpnUtil.removeVpnInstanceToVpnId(broker, vpnName, writeTxn);
253 LOG.trace("Removed vpnIdentifier for rd{} vpnname {}", rd, vpnName);
255 synchronized (vpnName.intern()) {
256 fibManager.removeVrfTable(broker, rd, null);
259 bgpManager.deleteVrf(rd, false);
260 } catch (Exception e) {
261 LOG.error("Exception when removing VRF from BGP for RD {} in VPN {} exception " + e, rd, vpnName);
264 // Clean up VPNExtraRoutes Operational DS
265 InstanceIdentifier<Vpn> vpnToExtraroute = VpnUtil.getVpnToExtrarouteIdentifier(rd);
266 Optional<Vpn> optVpnToExtraroute =
267 VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, vpnToExtraroute);
268 if (optVpnToExtraroute.isPresent()) {
269 VpnUtil.removeVpnExtraRouteForVpn(broker, rd, writeTxn);
272 // Clean up VPNInstanceOpDataEntry
273 VpnUtil.removeVpnOpInstance(broker, rd, writeTxn);
275 // Clean up FIB Entries Config DS
276 synchronized (vpnName.intern()) {
277 fibManager.removeVrfTable(broker, vpnName, null);
279 // Clean up VPNExtraRoutes Operational DS
280 InstanceIdentifier<Vpn> vpnToExtraroute = VpnUtil.getVpnToExtrarouteIdentifier(vpnName);
281 Optional<Vpn> optVpnToExtraroute =
282 VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, vpnToExtraroute);
283 if (optVpnToExtraroute.isPresent()) {
284 VpnUtil.removeVpnExtraRouteForVpn(broker, vpnName, writeTxn);
287 // Clean up VPNInstanceOpDataEntry
288 VpnUtil.removeVpnOpInstance(broker, vpnName, writeTxn);
290 // Clean up PrefixToInterface Operational DS
291 VpnUtil.removePrefixToInterfaceForVpnId(broker, vpnId, writeTxn);
293 // Clean up L3NextHop Operational DS
294 VpnUtil.removeL3nexthopForVpnId(broker, vpnId, writeTxn);
296 // Release the ID used for this VPN back to IdManager
297 VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME, vpnName);
299 List<ListenableFuture<Void>> futures = new ArrayList<>();
300 futures.add(writeTxn.submit());
306 protected void update(InstanceIdentifier<VpnInstance> identifier,
307 VpnInstance original, VpnInstance update) {
308 LOG.trace("Update VPN event key: {}, value: {}", identifier, update);
312 protected void add(final InstanceIdentifier<VpnInstance> identifier, final VpnInstance value) {
313 LOG.trace("Add VPN event key: {}, value: {}", identifier, value);
314 final String vpnName = value.getVpnInstanceName();
316 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
317 dataStoreCoordinator.enqueueJob("VPN-" + vpnName,
318 new AddVpnInstanceWorker(idManager, vpnInterfaceManager, dataBroker, value));
321 private class AddVpnInstanceWorker implements Callable<List<ListenableFuture<Void>>> {
322 IdManagerService idManager;
323 VpnInterfaceManager vpnInterfaceManager;
324 VpnInstance vpnInstance;
327 AddVpnInstanceWorker(IdManagerService idManager,
328 VpnInterfaceManager vpnInterfaceManager,
331 this.idManager = idManager;
332 this.vpnInterfaceManager = vpnInterfaceManager;
333 this.broker = broker;
334 this.vpnInstance = value;
338 public List<ListenableFuture<Void>> call() throws Exception {
339 // If another renderer(for eg : CSS) needs to be supported, check can be performed here
340 // to call the respective helpers.
341 final VpnAfConfig config = vpnInstance.getIpv4Family();
342 WriteTransaction writeConfigTxn = broker.newWriteOnlyTransaction();
343 WriteTransaction writeOperTxn = broker.newWriteOnlyTransaction();
344 addVpnInstance(vpnInstance, writeConfigTxn, writeOperTxn);
345 CheckedFuture<Void, TransactionCommitFailedException> checkFutures = writeOperTxn.submit();
348 } catch (InterruptedException | ExecutionException e) {
349 LOG.error("Error creating vpn {} ", vpnInstance.getVpnInstanceName());
350 throw new RuntimeException(e.getMessage());
352 List<ListenableFuture<Void>> futures = new ArrayList<>();
353 futures.add(writeConfigTxn.submit());
354 ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
355 Futures.addCallback(listenableFuture,
356 new PostAddVpnInstanceWorker(config, vpnInstance.getVpnInstanceName()));
361 // TODO Clean up the exception handling
362 @SuppressWarnings("checkstyle:IllegalCatch")
363 private void addVpnInstance(VpnInstance value, WriteTransaction writeConfigTxn,
364 WriteTransaction writeOperTxn) {
365 VpnAfConfig config = value.getIpv4Family();
366 String rd = config.getRouteDistinguisher();
367 String vpnInstanceName = value.getVpnInstanceName();
369 long vpnId = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME, vpnInstanceName);
372 "Unable to fetch label from Id Manager. Bailing out of adding operational data for Vpn Instance {}",
373 value.getVpnInstanceName());
375 "Unable to fetch label from Id Manager. Bailing out of adding operational data for Vpn Instance {}",
376 value.getVpnInstanceName());
379 LOG.info("VPN Id {} generated for VpnInstanceName {}", vpnId, vpnInstanceName);
380 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance
381 vpnInstanceToVpnId = VpnUtil.getVpnInstanceToVpnId(vpnInstanceName, vpnId, (rd != null) ? rd
384 if (writeConfigTxn != null) {
385 writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION,
386 VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnInstanceName),
387 vpnInstanceToVpnId, true);
389 TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
390 VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnInstanceName),
391 vpnInstanceToVpnId, TransactionUtil.DEFAULT_CALLBACK);
394 VpnIds vpnIdToVpnInstance = VpnUtil.getVpnIdToVpnInstance(vpnId, value.getVpnInstanceName(),
395 (rd != null) ? rd : value.getVpnInstanceName(), (rd != null)/*isExternalVpn*/);
397 if (writeConfigTxn != null) {
398 writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION,
399 VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId),
400 vpnIdToVpnInstance, true);
402 TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
403 VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId),
404 vpnIdToVpnInstance, TransactionUtil.DEFAULT_CALLBACK);
408 String cachedTransType = fibManager.getConfTransType();
409 if (cachedTransType.equals("Invalid")) {
411 fibManager.setConfTransType("L3VPN", "VXLAN");
412 } catch (Exception e) {
413 LOG.error("Exception caught setting the L3VPN tunnel transportType", e);
416 LOG.trace("Configured tunnel transport type for L3VPN as {}", cachedTransType);
418 } catch (Exception e) {
419 LOG.error("Error when trying to retrieve tunnel transport type for L3VPN ", e);
423 VpnInstanceOpDataEntryBuilder builder =
424 new VpnInstanceOpDataEntryBuilder().setVrfId(vpnInstanceName).setVpnId(vpnId)
425 .setVpnInstanceName(vpnInstanceName);
426 if (writeOperTxn != null) {
427 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
428 VpnUtil.getVpnInstanceOpDataIdentifier(vpnInstanceName),
429 builder.build(), true);
431 TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
432 VpnUtil.getVpnInstanceOpDataIdentifier(vpnInstanceName),
433 builder.build(), TransactionUtil.DEFAULT_CALLBACK);
436 VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder()
437 .setVrfId(rd).setVpnId(vpnId).setVpnInstanceName(vpnInstanceName);
439 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
440 .instance.op.data.entry.vpntargets.VpnTarget>
441 opVpnTargetList = new ArrayList<>();
442 VpnTargets vpnTargets = config.getVpnTargets();
443 if (vpnTargets != null) {
444 List<VpnTarget> vpnTargetList = vpnTargets.getVpnTarget();
445 if (vpnTargetList != null) {
446 for (VpnTarget vpnTarget : vpnTargetList) {
447 VpnTargetBuilder vpnTargetBuilder =
448 new VpnTargetBuilder().setKey(new VpnTargetKey(vpnTarget.getKey().getVrfRTValue()))
449 .setVrfRTType(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
450 .instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget.VrfRTType
451 .forValue(vpnTarget.getVrfRTType().getIntValue())).setVrfRTValue(
452 vpnTarget.getVrfRTValue());
453 opVpnTargetList.add(vpnTargetBuilder.build());
457 VpnTargetsBuilder vpnTargetsBuilder = new VpnTargetsBuilder().setVpnTarget(opVpnTargetList);
458 builder.setVpnTargets(vpnTargetsBuilder.build());
460 if (writeOperTxn != null) {
461 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
462 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
463 builder.build(), true);
465 TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
466 VpnUtil.getVpnInstanceOpDataIdentifier(rd),
467 builder.build(), TransactionUtil.DEFAULT_CALLBACK);
470 LOG.info("VpnInstanceOpData populated successfully for vpn {} rd {}", vpnInstanceName, rd);
474 private class PostAddVpnInstanceWorker implements FutureCallback<List<Void>> {
478 PostAddVpnInstanceWorker(VpnAfConfig config, String vpnName) {
479 this.config = config;
480 this.vpnName = vpnName;
484 * This implies that all the future instances have returned success. -- TODO: Confirm this
487 public void onSuccess(List<Void> voids) {
489 if rd is null, then its either a router vpn instance (or) a vlan external network vpn instance.
490 if rd is non-null, then it is a bgpvpn instance
492 String rd = config.getRouteDistinguisher();
493 if ((rd == null) || addBgpVrf(voids)) {
495 vpnInterfaceManager.vpnInstanceIsReady(vpnName);
499 // TODO Clean up the exception handling
500 @SuppressWarnings("checkstyle:IllegalCatch")
501 private boolean addBgpVrf(List<Void> voids) {
502 String rd = config.getRouteDistinguisher();
503 List<VpnTarget> vpnTargetList = config.getVpnTargets().getVpnTarget();
505 List<String> ertList = new ArrayList<String>();
506 List<String> irtList = new ArrayList<String>();
508 if (vpnTargetList != null) {
509 for (VpnTarget vpnTarget : vpnTargetList) {
510 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
511 ertList.add(vpnTarget.getVrfRTValue());
513 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
514 irtList.add(vpnTarget.getVrfRTValue());
516 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
517 ertList.add(vpnTarget.getVrfRTValue());
518 irtList.add(vpnTarget.getVrfRTValue());
522 LOG.error("vpn target list is empty, cannot add BGP VPN {} VRF {}", this.vpnName, rd);
526 bgpManager.addVrf(rd, irtList, ertList);
527 } catch (Exception e) {
528 LOG.error("Exception when adding VRF to BGP", e);
531 vpnInterfaceManager.handleVpnsExportingRoutes(this.vpnName, rd);
535 private void notifyTask() {
536 vpnOpDataNotifier.notifyVpnOpDataReady(VpnOpDataSyncer.VpnOpDataType.vpnInstanceToId, vpnName);
537 vpnOpDataNotifier.notifyVpnOpDataReady(VpnOpDataSyncer.VpnOpDataType.vpnOpData, vpnName);
541 * This method is used to handle failure callbacks.
542 * If more retry needed, the retrycount is decremented and mainworker is executed again.
543 * After retries completed, rollbackworker is executed.
544 * If rollbackworker fails, this is a double-fault. Double fault is logged and ignored.
548 public void onFailure(Throwable throwable) {
549 LOG.error("Job for vpnInstance: {} failed with exception: {}", vpnName ,throwable);
550 vpnInterfaceManager.vpnInstanceFailed(vpnName);
554 public boolean isVPNConfigured() {
556 InstanceIdentifier<VpnInstances> vpnsIdentifier = InstanceIdentifier.builder(VpnInstances.class).build();
557 Optional<VpnInstances> optionalVpns = TransactionUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
559 if (!optionalVpns.isPresent()
560 || optionalVpns.get().getVpnInstance() == null
561 || optionalVpns.get().getVpnInstance().isEmpty()) {
562 LOG.trace("No VPNs configured.");
565 LOG.trace("VPNs are configured on the system.");
569 protected VpnInstanceOpDataEntry getVpnInstanceOpData(String rd) {
570 InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(rd);
571 Optional<VpnInstanceOpDataEntry> vpnInstanceOpData =
572 TransactionUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
573 if (vpnInstanceOpData.isPresent()) {
574 return vpnInstanceOpData.get();