<parent>
<groupId>org.opendaylight.netvirt</groupId>
- <artifactId>binding-parent</artifactId>
+ <artifactId>managed-tx-parent</artifactId>
<version>0.7.0-SNAPSHOT</version>
- <relativePath>../../commons/binding-parent</relativePath>
+ <relativePath>../../commons/managed-tx-parent</relativePath>
</parent>
<artifactId>vpnmanager-impl</artifactId>
import java.math.BigInteger;
import java.util.List;
+import java.util.Objects;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
private static final Logger LOG = LoggerFactory.getLogger(CentralizedSwitchChangeListener.class);
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final IVpnManager vpnManager;
private final ExternalRouterDataUtil externalRouterDataUtil;
ExternalRouterDataUtil externalRouterDataUtil) {
super(RouterToNaptSwitch.class, CentralizedSwitchChangeListener.class);
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.vpnManager = vpnManager;
this.externalRouterDataUtil = externalRouterDataUtil;
}
@Override
protected void remove(InstanceIdentifier<RouterToNaptSwitch> key, RouterToNaptSwitch routerToNaptSwitch) {
LOG.debug("Removing {}", routerToNaptSwitch);
- WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
- setupRouterGwFlows(routerToNaptSwitch, writeTx, NwConstants.DEL_FLOW);
- writeTx.submit();
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ setupRouterGwFlows(routerToNaptSwitch, tx, NwConstants.DEL_FLOW)), LOG,
+ "Error processing switch removal for {}", routerToNaptSwitch);
}
@Override
protected void update(InstanceIdentifier<RouterToNaptSwitch> key, RouterToNaptSwitch origRouterToNaptSwitch,
RouterToNaptSwitch updatedRouterToNaptSwitch) {
LOG.debug("Updating old {} new {}", origRouterToNaptSwitch, updatedRouterToNaptSwitch);
- if (updatedRouterToNaptSwitch.getPrimarySwitchId() != origRouterToNaptSwitch.getPrimarySwitchId()) {
- WriteTransaction removeTx = dataBroker.newWriteOnlyTransaction();
- setupRouterGwFlows(origRouterToNaptSwitch, removeTx, NwConstants.DEL_FLOW);
- removeTx.submit();
- WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
- setupRouterGwFlows(updatedRouterToNaptSwitch, writeTx, NwConstants.ADD_FLOW);
- writeTx.submit();
+ if (!Objects.equals(updatedRouterToNaptSwitch.getPrimarySwitchId(),
+ origRouterToNaptSwitch.getPrimarySwitchId())) {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ setupRouterGwFlows(origRouterToNaptSwitch, tx, NwConstants.DEL_FLOW);
+ setupRouterGwFlows(updatedRouterToNaptSwitch, tx, NwConstants.ADD_FLOW);
+ }), LOG, "Error updating switch {} to {}", origRouterToNaptSwitch, updatedRouterToNaptSwitch);
}
}
@Override
protected void add(InstanceIdentifier<RouterToNaptSwitch> key, RouterToNaptSwitch routerToNaptSwitch) {
LOG.debug("Adding {}", routerToNaptSwitch);
- WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
- setupRouterGwFlows(routerToNaptSwitch, writeTx, NwConstants.ADD_FLOW);
- writeTx.submit();
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ setupRouterGwFlows(routerToNaptSwitch, tx, NwConstants.ADD_FLOW)), LOG,
+ "Error processing switch addition for {}", routerToNaptSwitch);
}
@Override
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddDpnEvent;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AddInterfaceToDpnOnVpnEvent;
public class DpnInVpnChangeListener implements OdlL3vpnListener {
private static final Logger LOG = LoggerFactory.getLogger(DpnInVpnChangeListener.class);
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
@Inject
public DpnInVpnChangeListener(DataBroker dataBroker) {
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
}
@Override
}
}
if (flushDpnsOnVpn) {
- WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
- deleteDpn(vpnToDpnList, rd, writeTxn);
try {
- writeTxn.submit().get();
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> deleteDpn(vpnToDpnList, rd, tx)).get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("Error removing dpnToVpnList for vpn {} ", vpnName);
throw new RuntimeException(e.getMessage(), e);
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
public class FibEntriesListener extends AsyncDataTreeChangeListenerBase<VrfEntry, FibEntriesListener> {
private static final Logger LOG = LoggerFactory.getLogger(FibEntriesListener.class);
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final VpnInstanceListener vpnInstanceListener;
@Inject
public FibEntriesListener(final DataBroker dataBroker, final VpnInstanceListener vpnInstanceListener) {
super(VrfEntry.class, FibEntriesListener.class);
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.vpnInstanceListener = vpnInstanceListener;
}
routeIds.add(label);
}
});
- TransactionUtil.asyncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getVpnInstanceOpDataIdentifier(rd),
- new VpnInstanceOpDataEntryBuilder(vpnInstanceOpData).setRouteEntryId(routeIds).build(),
- TransactionUtil.DEFAULT_CALLBACK);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ tx.put(LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+ new VpnInstanceOpDataEntryBuilder(vpnInstanceOpData).setRouteEntryId(routeIds)
+ .build())),
+ LOG, "Error adding label to VPN instance");
} else {
LOG.warn("No VPN Instance found for RD: {}", rd);
}
} else {
LOG.debug("Removing label from vpn info - {}", labels);
routeIds.removeAll(labels);
- TransactionUtil.asyncWrite(
- dataBroker,
- LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getVpnInstanceOpDataIdentifier(rd),
- new VpnInstanceOpDataEntryBuilder(vpnInstanceOpData).setRouteEntryId(
- routeIds).build(), TransactionUtil.DEFAULT_CALLBACK);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ tx.put(LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+ new VpnInstanceOpDataEntryBuilder(vpnInstanceOpData).setRouteEntryId(routeIds)
+ .build())),
+ LOG, "Error removing label from VPN instance");
}
} else {
LOG.warn("No VPN Instance found for RD: {}", rd);
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.arputil.api.ArpConstants;
import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
extends AsyncClusteredDataTreeChangeListenerBase<LearntVpnVipToPortEvent, LearntVpnVipToPortEventProcessor> {
private static final Logger LOG = LoggerFactory.getLogger(LearntVpnVipToPortEventProcessor.class);
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final OdlInterfaceRpcService interfaceRpc;
private final IMdsalApiManager mdsalManager;
private final AlivenessMonitorService alivenessManager;
IdManagerService idManagerService, final JobCoordinator jobCoordinator) {
super(LearntVpnVipToPortEvent.class, LearntVpnVipToPortEventProcessor.class);
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.interfaceRpc = interfaceRpc;
this.mdsalManager = mdsalManager;
this.alivenessManager = alivenessManager;
}
@Override
- public List<ListenableFuture<Void>> call() throws Exception {
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
- WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
- addMipAdjacency(vpnName, interfaceName,
- srcIpAddress, macAddress, destIpAddress);
- VpnUtil.createLearntVpnVipToPort(dataBroker, vpnName, srcIpAddress,
- interfaceName, macAddress, writeOperTxn);
- futures.add(writeConfigTxn.submit());
- futures.add(writeOperTxn.submit());
- return futures;
+ public List<ListenableFuture<Void>> call() {
+ return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(operTx -> {
+ addMipAdjacency(vpnName, interfaceName,
+ srcIpAddress, macAddress, destIpAddress);
+ VpnUtil.createLearntVpnVipToPort(dataBroker, vpnName, srcIpAddress,
+ interfaceName, macAddress, operTx);
+ }));
}
private void addMipAdjacency(String vpnInstName, String vpnInterface, String srcPrefix, String mipMacAddress,
+++ /dev/null
-/*
- * Copyright (c) 2015 - 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.netvirt.vpnmanager;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class TransactionUtil {
- private static final Logger LOG = LoggerFactory.getLogger(TransactionUtil.class);
-
- private TransactionUtil() {
- }
-
- public static final FutureCallback<Void> DEFAULT_CALLBACK = new FutureCallback<Void>() {
- @Override
- public void onSuccess(Void result) {
- LOG.debug("onSuccess: Success in Datastore operation");
- }
-
- @Override
- public void onFailure(Throwable error) {
- LOG.error("onFailure: Error in Datastore operation", error);
- }
- };
-
- public static <T extends DataObject> Optional<T> read(DataBroker dataBroker, LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path) {
-
- ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction();
-
- Optional<T> result;
- try {
- result = tx.read(datastoreType, path).get();
- } catch (InterruptedException | ExecutionException e) {
- LOG.debug("read: Error while reading data from path {}", path);
- throw new RuntimeException(e);
- }
- return result;
- }
-
- public static <T extends DataObject> void asyncWrite(DataBroker dataBroker, LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
- WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- tx.put(datastoreType, path, data, true);
- Futures.addCallback(tx.submit(), callback, MoreExecutors.directExecutor());
- }
-
- public static <T extends DataObject> void syncWrite(DataBroker dataBroker, LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path, T data) {
- WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- tx.put(datastoreType, path, data, WriteTransaction.CREATE_MISSING_PARENTS);
- try {
- tx.submit().get();
- } catch (InterruptedException | ExecutionException e) {
- LOG.error("syncWrite: Error writing VPN instance to ID info to datastore (path, data) : ({}, {})", path,
- data);
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-}
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.fibmanager.api.IFibManager;
import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
import org.opendaylight.netvirt.vpnmanager.api.VpnExtraRouteHelper;
private static final Logger LOG = LoggerFactory.getLogger(TunnelInterfaceStateListener.class);
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final IFibManager fibManager;
private final OdlInterfaceRpcService intfRpcService;
private final VpnInterfaceManager vpnInterfaceManager;
final JobCoordinator jobCoordinator) {
super(StateTunnelList.class, TunnelInterfaceStateListener.class);
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.fibManager = fibManager;
this.intfRpcService = ifaceMgrRpcService;
this.vpnInterfaceManager = vpnInterfaceManager;
LOG.trace("update: No vpnInstanceOpdata present");
return;
}
- WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
if (tunOpStatus == TunnelOperStatus.Up) {
handleTunnelEventForDPN(update, TunnelAction.TUNNEL_EP_ADD);
} else {
- vpnInstanceOpData.stream().filter(opData -> {
- if (opData.getVpnToDpnList() == null) {
- return false;
- }
- return opData.getVpnToDpnList().stream().anyMatch(vpnToDpn -> vpnToDpn.getDpnId().equals(srcDpnId));
- }).forEach(opData -> {
- List<DestPrefixes> prefixes = VpnExtraRouteHelper.getExtraRouteDestPrefixes(dataBroker,
- opData.getVpnId());
- prefixes.forEach(destPrefix -> {
- VrfEntry vrfEntry = VpnUtil.getVrfEntry(dataBroker, opData.getVrfId(),
- destPrefix.getDestPrefix());
- if (vrfEntry == null || vrfEntry.getRoutePaths() == null) {
- return;
- }
- List<RoutePaths> routePaths = vrfEntry.getRoutePaths();
- routePaths.forEach(routePath -> {
- if (routePath.getNexthopAddress().equals(srcTepIp)) {
- fibManager.updateRoutePathForFibEntry(opData.getVrfId(),
- destPrefix.getDestPrefix(), srcTepIp, routePath.getLabel(),
- false, writeConfigTxn);
- }
- });
- });
- });
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx ->
+ vpnInstanceOpData.stream()
+ .filter(opData -> opData.getVpnToDpnList() != null
+ && opData.getVpnToDpnList().stream().anyMatch(
+ vpnToDpn -> vpnToDpn.getDpnId().equals(srcDpnId)))
+ .forEach(opData -> {
+ List<DestPrefixes> prefixes = VpnExtraRouteHelper.getExtraRouteDestPrefixes(dataBroker,
+ opData.getVpnId());
+ prefixes.forEach(destPrefix -> {
+ VrfEntry vrfEntry = VpnUtil.getVrfEntry(dataBroker, opData.getVrfId(),
+ destPrefix.getDestPrefix());
+ if (vrfEntry == null || vrfEntry.getRoutePaths() == null) {
+ return;
+ }
+ List<RoutePaths> routePaths = vrfEntry.getRoutePaths();
+ routePaths.forEach(routePath -> {
+ if (routePath.getNexthopAddress().equals(srcTepIp)) {
+ fibManager.updateRoutePathForFibEntry(opData.getVrfId(),
+ destPrefix.getDestPrefix(), srcTepIp, routePath.getLabel(),
+ false, confTx);
+ }
+ });
+ });
+ })
+ ), LOG, "Error updating route paths for FIB entries");
}
- writeConfigTxn.submit();
}
@Override
@Override
public List<ListenableFuture<Void>> call() {
- WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
- WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
- List<ListenableFuture<Void>> futures = new ArrayList<>();
-
- if (tunnelAction == TunnelAction.TUNNEL_EP_ADD) {
- vpnInterfaceManager.updateVpnInterfaceOnTepAdd(vpnInterface,
- stateTunnelList,
- writeConfigTxn,
- writeOperTxn);
- }
-
- if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE && isTepDeletedOnDpn) {
- vpnInterfaceManager.updateVpnInterfaceOnTepDelete(vpnInterface,
- stateTunnelList,
- writeConfigTxn,
- writeOperTxn);
- }
+ List<ListenableFuture<Void>> futures = new ArrayList<>(2);
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx ->
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(operTx -> {
+ if (tunnelAction == TunnelAction.TUNNEL_EP_ADD) {
+ vpnInterfaceManager.updateVpnInterfaceOnTepAdd(vpnInterface, stateTunnelList, confTx,
+ operTx);
+ }
- futures.add(writeOperTxn.submit());
- futures.add(writeConfigTxn.submit());
+ if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE && isTepDeletedOnDpn) {
+ vpnInterfaceManager.updateVpnInterfaceOnTepDelete(vpnInterface, stateTunnelList, confTx,
+ operTx);
+ }
+ }))));
return futures;
}
}
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.elanmanager.api.IElanService;
import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
private static final Logger LOG = LoggerFactory.getLogger(VpnElanInterfaceChangeListener.class);
private final DataBroker broker;
+ private final ManagedNewTransactionRunner txRunner;
private final IElanService elanService;
@Inject
public VpnElanInterfaceChangeListener(final DataBroker broker, final IElanService elanService) {
super(ElanInterface.class, VpnElanInterfaceChangeListener.class);
this.broker = broker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(broker);
this.elanService = elanService;
}
}
InstanceIdentifier<VpnInterface> vpnInterfaceIdentifier = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
- VpnUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, vpnInterfaceIdentifier);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ tx.delete(LogicalDatastoreType.CONFIGURATION, vpnInterfaceIdentifier)), LOG,
+ "Error removing VPN interface {}", vpnInterfaceIdentifier);
LOG.info("remove: Removed VPN interface {}", interfaceName);
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.netvirt.fibmanager.api.IFibManager;
import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
private static final Logger LOG = LoggerFactory.getLogger(VpnFootprintService.class);
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final IFibManager fibManager;
private final VpnOpDataSyncer vpnOpDataSyncer;
private final NotificationPublishService notificationPublishService;
final NotificationPublishService notificationPublishService, final VpnOpDataSyncer vpnOpDataSyncer,
final IInterfaceManager interfaceManager) {
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.fibManager = fibManager;
this.vpnOpDataSyncer = vpnOpDataSyncer;
this.notificationPublishService = notificationPublishService;
private void createOrUpdateVpnToDpnListForInterfaceName(long vpnId, String primaryRd, BigInteger dpnId,
String intfName, String vpnName) {
- Boolean newDpnOnVpn = Boolean.FALSE;
+ AtomicBoolean newDpnOnVpn = new AtomicBoolean(false);
synchronized (vpnName.intern()) {
- WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(primaryRd, dpnId);
Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
VpnInterfaces vpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
- if (dpnInVpn.isPresent()) {
- VpnToDpnList vpnToDpnList = dpnInVpn.get();
- List<VpnInterfaces> vpnInterfaces = vpnToDpnList.getVpnInterfaces();
- if (vpnInterfaces == null) {
- vpnInterfaces = new ArrayList<>();
- }
- vpnInterfaces.add(vpnInterface);
- VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
- vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
-
- writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(),
- WriteTransaction.CREATE_MISSING_PARENTS);
- /*
- * If earlier state was inactive, it is considered new DPN coming back to the
- * same VPN
- */
- if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
- newDpnOnVpn = Boolean.TRUE;
+ ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ if (dpnInVpn.isPresent()) {
+ VpnToDpnList vpnToDpnList = dpnInVpn.get();
+ List<VpnInterfaces> vpnInterfaces = vpnToDpnList.getVpnInterfaces();
+ if (vpnInterfaces == null) {
+ vpnInterfaces = new ArrayList<>();
+ }
+ vpnInterfaces.add(vpnInterface);
+ VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
+ vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
+
+ tx.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(),
+ WriteTransaction.CREATE_MISSING_PARENTS);
+ /*
+ * If earlier state was inactive, it is considered new DPN coming back to the
+ * same VPN
+ */
+ if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
+ newDpnOnVpn.set(true);
+ }
+ LOG.debug("createOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} interface {}"
+ + " on dpn {}", vpnName, vpnId, intfName, dpnId);
+ } else {
+ List<VpnInterfaces> vpnInterfaces = new ArrayList<>();
+ vpnInterfaces.add(vpnInterface);
+ VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
+ vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
+
+ tx.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(),
+ WriteTransaction.CREATE_MISSING_PARENTS);
+ newDpnOnVpn.set(true);
+ LOG.debug("createOrUpdateVpnToDpnList: Creating vpn footprint for vpn {} vpnId {} interface {}"
+ + " on dpn {}", vpnName, vpnId, intfName, dpnId);
}
- LOG.debug("createOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} interface {}"
- + " on dpn {}", vpnName, vpnId, intfName, dpnId);
- } else {
- List<VpnInterfaces> vpnInterfaces = new ArrayList<>();
- vpnInterfaces.add(vpnInterface);
- VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
- vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
-
- writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(),
- WriteTransaction.CREATE_MISSING_PARENTS);
- newDpnOnVpn = Boolean.TRUE;
- LOG.debug("createOrUpdateVpnToDpnList: Creating vpn footprint for vpn {} vpnId {} interface {}"
- + " on dpn {}", vpnName, vpnId, intfName, dpnId);
- }
+ });
+
try {
- writeTxn.submit().get();
+ future.get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("createOrUpdateVpnToDpnList: Error adding to dpnToVpnList for vpn {} vpnId {} interface {}"
+ " dpn {}", vpnName, vpnId, intfName, dpnId, e);
/*
* Informing the FIB only after writeTxn is submitted successfully.
*/
- if (newDpnOnVpn) {
+ if (newDpnOnVpn.get()) {
if (VpnUtil.isVlan(dataBroker ,intfName)) {
if (!VpnUtil.shouldPopulateFibForVlan(dataBroker, vpnName, null, dpnId, interfaceManager)) {
return;
private void createOrUpdateVpnToDpnListForIPAddress(long vpnId, String primaryRd, BigInteger dpnId,
ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
- Boolean newDpnOnVpn = Boolean.FALSE;
+ AtomicBoolean newDpnOnVpn = new AtomicBoolean(false);
synchronized (vpnName.intern()) {
- WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(primaryRd, dpnId);
Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
IpAddressesBuilder ipAddressesBldr = new IpAddressesBuilder()
ipAddressesBldr.setKey(new IpAddressesKey(ipAddressSourceValuePair.getValue()));
ipAddressesBldr.setIpAddress(ipAddressSourceValuePair.getValue());
- if (dpnInVpn.isPresent()) {
- VpnToDpnList vpnToDpnList = dpnInVpn.get();
- List<IpAddresses> ipAddresses = vpnToDpnList.getIpAddresses();
- if (ipAddresses == null) {
- ipAddresses = new ArrayList<>();
- }
- ipAddresses.add(ipAddressesBldr.build());
- VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
- vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
-
- writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
- /*
- * If earlier state was inactive, it is considered new DPN coming back to the
- * same VPN
- */
- if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
- newDpnOnVpn = Boolean.TRUE;
- }
- } else {
- List<IpAddresses> ipAddresses = new ArrayList<>();
- ipAddresses.add(ipAddressesBldr.build());
- VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
- vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
+ ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ if (dpnInVpn.isPresent()) {
+ VpnToDpnList vpnToDpnList = dpnInVpn.get();
+ List<IpAddresses> ipAddresses = vpnToDpnList.getIpAddresses();
+ if (ipAddresses == null) {
+ ipAddresses = new ArrayList<>();
+ }
+ ipAddresses.add(ipAddressesBldr.build());
+ VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
+ vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
+
+ tx.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
+ /*
+ * If earlier state was inactive, it is considered new DPN coming back to the
+ * same VPN
+ */
+ if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
+ newDpnOnVpn.set(true);
+ }
+ } else {
+ List<IpAddresses> ipAddresses = new ArrayList<>();
+ ipAddresses.add(ipAddressesBldr.build());
+ VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
+ vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setIpAddresses(ipAddresses);
- writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
- newDpnOnVpn = Boolean.TRUE;
- }
+ tx.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
+ newDpnOnVpn.set(true);
+ }
+ });
try {
- writeTxn.submit().get();
+ future.get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("Error adding to dpnToVpnList for vpn {} ipAddresses {} dpn {}", vpnName,
ipAddressSourceValuePair.getValue(), dpnId, e);
/*
* Informing the Fib only after writeTxn is submitted successfuly.
*/
- if (newDpnOnVpn) {
+ if (newDpnOnVpn.get()) {
LOG.debug("Sending populateFib event for new dpn {} in VPN {}", dpnId, vpnName);
fibManager.populateFibOnNewDpn(dpnId, vpnId, primaryRd,
new DpnEnterExitVpnWorker(dpnId, vpnName, primaryRd, true /* entered */));
private void removeOrUpdateVpnToDpnListForInterfaceName(long vpnId, String rd, BigInteger dpnId, String intfName,
String vpnName) {
- Boolean lastDpnOnVpn = Boolean.FALSE;
+ AtomicBoolean lastDpnOnVpn = new AtomicBoolean(false);
synchronized (vpnName.intern()) {
InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(rd, dpnId);
VpnToDpnList dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
VpnInterfaces currVpnInterface = new VpnInterfacesBuilder().setInterfaceName(intfName).build();
if (vpnInterfaces.remove(currVpnInterface)) {
- WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
- if (vpnInterfaces.isEmpty()) {
- List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
- VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setVpnInterfaces(null);
- if (ipAddresses == null || ipAddresses.isEmpty()) {
- dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
- lastDpnOnVpn = Boolean.TRUE;
- } else {
- LOG.error("removeOrUpdateVpnToDpnList: vpn interfaces are empty but ip addresses are present"
- + " for the vpn {} in dpn {} interface {}", vpnName, dpnId, intfName);
- }
- LOG.debug("removeOrUpdateVpnToDpnList: Removing vpn footprint for vpn {} vpnId {} interface {},"
- + " on dpn {}", vpnName, vpnName, intfName, dpnId);
- writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(),
- WriteTransaction.CREATE_MISSING_PARENTS);
-
- } else {
- writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
- id.child(VpnInterfaces.class, new VpnInterfacesKey(intfName)));
- LOG.debug("removeOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} interface {},"
- + " on dpn {}", vpnName, vpnName, intfName, dpnId);
- }
try {
- writeTxn.submit().get();
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ if (vpnInterfaces.isEmpty()) {
+ List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
+ VpnToDpnListBuilder dpnInVpnBuilder =
+ new VpnToDpnListBuilder(dpnInVpn).setVpnInterfaces(null);
+ if (ipAddresses == null || ipAddresses.isEmpty()) {
+ dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
+ lastDpnOnVpn.set(true);
+ } else {
+ LOG.error("removeOrUpdateVpnToDpnList: vpn interfaces are empty but ip addresses are "
+ + "present for the vpn {} in dpn {} interface {}", vpnName, dpnId, intfName);
+ }
+ LOG.debug("removeOrUpdateVpnToDpnList: Removing vpn footprint for vpn {} vpnId {} "
+ + "interface {}, on dpn {}", vpnName, vpnName, intfName, dpnId);
+ tx.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(),
+ WriteTransaction.CREATE_MISSING_PARENTS);
+
+ } else {
+ tx.delete(LogicalDatastoreType.OPERATIONAL,
+ id.child(VpnInterfaces.class, new VpnInterfacesKey(intfName)));
+ LOG.debug("removeOrUpdateVpnToDpnList: Updating vpn footprint for vpn {} vpnId {} "
+ + "interface {}, on dpn {}", vpnName, vpnName, intfName, dpnId);
+ }
+ }).get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("removeOrUpdateVpnToDpnList: Error removing from dpnToVpnList for vpn {} vpnId {}"
+ " interface {} dpn {}", vpnName, vpnId, intfName, dpnId, e);
LOG.info("removeOrUpdateVpnToDpnList: Updated/Removed vpn footprint for vpn {} vpnId {} interface {},"
+ " on dpn {}", vpnName, vpnName, intfName, dpnId);
- if (lastDpnOnVpn) {
+ if (lastDpnOnVpn.get()) {
fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd,
new DpnEnterExitVpnWorker(dpnId, vpnName, rd, false /* exited */));
LOG.info("removeOrUpdateVpnToDpnList: Sent cleanup event for dpn {} in VPN {} vpnId {} interface {}", dpnId,
private void removeOrUpdateVpnToDpnListForIpAddress(long vpnId, String rd, BigInteger dpnId,
ImmutablePair<IpAddresses.IpAddressSource, String> ipAddressSourceValuePair, String vpnName) {
- Boolean lastDpnOnVpn = Boolean.FALSE;
+ AtomicBoolean lastDpnOnVpn = new AtomicBoolean(false);
synchronized (vpnName.intern()) {
InstanceIdentifier<VpnToDpnList> id = VpnHelper.getVpnToDpnListIdentifier(rd, dpnId);
VpnToDpnList dpnInVpn = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
.setKey(new IpAddressesKey(ipAddressSourceValuePair.getValue()))
.setIpAddressSource(ipAddressSourceValuePair.getKey()).build();
if (ipAddresses.remove(currIpAddress)) {
- WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
- if (ipAddresses.isEmpty()) {
- List<VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
- VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setIpAddresses(null);
- if (vpnInterfaces == null || vpnInterfaces.isEmpty()) {
- dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
- lastDpnOnVpn = Boolean.TRUE;
- } else {
- LOG.warn("ip addresses are empty but vpn interfaces are present for the vpn {} in dpn {}",
- vpnName, dpnId);
- }
- writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(), true);
-
- } else {
- writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
- id.child(IpAddresses.class, new IpAddressesKey(ipAddressSourceValuePair.getValue())));
- }
try {
- writeTxn.submit().get();
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ if (ipAddresses.isEmpty()) {
+ List<VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
+ VpnToDpnListBuilder dpnInVpnBuilder =
+ new VpnToDpnListBuilder(dpnInVpn).setIpAddresses(null);
+ if (vpnInterfaces == null || vpnInterfaces.isEmpty()) {
+ dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
+ lastDpnOnVpn.set(true);
+ } else {
+ LOG.warn("ip addresses are empty but vpn interfaces are present for the vpn {} in "
+ + "dpn {}", vpnName, dpnId);
+ }
+ tx.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(), true);
+
+ } else {
+ tx.delete(LogicalDatastoreType.OPERATIONAL, id.child(IpAddresses.class,
+ new IpAddressesKey(ipAddressSourceValuePair.getValue())));
+ }
+ }).get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("Error removing from dpnToVpnList for vpn {} Ipaddress {} dpn {}", vpnName,
ipAddressSourceValuePair.getValue(), dpnId, e);
}
} // Ends synchronized block
- if (lastDpnOnVpn) {
+ if (lastDpnOnVpn.get()) {
LOG.debug("Sending cleanup event for dpn {} in VPN {}", dpnId, vpnName);
fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd,
new DpnEnterExitVpnWorker(dpnId, vpnName, rd, false /* exited */));
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.FlowEntity;
import org.opendaylight.genius.mdsalutil.InstructionInfo;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
import org.opendaylight.genius.utils.SystemPropertyReader;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.fibmanager.api.IFibManager;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
private static final String LOGGING_PREFIX_ADD = "VPN-ADD:";
private static final String LOGGING_PREFIX_DELETE = "VPN-REMOVE:";
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final IdManagerService idManager;
private final VpnInterfaceManager vpnInterfaceManager;
private final IFibManager fibManager;
final JobCoordinator jobCoordinator) {
super(VpnInstance.class, VpnInstanceListener.class);
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.idManager = idManager;
this.vpnInterfaceManager = vpnInterfaceManager;
this.fibManager = fibManager;
vpnName);
return;
} else {
- jobCoordinator.enqueueJob("VPN-" + vpnName, () -> {
- VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder().setVrfId(primaryRd)
- .setVpnState(VpnInstanceOpDataEntry.VpnState.PendingDelete);
- InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd);
- WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
- writeTxn.merge(LogicalDatastoreType.OPERATIONAL, id, builder.build());
-
- LOG.info("{} call: Operational status set to PENDING_DELETE for vpn {} with rd {}",
- LOGGING_PREFIX_DELETE, vpnName, primaryRd);
- return Collections.singletonList(writeTxn.submit());
- }, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
+ jobCoordinator.enqueueJob("VPN-" + vpnName, () ->
+ Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder().setVrfId(primaryRd)
+ .setVpnState(VpnInstanceOpDataEntry.VpnState.PendingDelete);
+ InstanceIdentifier<VpnInstanceOpDataEntry> id =
+ VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd);
+ tx.merge(LogicalDatastoreType.OPERATIONAL, id, builder.build());
+
+ LOG.info("{} call: Operational status set to PENDING_DELETE for vpn {} with rd {}",
+ LOGGING_PREFIX_DELETE, vpnName, primaryRd);
+ })), SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
}
}
public List<ListenableFuture<Void>> call() {
// If another renderer(for eg : CSS) needs to be supported, check can be performed here
// to call the respective helpers.
- WriteTransaction writeConfigTxn = broker.newWriteOnlyTransaction();
- WriteTransaction writeOperTxn = broker.newWriteOnlyTransaction();
- addVpnInstance(vpnInstance, writeConfigTxn, writeOperTxn);
- try {
- writeOperTxn.submit().get();
- } catch (InterruptedException | ExecutionException e) {
- log.error("{} call: Error creating vpn {} ", LOGGING_PREFIX_ADD, vpnInstance.getVpnInstanceName());
- throw new RuntimeException(e.getMessage(), e);
- }
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(writeConfigTxn.submit());
- ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
- Futures.addCallback(listenableFuture,
+ List<ListenableFuture<Void>> futures = new ArrayList<>(2);
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> {
+ ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(operTx ->
+ addVpnInstance(vpnInstance, confTx, operTx));
+ ListenableFutures.addErrorLogging(future, LOG, "{} call: error creating VPN {}", LOGGING_PREFIX_ADD,
+ vpnInstance.getVpnInstanceName());
+ futures.add(future);
+ }));
+ Futures.addCallback(Futures.allAsList(futures),
new PostAddVpnInstanceWorker(vpnInstance , vpnInstance.getVpnInstanceName()),
MoreExecutors.directExecutor());
return futures;
@SuppressWarnings("checkstyle:IllegalCatch")
private void addVpnInstance(VpnInstance value, WriteTransaction writeConfigTxn,
WriteTransaction writeOperTxn) {
+ if (writeConfigTxn == null) {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ addVpnInstance(value, tx, writeOperTxn)), LOG, "Error adding VPN instance {}", value);
+ return;
+ }
+ if (writeOperTxn == null) {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ addVpnInstance(value, writeConfigTxn, tx)), LOG, "Error adding VPN instance {}", value);
+ return;
+ }
VpnAfConfig config = value.getIpv4Family();
String vpnInstanceName = value.getVpnInstanceName();
org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance
vpnInstanceToVpnId = VpnUtil.getVpnInstanceToVpnId(vpnInstanceName, vpnId, primaryRd);
- if (writeConfigTxn != null) {
- writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION,
- VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnInstanceName),
- vpnInstanceToVpnId, WriteTransaction.CREATE_MISSING_PARENTS);
- } else {
- TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
- VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnInstanceName),
- vpnInstanceToVpnId);
- }
+ writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION,
+ VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnInstanceName),
+ vpnInstanceToVpnId, WriteTransaction.CREATE_MISSING_PARENTS);
VpnIds vpnIdToVpnInstance = VpnUtil.getVpnIdToVpnInstance(vpnId, value.getVpnInstanceName(),
primaryRd, VpnUtil.isBgpVpn(vpnInstanceName, primaryRd));
- if (writeConfigTxn != null) {
- writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION,
- VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId),
- vpnIdToVpnInstance, WriteTransaction.CREATE_MISSING_PARENTS);
- } else {
- TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
- VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId),
- vpnIdToVpnInstance);
- }
+ writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION,
+ VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId),
+ vpnIdToVpnInstance, WriteTransaction.CREATE_MISSING_PARENTS);
try {
String cachedTransType = fibManager.getConfTransType();
} else {
builder.setBgpvpnType(VpnInstanceOpDataEntry.BgpvpnType.VPN);
}
- if (writeOperTxn != null) {
- writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd),
- builder.build(), true);
- } else {
- TransactionUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd),
- builder.build());
- }
+ writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd),
+ builder.build(), true);
LOG.info("{} addVpnInstance: VpnInstanceOpData populated successfully for vpn {} rd {}", LOGGING_PREFIX_ADD,
vpnInstanceName, primaryRd);
}
protected VpnInstanceOpDataEntry getVpnInstanceOpData(String rd) {
InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(rd);
- Optional<VpnInstanceOpDataEntry> vpnInstanceOpData =
- TransactionUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
- if (vpnInstanceOpData.isPresent()) {
- return vpnInstanceOpData.get();
+ try {
+ return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL,
+ id).orNull();
+ } catch (ReadFailedException e) {
+ throw new RuntimeException("Error reading VPN instance data for " + rd, e);
}
- return null;
}
private List<String> getDcGatewayTunnelInterfaceNameList() {
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
final BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(interfaceState);
final int ifIndex = interfaceState.getIfIndex();
jobCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName, () -> {
- WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
- WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
- WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
- LOG.info("addVpnInterface: VPN Interface add event - intfName {} vpnName {} on dpn {}" ,
- vpnInterface.getName(), vpnName, vpnInterface.getDpnId());
- processVpnInterfaceUp(dpnId, vpnInterface, primaryRd, ifIndex, false, writeConfigTxn,
- writeOperTxn, writeInvTxn, interfaceState, vpnName);
- if (oldAdjs != null && !oldAdjs.equals(newAdjs)) {
- LOG.info("addVpnInterface: Adjacency changed upon VPNInterface {}"
- + " Update for swapping VPN {} case.", interfaceName, vpnName);
- if (newAdjs != null) {
- for (Adjacency adj : newAdjs) {
- if (oldAdjs.contains(adj)) {
- oldAdjs.remove(adj);
- } else {
- if (!isBgpVpnInternetVpn || VpnUtil.isAdjacencyEligibleToVpnInternet(
- dataBroker, adj)) {
- addNewAdjToVpnInterface(vpnInterfaceOpIdentifier, primaryRd,
- adj, dpnId, writeOperTxn, writeConfigTxn);
- }
- }
- }
- }
- for (Adjacency adj : oldAdjs) {
- if (!isBgpVpnInternetVpn || VpnUtil.isAdjacencyEligibleToVpnInternet(
- dataBroker, adj)) {
- delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
- writeOperTxn, writeConfigTxn);
- }
- }
- }
- ListenableFuture<Void> operFuture = writeOperTxn.submit();
- try {
- operFuture.get();
- } catch (ExecutionException e) {
- LOG.error("addVpnInterface: Exception encountered while submitting operational future for"
- + " addVpnInterface {} on vpn {}", vpnInterface.getName(), vpnName, e);
- return null;
- }
+ // TODO Deal with sequencing — the config tx must only submitted if the oper tx goes in
+ // (the inventory tx goes in last)
List<ListenableFuture<Void>> futures = new ArrayList<>();
- ListenableFuture<Void> configFuture = writeConfigTxn.submit();
- futures.add(configFuture);
- Futures.addCallback(configFuture, new PostVpnInterfaceWorker(interfaceName, true, "Config"));
- futures.add(writeInvTxn.submit());
+ ListenableFuture<Void> confFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+ confTx -> futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+ operTx -> futures.add(
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(invTx -> {
+ LOG.info(
+ "addVpnInterface: VPN Interface add event - intfName {} vpnName {}"
+ + " on dpn {}",
+ vpnInterface.getName(), vpnName, vpnInterface.getDpnId());
+ processVpnInterfaceUp(dpnId, vpnInterface, primaryRd, ifIndex, false,
+ confTx, operTx, invTx, interfaceState, vpnName);
+ if (oldAdjs != null && !oldAdjs.equals(newAdjs)) {
+ LOG.info("addVpnInterface: Adjacency changed upon VPNInterface {}"
+ + " Update for swapping VPN {} case.", interfaceName, vpnName);
+ if (newAdjs != null) {
+ for (Adjacency adj : newAdjs) {
+ if (oldAdjs.contains(adj)) {
+ oldAdjs.remove(adj);
+ } else {
+ if (!isBgpVpnInternetVpn
+ || VpnUtil.isAdjacencyEligibleToVpnInternet(
+ dataBroker, adj)) {
+ addNewAdjToVpnInterface(vpnInterfaceOpIdentifier,
+ primaryRd, adj, dpnId, operTx, confTx);
+ }
+ }
+ }
+ }
+ for (Adjacency adj : oldAdjs) {
+ if (!isBgpVpnInternetVpn
+ || VpnUtil.isAdjacencyEligibleToVpnInternet(
+ dataBroker, adj)) {
+ delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
+ operTx, confTx);
+ }
+ }
+ }
+ })))));
+ futures.add(confFuture);
+ Futures.addCallback(confFuture, new PostVpnInterfaceWorker(interfaceName, true, "Config"),
+ MoreExecutors.directExecutor());
LOG.info("addVpnInterface: Addition of interface {} in VPN {} on dpn {}"
+ " processed successfully", interfaceName, vpnName, dpnId);
return futures;
} else if (Boolean.TRUE.equals(vpnInterface.isRouterInterface())) {
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterface.getName(),
() -> {
- WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
- createFibEntryForRouterInterface(primaryRd, vpnInterface, interfaceName,
- writeConfigTxn, vpnName);
- LOG.info("addVpnInterface: Router interface {} for vpn {} on dpn {}", interfaceName,
- vpnName, vpnInterface.getDpnId());
- ListenableFuture<Void> futures = writeConfigTxn.submit();
- String errorText = "addVpnInterfaceCall: Exception encountered while submitting writeConfigTxn"
- + " for interface " + vpnInterface.getName() + " on vpn " + vpnName;
- ListenableFutures.addErrorLogging(futures, LOG, errorText);
- return Collections.singletonList(futures);
+ ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> {
+ createFibEntryForRouterInterface(primaryRd, vpnInterface, interfaceName,
+ confTx, vpnName);
+ LOG.info("addVpnInterface: Router interface {} for vpn {} on dpn {}", interfaceName,
+ vpnName, vpnInterface.getDpnId());
+ });
+ ListenableFutures.addErrorLogging(future, LOG,
+ "Error creating FIB entry for interface {} on VPN {}", vpnInterface.getName(), vpnName);
+ return Collections.singletonList(future);
});
} else {
LOG.info("addVpnInterface: Handling addition of VPN interface {} on vpn {} skipped as interfaceState"
List<VpnInstanceOpDataEntry> vpnsToExportRoute = getVpnsExportingMyRoute(vpnName);
for (VpnInstanceOpDataEntry vpn : vpnsToExportRoute) {
List<VrfEntry> vrfEntries = VpnUtil.getAllVrfEntries(dataBroker, vpn.getVrfId());
- WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
if (vrfEntries != null) {
- for (VrfEntry vrfEntry : vrfEntries) {
- try {
- if (!FibHelper.isControllerManagedNonInterVpnLinkRoute(
- RouteOrigin.value(vrfEntry.getOrigin()))) {
- LOG.info("handleVpnsExportingRoutes: vrfEntry with rd {} prefix {}"
- + " is not a controller managed non intervpn link route. Ignoring.",
- vpn.getVrfId(), vrfEntry.getDestPrefix());
- continue;
- }
- String prefix = vrfEntry.getDestPrefix();
- String gwMac = vrfEntry.getGatewayMacAddress();
- vrfEntry.getRoutePaths().forEach(routePath -> {
- String nh = routePath.getNexthopAddress();
- int label = routePath.getLabel().intValue();
- if (FibHelper.isControllerManagedVpnInterfaceRoute(RouteOrigin.value(
- vrfEntry.getOrigin()))) {
- LOG.info("handleVpnsExportingRoutesImporting: Importing fib entry rd {} prefix {}"
- + " nexthop {} label {} to vpn {} vpnRd {}", vpn.getVrfId(), prefix, nh, label,
- vpnName, vpnRd);
- fibManager.addOrUpdateFibEntry(vpnRd, null /*macAddress*/, prefix,
- Collections.singletonList(nh), VrfEntry.EncapType.Mplsgre, label,
- 0 /*l3vni*/, gwMac, vpn.getVrfId(), RouteOrigin.SELF_IMPORTED,
- writeConfigTxn);
- } else {
- LOG.info("handleVpnsExportingRoutes: Importing subnet route fib entry rd {} prefix {}"
- + " nexthop {} label {} to vpn {} vpnRd {}", vpn.getVrfId(), prefix, nh, label,
- vpnName, vpnRd);
- SubnetRoute route = vrfEntry.getAugmentation(SubnetRoute.class);
- importSubnetRouteForNewVpn(vpnRd, prefix, nh, label, route, vpn.getVrfId(),
- writeConfigTxn);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> {
+ for (VrfEntry vrfEntry : vrfEntries) {
+ try {
+ if (!FibHelper.isControllerManagedNonInterVpnLinkRoute(
+ RouteOrigin.value(vrfEntry.getOrigin()))) {
+ LOG.info("handleVpnsExportingRoutes: vrfEntry with rd {} prefix {}"
+ + " is not a controller managed non intervpn link route. Ignoring.",
+ vpn.getVrfId(), vrfEntry.getDestPrefix());
+ continue;
}
- });
- } catch (RuntimeException e) {
- LOG.error("getNextHopAddressList: Exception occurred while importing route with rd {}"
- + " prefix {} routePaths {} to vpn {} vpnRd {}", vpn.getVrfId(),
- vrfEntry.getDestPrefix(), vrfEntry.getRoutePaths(), vpnName, vpnRd);
+ String prefix = vrfEntry.getDestPrefix();
+ String gwMac = vrfEntry.getGatewayMacAddress();
+ vrfEntry.getRoutePaths().forEach(routePath -> {
+ String nh = routePath.getNexthopAddress();
+ int label = routePath.getLabel().intValue();
+ if (FibHelper.isControllerManagedVpnInterfaceRoute(RouteOrigin.value(
+ vrfEntry.getOrigin()))) {
+ LOG.info("handleVpnsExportingRoutesImporting: Importing fib entry rd {} prefix {}"
+ + " nexthop {} label {} to vpn {} vpnRd {}",
+ vpn.getVrfId(), prefix, nh, label, vpnName, vpnRd);
+ fibManager.addOrUpdateFibEntry(vpnRd, null /*macAddress*/, prefix,
+ Collections.singletonList(nh), VrfEntry.EncapType.Mplsgre, label,
+ 0 /*l3vni*/, gwMac, vpn.getVrfId(), RouteOrigin.SELF_IMPORTED,
+ confTx);
+ } else {
+ LOG.info("handleVpnsExportingRoutes: Importing subnet route fib entry rd {} "
+ + "prefix {} nexthop {} label {} to vpn {} vpnRd {}",
+ vpn.getVrfId(), prefix, nh, label, vpnName, vpnRd);
+ SubnetRoute route = vrfEntry.getAugmentation(SubnetRoute.class);
+ importSubnetRouteForNewVpn(vpnRd, prefix, nh, label, route, vpn.getVrfId(),
+ confTx);
+ }
+ });
+ } catch (RuntimeException e) {
+ LOG.error("getNextHopAddressList: Exception occurred while importing route with rd {}"
+ + " prefix {} routePaths {} to vpn {} vpnRd {}", vpn.getVrfId(),
+ vrfEntry.getDestPrefix(), vrfEntry.getRoutePaths(), vpnName, vpnRd);
+ }
}
- }
- writeConfigTxn.submit();
+ }), LOG, "Error handing VPN exporting routes");
} else {
LOG.info("getNextHopAddressList: No vrf entries to import from vpn {} with rd {} to vpn {} with rd {}",
vpn.getVpnInstanceName(), vpn.getVrfId(), vpnName, vpnRd);
}
}
- @SuppressWarnings("checkstyle:IllegalCatch")
@Override
public void remove(InstanceIdentifier<VpnInterface> identifier, VpnInterface vpnInterface) {
final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
final String interfaceName) {
if (Boolean.TRUE.equals(vpnInterface.isRouterInterface())) {
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterface.getName(), () -> {
- WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
- deleteFibEntryForRouterInterface(vpnInterface, writeConfigTxn, vpnName);
- LOG.info("remove: Router interface {} for vpn {}", interfaceName, vpnName);
- ListenableFuture<Void> futures = writeConfigTxn.submit();
- String errorText = "removeVpnInterfaceCall: Exception encountered while submitting writeConfigTxn"
- + " for interface " + vpnInterface.getName() + " on vpn " + vpnName;
- ListenableFutures.addErrorLogging(futures, LOG, errorText);
- return Collections.singletonList(futures);
+ ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> {
+ deleteFibEntryForRouterInterface(vpnInterface, confTx, vpnName);
+ LOG.info("remove: Router interface {} for vpn {}", interfaceName, vpnName);
+ });
+ ListenableFutures.addErrorLogging(future, LOG, "Error removing call for interface {} on VPN {}",
+ vpnInterface.getName(), vpnName);
+ return Collections.singletonList(future);
}, DJC_MAX_RETRIES);
} else {
Interface interfaceState = InterfaceUtils.getInterfaceStateFromOperDS(dataBroker, interfaceName);
String primaryRd = VpnUtil.getPrimaryRd(dataBroker, newVpnName);
if (!VpnUtil.isVpnPendingDelete(dataBroker, primaryRd)) {
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterfaceName, () -> {
- WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
- WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
- InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpIdentifier =
- VpnUtil.getVpnInterfaceOpDataEntryIdentifier(vpnInterfaceName, newVpnName);
- LOG.info("VPN Interface update event - intfName {} onto vpnName {} running config-driven",
- update.getName(), newVpnName);
- //handle both addition and removal of adjacencies
- //currently, new adjacency may be an extra route
- boolean isBgpVpnInternetVpn = VpnUtil.isBgpVpnInternet(dataBroker, newVpnName);
- if (!oldAdjs.equals(newAdjs)) {
- for (Adjacency adj : copyNewAdjs) {
- if (copyOldAdjs.contains(adj)) {
- copyOldAdjs.remove(adj);
- } else {
- // add new adjacency - right now only extra route will hit this path
- if (!isBgpVpnInternetVpn || VpnUtil.isAdjacencyEligibleToVpnInternet(dataBroker, adj)) {
- addNewAdjToVpnInterface(vpnInterfaceOpIdentifier, primaryRd, adj,
- dpnId, writeOperTxn, writeConfigTxn);
+ // TODO Deal with sequencing — the config tx must only submitted if the oper tx goes in
+ List<ListenableFuture<Void>> futures = new ArrayList<>();
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> {
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(operTx -> {
+ InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpIdentifier =
+ VpnUtil.getVpnInterfaceOpDataEntryIdentifier(vpnInterfaceName, newVpnName);
+ LOG.info("VPN Interface update event - intfName {} onto vpnName {} running config-driven",
+ update.getName(), newVpnName);
+ //handle both addition and removal of adjacencies
+ //currently, new adjacency may be an extra route
+ boolean isBgpVpnInternetVpn = VpnUtil.isBgpVpnInternet(dataBroker, newVpnName);
+ if (!oldAdjs.equals(newAdjs)) {
+ for (Adjacency adj : copyNewAdjs) {
+ if (copyOldAdjs.contains(adj)) {
+ copyOldAdjs.remove(adj);
+ } else {
+ // add new adjacency - right now only extra route will hit this path
+ if (!isBgpVpnInternetVpn || VpnUtil.isAdjacencyEligibleToVpnInternet(dataBroker,
+ adj)) {
+ addNewAdjToVpnInterface(vpnInterfaceOpIdentifier, primaryRd, adj,
+ dpnId, operTx, confTx);
+ }
+ LOG.info("update: new Adjacency {} with nextHop {} label {} subnet {} added to"
+ + " vpn interface {} on vpn {} dpnId {}",
+ adj.getIpAddress(), adj.getNextHopIpList(),
+ adj.getLabel(), adj.getSubnetId(), update.getName(),
+ newVpnName, dpnId);
+ }
}
- LOG.info("update: new Adjacency {} with nextHop {} label {} subnet {} added to vpn "
- + "interface {} on vpn {} dpnId {}",
- adj.getIpAddress(), adj.getNextHopIpList(),
- adj.getLabel(), adj.getSubnetId(), update.getName(),
- newVpnName, dpnId);
- }
- }
- for (Adjacency adj : copyOldAdjs) {
- if (!isBgpVpnInternetVpn || VpnUtil.isAdjacencyEligibleToVpnInternet(dataBroker, adj)) {
- if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency
- && !adj.isPhysNetworkFunc()) {
- delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
- writeOperTxn, writeConfigTxn);
- Optional<VpnInterfaceOpDataEntry> optVpnInterface = VpnUtil.read(dataBroker,
- LogicalDatastoreType.OPERATIONAL, vpnInterfaceOpIdentifier);
- VpnInterfaceOpDataEntry vpnInterfaceOpDataEntry = optVpnInterface.get();
- long vpnId = VpnUtil.getVpnId(dataBroker, newVpnName);
- VpnUtil.removePrefixToInterfaceAdj(dataBroker, adj, vpnId, vpnInterfaceOpDataEntry,
- writeOperTxn);
- //remove FIB entry
- String vpnRd = VpnUtil.getVpnRd(dataBroker, newVpnName);
- LOG.debug("update: remove prefix {} from the FIB and BGP entry "
- + "for the Vpn-Rd {} ", adj.getIpAddress(), vpnRd);
- //remove BGP entry
- fibManager.removeFibEntry(vpnRd, adj.getIpAddress(), writeConfigTxn);
- if (vpnRd != null && !vpnRd.equalsIgnoreCase(newVpnName)) {
- bgpManager.withdrawPrefix(vpnRd, adj.getIpAddress());
+ for (Adjacency adj : copyOldAdjs) {
+ if (!isBgpVpnInternetVpn || VpnUtil.isAdjacencyEligibleToVpnInternet(dataBroker,
+ adj)) {
+ if (adj.getAdjacencyType() == AdjacencyType.PrimaryAdjacency
+ && !adj.isPhysNetworkFunc()) {
+ delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
+ operTx, confTx);
+ Optional<VpnInterfaceOpDataEntry> optVpnInterface = VpnUtil.read(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, vpnInterfaceOpIdentifier);
+ VpnInterfaceOpDataEntry vpnInterfaceOpDataEntry = optVpnInterface.get();
+ long vpnId = VpnUtil.getVpnId(dataBroker, newVpnName);
+ VpnUtil.removePrefixToInterfaceAdj(dataBroker, adj, vpnId,
+ vpnInterfaceOpDataEntry, operTx);
+ //remove FIB entry
+ String vpnRd = VpnUtil.getVpnRd(dataBroker, newVpnName);
+ LOG.debug("update: remove prefix {} from the FIB and BGP entry "
+ + "for the Vpn-Rd {} ", adj.getIpAddress(), vpnRd);
+ //remove BGP entry
+ fibManager.removeFibEntry(vpnRd, adj.getIpAddress(), confTx);
+ if (vpnRd != null && !vpnRd.equalsIgnoreCase(newVpnName)) {
+ bgpManager.withdrawPrefix(vpnRd, adj.getIpAddress());
+ }
+ } else {
+ delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
+ operTx, confTx);
+ }
}
- } else {
- delAdjFromVpnInterface(vpnInterfaceOpIdentifier, adj, dpnId,
- writeOperTxn, writeConfigTxn);
+ LOG.info("update: Adjacency {} with nextHop {} label {} subnet {} removed from"
+ + " vpn interface {} on vpn {}", adj.getIpAddress(), adj
+ .getNextHopIpList(),
+ adj.getLabel(), adj.getSubnetId(), update.getName(), newVpnName);
}
}
- LOG.info("update: Adjacency {} with nextHop {} label {} subnet {} removed from"
- + " vpn interface {} on vpn {}", adj.getIpAddress(), adj.getNextHopIpList(),
- adj.getLabel(), adj.getSubnetId(), update.getName(), newVpnName);
- }
- }
- ListenableFuture<Void> operFuture = writeOperTxn.submit();
- try {
- operFuture.get();
- } catch (ExecutionException e) {
- LOG.error("Exception encountered while submitting operational future for update"
- + " VpnInterface {} on vpn {}", vpnInterfaceName, newVpnName, e);
- return null;
- }
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(writeConfigTxn.submit());
- LOG.info("update: vpn interface updated for interface {} oldVpn(s) {} newVpn {}"
- + "processed successfully", update.getName(),
- VpnHelper.getVpnInterfaceVpnInstanceNamesString(original.getVpnInstanceNames()), newVpnName);
+ }));
+ }));
return futures;
});
} else {
LOG.debug("Processing the vpnInterface{} for the Ajacency:{}", vpnInterface, adjacency);
jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterface.getInterfaceName(),
() -> {
- WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
- WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
+ // TODO Deal with sequencing — the config tx must only submitted if the oper tx goes in
if (VpnUtil.isAdjacencyEligibleToVpn(dataBroker, adjacency, vpnName)) {
- addNewAdjToVpnInterface(existingVpnInterfaceId, primaryRd, adjacency,
- vpnInterfaceOptional.get().getDpnId(), writeConfigTxn, writeOperTxn);
- ListenableFuture<Void> operFuture = writeOperTxn.submit();
- try {
- operFuture.get();
- } catch (ExecutionException | InterruptedException e) {
- LOG.error("Exception encountered while submitting operational"
- + " future for vpnInterface {}", vpnInterface, e);
- }
List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(writeConfigTxn.submit());
+ futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(operTx -> futures.add(
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+ confTx -> addNewAdjToVpnInterface(existingVpnInterfaceId, primaryRd,
+ adjacency, vpnInterfaceOptional.get().getDpnId(), confTx,
+ operTx)))));
return futures;
- } else {
+ } else {
return Collections.emptyList();
}
});
package org.opendaylight.netvirt.vpnmanager;
import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesOp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
VpnInterfaceOpListener> {
private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceOpListener.class);
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final VpnInterfaceManager vpnInterfaceManager;
private final VpnFootprintService vpnFootprintService;
private final JobCoordinator jobCoordinator;
final VpnFootprintService vpnFootprintService, final JobCoordinator jobCoordinator) {
super(VpnInterfaceOpDataEntry.class, VpnInterfaceOpListener.class);
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.vpnInterfaceManager = vpnInterfaceManager;
this.vpnFootprintService = vpnFootprintService;
this.jobCoordinator = jobCoordinator;
VpnInterfaceOpDataEntryKey.class);
final String interfaceName = key.getName();
jobCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
- () -> {
- WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
- postProcessVpnInterfaceRemoval(identifier, del, writeOperTxn);
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(writeOperTxn.submit());
+ () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ postProcessVpnInterfaceRemoval(identifier, del, tx);
LOG.info("remove: Removed vpn operational data for interface {} on dpn {} vpn {}", del.getName(),
del.getDpnId(), del.getVpnInstanceName());
- return futures;
- });
+ })));
}
private void postProcessVpnInterfaceRemoval(InstanceIdentifier<VpnInterfaceOpDataEntry> identifier,
VpnInterfaceOpDataEntry del, WriteTransaction writeOperTxn) {
+ if (writeOperTxn == null) {
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ postProcessVpnInterfaceRemoval(identifier, del, tx)), LOG,
+ "Error post-processing VPN interface removal");
+ return;
+ }
final VpnInterfaceOpDataEntryKey key = identifier.firstKeyOf(VpnInterfaceOpDataEntry.class,
VpnInterfaceOpDataEntryKey.class);
String interfaceName = key.getName();
VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName));
if (vpnInstance.isPresent()) {
- String rd = null;
- rd = vpnInstance.get().getVrfId();
+ String rd = vpnInstance.get().getVrfId();
VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(dataBroker, rd);
*/
for (Prefixes pref : prefixToInterface) {
if (VpnUtil.isMatchedPrefixToInterface(pref, del)) {
- if (writeOperTxn != null) {
- writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()));
- } else {
- VpnUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()),
- VpnUtil.DEFAULT_CALLBACK);
- }
+ writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(), pref.getIpAddress()));
}
}
}
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
public void addExtraRoute(String vpnName, String destination, String nextHop, String rd, String routerID,
Long l3vni, RouteOrigin origin, String intfName, Adjacency operationalAdj,
VrfEntry.EncapType encapType, WriteTransaction writeConfigTxn) {
-
- Boolean writeConfigTxnPresent = true;
if (writeConfigTxn == null) {
- writeConfigTxnPresent = false;
- writeConfigTxn = dataBroker.newWriteOnlyTransaction();
+ String finalNextHop = nextHop;
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ addExtraRoute(vpnName, destination, finalNextHop, rd, routerID, l3vni, origin, intfName, operationalAdj,
+ encapType, tx)),
+ LOG, "Error adding extra route");
+ return;
}
//add extra route to vpn mapping; advertise with nexthop as tunnel ip
}
}
}
-
- if (!writeConfigTxnPresent) {
- writeConfigTxn.submit();
- }
}
@Override
@Override
public void delExtraRoute(String vpnName, String destination, String nextHop, String rd, String routerID,
String intfName, WriteTransaction writeConfigTxn) {
- Boolean writeConfigTxnPresent = true;
- BigInteger dpnId = null;
if (writeConfigTxn == null) {
- writeConfigTxnPresent = false;
- writeConfigTxn = dataBroker.newWriteOnlyTransaction();
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ delExtraRoute(vpnName, destination, nextHop, rd, routerID, intfName, tx)),
+ LOG, "Error deleting extra route");
+ return;
}
+ BigInteger dpnId = null;
String tunnelIp = nextHop;
if (intfName != null && !intfName.isEmpty()) {
dpnId = InterfaceUtils.getDpnForInterface(ifaceMgrRpcService, intfName);
LOG.info("delExtraRoute: Removed extra route {} from interface {} for rd {}", destination, intfName,
routerID);
}
- if (!writeConfigTxnPresent) {
- writeConfigTxn.submit();
- }
}
// TODO Clean up the exception handling
@Override
public boolean isVPNConfigured() {
InstanceIdentifier<VpnInstances> vpnsIdentifier = InstanceIdentifier.builder(VpnInstances.class).build();
- Optional<VpnInstances> optionalVpns = TransactionUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
- vpnsIdentifier);
- if (!optionalVpns.isPresent()
- || optionalVpns.get().getVpnInstance() == null
- || optionalVpns.get().getVpnInstance().isEmpty()) {
- LOG.trace("isVPNConfigured: No VPNs configured.");
- return false;
+ try {
+ Optional<VpnInstances> optionalVpns =
+ SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
+ vpnsIdentifier);
+ if (!optionalVpns.isPresent()
+ || optionalVpns.get().getVpnInstance() == null
+ || optionalVpns.get().getVpnInstance().isEmpty()) {
+ LOG.trace("isVPNConfigured: No VPNs configured.");
+ return false;
+ }
+ } catch (ReadFailedException e) {
+ throw new RuntimeException("Error reading VPN " + vpnsIdentifier, e);
}
LOG.trace("isVPNConfigured: VPNs are configured on the system.");
return true;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncClusteredDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.FlowEntity;
import org.opendaylight.genius.mdsalutil.InstructionInfo;
private static final String FLOWID_PREFIX = "L3.";
private final DataBroker broker;
+ private final ManagedNewTransactionRunner txRunner;
private final IMdsalApiManager mdsalManager;
private final JobCoordinator jobCoordinator;
private final List<BigInteger> connectedDpnIds;
public VpnNodeListener(DataBroker dataBroker, IMdsalApiManager mdsalManager, JobCoordinator jobCoordinator) {
super(Node.class, VpnNodeListener.class);
this.broker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.mdsalManager = mdsalManager;
this.jobCoordinator = jobCoordinator;
this.connectedDpnIds = new CopyOnWriteArrayList<>();
private void processNodeAdd(BigInteger dpId) {
jobCoordinator.enqueueJob("VPNNODE-" + dpId.toString(),
- () -> {
- WriteTransaction writeFlowTx = broker.newWriteOnlyTransaction();
+ () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
LOG.debug("Received notification to install TableMiss entries for dpn {} ", dpId);
- makeTableMissFlow(writeFlowTx, dpId, NwConstants.ADD_FLOW);
- makeL3IntfTblMissFlow(writeFlowTx, dpId, NwConstants.ADD_FLOW);
- makeSubnetRouteTableMissFlow(writeFlowTx, dpId, NwConstants.ADD_FLOW);
- createTableMissForVpnGwFlow(writeFlowTx, dpId);
- createL3GwMacArpFlows(writeFlowTx, dpId);
- programTableMissForVpnVniDemuxTable(writeFlowTx, dpId, NwConstants.ADD_FLOW);
- return Collections.singletonList(writeFlowTx.submit());
- }, 3);
+ makeTableMissFlow(tx, dpId, NwConstants.ADD_FLOW);
+ makeL3IntfTblMissFlow(tx, dpId, NwConstants.ADD_FLOW);
+ makeSubnetRouteTableMissFlow(tx, dpId, NwConstants.ADD_FLOW);
+ createTableMissForVpnGwFlow(tx, dpId);
+ createL3GwMacArpFlows(tx, dpId);
+ programTableMissForVpnVniDemuxTable(tx, dpId, NwConstants.ADD_FLOW);
+ })), 3);
}
private void makeTableMissFlow(WriteTransaction writeFlowTx, BigInteger dpnId, int addOrRemove) {
package org.opendaylight.netvirt.vpnmanager;
import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.concurrent.ExecutionException;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.genius.utils.SystemPropertyReader;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
public class VpnOpStatusListener extends AsyncDataTreeChangeListenerBase<VpnInstanceOpDataEntry, VpnOpStatusListener> {
private static final Logger LOG = LoggerFactory.getLogger(VpnOpStatusListener.class);
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final IBgpManager bgpManager;
private final IdManagerService idManager;
private final IFibManager fibManager;
final JobCoordinator jobCoordinator) {
super(VpnInstanceOpDataEntry.class, VpnOpStatusListener.class);
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.bgpManager = bgpManager;
this.idManager = idManager;
this.fibManager = fibManager;
String primaryRd = update.getVrfId();
final long vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
jobCoordinator.enqueueJob("VPN-" + update.getVpnInstanceName(), () -> {
- WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
- WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
- // Clean up VpnInstanceToVpnId from Config DS
- VpnUtil.removeVpnIdToVpnInstance(dataBroker, vpnId, writeConfigTxn);
- VpnUtil.removeVpnInstanceToVpnId(dataBroker, vpnName, writeConfigTxn);
- LOG.trace("Removed vpnIdentifier for rd{} vpnname {}", primaryRd, vpnName);
-
- // Clean up FIB Entries Config DS
- synchronized (vpnName.intern()) {
- fibManager.removeVrfTable(primaryRd, null);
- }
-
- // Clean up VPNExtraRoutes Operational DS
- if (VpnUtil.isBgpVpn(vpnName, primaryRd)) {
- if (update.getType() == VpnInstanceOpDataEntry.Type.L2) {
- rds.parallelStream().forEach(rd -> bgpManager.deleteVrf(rd, false, AddressFamily.L2VPN));
+ // Two transactions are used, one for operational, one for config; we only submit the config
+ // transaction if the operational transaction succeeds
+ ListenableFuture<Void> operationalFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(operTx -> {
+ // Clean up VPNExtraRoutes Operational DS
+ if (VpnUtil.isBgpVpn(vpnName, primaryRd)) {
+ if (update.getType() == VpnInstanceOpDataEntry.Type.L2) {
+ rds.parallelStream().forEach(rd -> bgpManager.deleteVrf(rd, false, AddressFamily.L2VPN));
+ }
+ if (update.isIpv4Configured()) {
+ rds.parallelStream().forEach(rd -> bgpManager.deleteVrf(rd, false, AddressFamily.IPV4));
+ }
+ if (update.isIpv6Configured()) {
+ rds.parallelStream().forEach(rd -> bgpManager.deleteVrf(rd, false, AddressFamily.IPV6));
+ }
}
- if (update.isIpv4Configured()) {
- rds.parallelStream().forEach(rd -> bgpManager.deleteVrf(rd, false, AddressFamily.IPV4));
+ InstanceIdentifier<Vpn> vpnToExtraroute =
+ VpnExtraRouteHelper.getVpnToExtrarouteVpnIdentifier(vpnName);
+ Optional<Vpn> optVpnToExtraroute = VpnUtil.read(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, vpnToExtraroute);
+ if (optVpnToExtraroute.isPresent()) {
+ VpnUtil.removeVpnExtraRouteForVpn(vpnName, operTx);
}
- if (update.isIpv6Configured()) {
- rds.parallelStream().forEach(rd -> bgpManager.deleteVrf(rd, false, AddressFamily.IPV6));
+
+ if (VpnUtil.isL3VpnOverVxLan(update.getL3vni())) {
+ VpnUtil.removeExternalTunnelDemuxFlows(vpnName, dataBroker, mdsalManager);
}
- }
- InstanceIdentifier<Vpn> vpnToExtraroute = VpnExtraRouteHelper.getVpnToExtrarouteVpnIdentifier(vpnName);
- Optional<Vpn> optVpnToExtraroute = VpnUtil.read(dataBroker,
- LogicalDatastoreType.OPERATIONAL, vpnToExtraroute);
- if (optVpnToExtraroute.isPresent()) {
- VpnUtil.removeVpnExtraRouteForVpn(dataBroker, vpnName, writeOperTxn);
- }
- if (VpnUtil.isL3VpnOverVxLan(update.getL3vni())) {
- VpnUtil.removeExternalTunnelDemuxFlows(vpnName, dataBroker, mdsalManager);
- }
+ // Clean up PrefixToInterface Operational DS
+ Optional<VpnIds> optPrefixToIntf = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getPrefixToInterfaceIdentifier(vpnId));
+ if (optPrefixToIntf.isPresent()) {
+ VpnUtil.removePrefixToInterfaceForVpnId(vpnId, operTx);
+ }
- // Clean up PrefixToInterface Operational DS
- Optional<VpnIds> optPrefixToIntf = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getPrefixToInterfaceIdentifier(vpnId));
- if (optPrefixToIntf.isPresent()) {
- VpnUtil.removePrefixToInterfaceForVpnId(dataBroker, vpnId, writeOperTxn);
- }
+ // Clean up L3NextHop Operational DS
+ InstanceIdentifier<VpnNexthops> vpnNextHops = InstanceIdentifier.builder(L3nexthop.class).child(
+ VpnNexthops.class, new VpnNexthopsKey(vpnId)).build();
+ Optional<VpnNexthops> optL3nexthopForVpnId = VpnUtil.read(dataBroker,
+ LogicalDatastoreType.OPERATIONAL,
+ vpnNextHops);
+ if (optL3nexthopForVpnId.isPresent()) {
+ VpnUtil.removeL3nexthopForVpnId(vpnId, operTx);
+ }
- // Clean up L3NextHop Operational DS
- InstanceIdentifier<VpnNexthops> vpnNextHops = InstanceIdentifier.builder(L3nexthop.class).child(
- VpnNexthops.class, new VpnNexthopsKey(vpnId)).build();
- Optional<VpnNexthops> optL3nexthopForVpnId = VpnUtil.read(dataBroker,
- LogicalDatastoreType.OPERATIONAL,
- vpnNextHops);
- if (optL3nexthopForVpnId.isPresent()) {
- VpnUtil.removeL3nexthopForVpnId(dataBroker, vpnId, writeOperTxn);
- }
+ // Clean up VPNInstanceOpDataEntry
+ VpnUtil.removeVpnOpInstance(primaryRd, operTx);
+ });
- // Clean up VPNInstanceOpDataEntry
- VpnUtil.removeVpnOpInstance(dataBroker, primaryRd, writeOperTxn);
+ Futures.addCallback(operationalFuture, new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(Void result) {
+ Futures.addCallback(txRunner.callWithNewWriteOnlyTransactionAndSubmit(confTx -> {
+ // Clean up VpnInstanceToVpnId from Config DS
+ VpnUtil.removeVpnIdToVpnInstance(vpnId, confTx);
+ VpnUtil.removeVpnInstanceToVpnId(vpnName, confTx);
+ LOG.trace("Removed vpnIdentifier for rd{} vpnname {}", primaryRd, vpnName);
- // Note: Release the of VpnId will happen in PostDeleteVpnInstancWorker only if
- // operationalTxn/Config succeeds.
+ // Clean up FIB Entries Config DS
+ synchronized (vpnName.intern()) {
+ fibManager.removeVrfTable(primaryRd, confTx);
+ }
+ }), new VpnOpStatusListener.PostDeleteVpnInstanceWorker(vpnName),
+ MoreExecutors.directExecutor());
+ // Note: Release the of VpnId will happen in PostDeleteVpnInstancWorker only if
+ // operationalTxn/Config succeeds.
+ }
+
+ @Override
+ public void onFailure(Throwable throwable) {
+ LOG.error("Error deleting VPN {}", vpnName, throwable);
+ }
+ }, MoreExecutors.directExecutor());
- CheckedFuture<Void, TransactionCommitFailedException> checkFutures = writeOperTxn.submit();
- try {
- checkFutures.get();
- } catch (InterruptedException | ExecutionException e) {
- LOG.error("Error deleting vpn {} ", vpnName);
- writeConfigTxn.cancel();
- throw new RuntimeException(e);
- }
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(writeConfigTxn.submit());
- ListenableFuture<List<Void>> listenableFuture = Futures.allAsList(futures);
- Futures.addCallback(listenableFuture, new VpnOpStatusListener.PostDeleteVpnInstanceWorker(vpnName));
LOG.info("Removed vpn data for vpnname {}", vpnName);
- return futures;
+ return Collections.singletonList(operationalFuture);
}, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
} else if (update.getVpnState() == VpnInstanceOpDataEntry.VpnState.Created) {
final String vpnName = update.getVpnInstanceName();
return;
}
jobCoordinator.enqueueJob("VPN-" + update.getVpnInstanceName(), () -> {
- WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
- long primaryRdAddFailed = rds.parallelStream().filter(rd -> {
+ rds.parallelStream().forEach(rd -> {
try {
LOG.info("VpnOpStatusListener.update: updating BGPVPN for vpn {} with RD {}"
+ " Type is {}, IPv4 is {}, IPv6 is {}", vpnName, primaryRd, update.getType(),
} catch (Exception e) {
LOG.error("VpnOpStatusListener.update: Exception when updating VRF to BGP"
+ " for vpn {} rd {}", vpnName, rd);
- return false;
}
- return false;
- }).count();
+ });
return Collections.emptyList();
});
}
LOG.debug("add: Ignoring vpn Op {} with rd {}", value.getVpnInstanceName(), value.getVrfId());
}
- private class PostDeleteVpnInstanceWorker implements FutureCallback<List<Void>> {
+ private class PostDeleteVpnInstanceWorker implements FutureCallback<Void> {
private final Logger log = LoggerFactory.getLogger(VpnOpStatusListener.PostDeleteVpnInstanceWorker.class);
String vpnName;
* Release the ID used for VPN back to IdManager
*/
@Override
- public void onSuccess(List<Void> voids) {
+ public void onSuccess(Void ignored) {
VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME, vpnName);
log.info("onSuccess: VpnId for VpnName {} is released to IdManager successfully.", vpnName);
}
import com.google.common.base.Optional;
import com.google.common.collect.Iterators;
import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.FlowEntity;
import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
import org.opendaylight.genius.utils.ServiceIndex;
import org.opendaylight.genius.utils.SystemPropertyReader;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
import org.opendaylight.netvirt.fibmanager.api.FibHelper;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.impl.schema.tree.SchemaValidationFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Optional<VrfTables> vrfTablesOpc = read(broker, LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid);
if (vrfTablesOpc.isPresent()) {
VrfTables vrfTables = vrfTablesOpc.get();
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- for (VrfEntry vrfEntry : vrfTables.getVrfEntry()) {
- if (origin == RouteOrigin.value(vrfEntry.getOrigin())) {
- tx.delete(LogicalDatastoreType.CONFIGURATION,
- vpnVrfTableIid.child(VrfEntry.class, vrfEntry.getKey()));
- }
- }
- tx.submit();
+ ListenableFutures.addErrorLogging(
+ new ManagedNewTransactionRunnerImpl(broker).callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ for (VrfEntry vrfEntry : vrfTables.getVrfEntry()) {
+ if (origin == RouteOrigin.value(vrfEntry.getOrigin())) {
+ tx.delete(LogicalDatastoreType.CONFIGURATION,
+ vpnVrfTableIid.child(VrfEntry.class, vrfEntry.getKey()));
+ }
+ }
+ }), LOG, "Error removing VRF entries by origin");
}
}
public static void removeVrfEntries(DataBroker broker, String rd, List<VrfEntry> vrfEntries) {
InstanceIdentifier<VrfTables> vpnVrfTableIid =
InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build();
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- for (VrfEntry vrfEntry : vrfEntries) {
- tx.delete(LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid.child(VrfEntry.class, vrfEntry.getKey()));
- }
- tx.submit();
+ ListenableFutures.addErrorLogging(
+ new ManagedNewTransactionRunnerImpl(broker).callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ for (VrfEntry vrfEntry : vrfEntries) {
+ tx.delete(LogicalDatastoreType.CONFIGURATION,
+ vpnVrfTableIid.child(VrfEntry.class, vrfEntry.getKey()));
+ }
+ }), LOG, "Error removing VRF entries");
}
// TODO Clean up the exception handling
};
+ @Deprecated
public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path) {
try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
}
}
- public static <T extends DataObject> void asyncUpdate(DataBroker broker, LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path, T data) {
- asyncUpdate(broker, datastoreType, path, data, DEFAULT_CALLBACK);
- }
-
- public static <T extends DataObject> void asyncUpdate(DataBroker broker, LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.merge(datastoreType, path, data, true);
- Futures.addCallback(tx.submit(), callback, MoreExecutors.directExecutor());
- }
-
- public static <T extends DataObject> void asyncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path, T data) {
- asyncWrite(broker, datastoreType, path, data, DEFAULT_CALLBACK);
- }
-
- public static <T extends DataObject> void asyncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.put(datastoreType, path, data, WriteTransaction.CREATE_MISSING_PARENTS);
- Futures.addCallback(tx.submit(), callback, MoreExecutors.directExecutor());
- }
-
- // TODO Clean up the exception handling
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static <T extends DataObject> void tryDelete(DataBroker broker, LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path) {
- try {
- delete(broker, datastoreType, path, DEFAULT_CALLBACK);
- } catch (SchemaValidationFailedException sve) {
- LOG.info("tryDelete: Could not delete {}. SchemaValidationFailedException: {}", path, sve.getMessage());
- } catch (Exception e) {
- LOG.info("tryDelete: Could not delete {}. Unhandled error: {}", path, e.getMessage());
- }
- }
-
- public static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path) {
- delete(broker, datastoreType, path, DEFAULT_CALLBACK);
- }
-
-
- public static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path, FutureCallback<Void> callback) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.delete(datastoreType, path);
- Futures.addCallback(tx.submit(), callback, MoreExecutors.directExecutor());
- }
-
+ @Deprecated
public static <T extends DataObject> void syncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path, T data) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.put(datastoreType, path, data, WriteTransaction.CREATE_MISSING_PARENTS);
-
try {
- tx.submit().get();
- } catch (InterruptedException | ExecutionException e) {
- LOG.error("syncWrite: Error writing to datastore (path, data) : ({}, {})", path, data);
+ SingleTransactionDataBroker.syncWrite(broker, datastoreType, path, data);
+ } catch (TransactionCommitFailedException e) {
+ LOG.error("syncWrite: Error writing to datastore (path, data) : ({}, {})", path, data, e);
throw new RuntimeException(e.getMessage(), e);
}
}
+ @Deprecated
public static <T extends DataObject> void syncUpdate(DataBroker broker, LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path, T data) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.merge(datastoreType, path, data, true);
-
try {
- tx.submit().get();
- } catch (InterruptedException | ExecutionException e) {
- LOG.error("syncUpdate: Error writing to datastore (path, data) : ({}, {})", path, data);
+ SingleTransactionDataBroker.syncUpdate(broker, datastoreType, path, data);
+ } catch (TransactionCommitFailedException e) {
+ LOG.error("syncUpdate: Error writing to datastore (path, data) : ({}, {})", path, data, e);
throw new RuntimeException(e.getMessage(), e);
}
}
.build();
}
- // TODO Clean up the exception handling
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static void removePrefixToInterfaceForVpnId(DataBroker broker, long vpnId, WriteTransaction writeTxn) {
- try {
- // Clean up PrefixToInterface Operational DS
- if (writeTxn != null) {
- writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.builder(PrefixToInterface.class).child(
- VpnIds.class, new VpnIdsKey(vpnId)).build());
- } else {
- delete(broker, LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class,
- new VpnIdsKey(vpnId)).build(),
- DEFAULT_CALLBACK);
- }
- } catch (Exception e) {
- LOG.error("removePrefixToInterfaceForVpnId: Exception during cleanup of PrefixToInterface for VPN ID {}",
- vpnId, e);
- }
- }
-
- // TODO Clean up the exception handling
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static void removeVpnExtraRouteForVpn(DataBroker broker, String vpnName, WriteTransaction writeTxn) {
- try {
- // Clean up VPNExtraRoutes Operational DS
- if (writeTxn != null) {
- writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.builder(VpnToExtraroutes.class)
- .child(Vpn.class, new VpnKey(vpnName)).build());
- } else {
- delete(broker, LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.builder(VpnToExtraroutes.class)
- .child(Vpn.class, new VpnKey(vpnName)).build(),
- DEFAULT_CALLBACK);
- }
- } catch (Exception e) {
- LOG.error("removeVpnExtraRouteForVpna: Exception during cleanup of VPNToExtraRoute for VPN {}",
- vpnName, e);
- }
+ public static void removePrefixToInterfaceForVpnId(long vpnId, @Nonnull WriteTransaction operTx) {
+ // Clean up PrefixToInterface Operational DS
+ operTx.delete(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class, new VpnIdsKey(vpnId)).build());
}
- // TODO Clean up the exception handling
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static void removeVpnOpInstance(DataBroker broker, String vpnName, WriteTransaction writeTxn) {
- try {
- // Clean up VPNInstanceOpDataEntry
- if (writeTxn != null) {
- writeTxn.delete(LogicalDatastoreType.OPERATIONAL, getVpnInstanceOpDataIdentifier(vpnName));
- } else {
- delete(broker, LogicalDatastoreType.OPERATIONAL, getVpnInstanceOpDataIdentifier(vpnName),
- DEFAULT_CALLBACK);
- }
- } catch (Exception e) {
- LOG.error("removeVpnOpInstance: Exception during cleanup of VPNInstanceOpDataEntry for VPN {}",
- vpnName, e);
- }
+ public static void removeVpnExtraRouteForVpn(String vpnName, @Nonnull WriteTransaction operTx) {
+ // Clean up VPNExtraRoutes Operational DS
+ operTx.delete(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(VpnToExtraroutes.class).child(Vpn.class, new VpnKey(vpnName)).build());
}
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
- public static void removeVpnInstanceToVpnId(DataBroker broker, String vpnName, WriteTransaction writeTxn) {
- try {
- if (writeTxn != null) {
- writeTxn.delete(LogicalDatastoreType.CONFIGURATION,
- VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName));
- } else {
- delete(broker, LogicalDatastoreType.CONFIGURATION,
- VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName),
- DEFAULT_CALLBACK);
- }
- } catch (Exception e) {
- LOG.error("removeVpnInstanceToVpnId: Exception during clean up of VpnInstanceToVpnId for VPN {}",
- vpnName, e);
- }
+ public static void removeVpnOpInstance(String vpnName, @Nonnull WriteTransaction operTx) {
+ // Clean up VPNInstanceOpDataEntry
+ operTx.delete(LogicalDatastoreType.OPERATIONAL, getVpnInstanceOpDataIdentifier(vpnName));
}
- // TODO Clean up the exception handling
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static void removeVpnIdToVpnInstance(DataBroker broker, long vpnId, WriteTransaction writeTxn) {
- try {
- if (writeTxn != null) {
- writeTxn.delete(LogicalDatastoreType.CONFIGURATION, getVpnIdToVpnInstanceIdentifier(vpnId));
- } else {
- delete(broker, LogicalDatastoreType.CONFIGURATION, getVpnIdToVpnInstanceIdentifier(vpnId),
- DEFAULT_CALLBACK);
- }
- } catch (Exception e) {
- LOG.error("removeVpnIdToVpnInstance: Exception during clean up of VpnIdToVpnInstance for VPNID {}",
- vpnId, e);
- }
+ public static void removeVpnInstanceToVpnId(String vpnName, @Nonnull WriteTransaction confTx) {
+ confTx.delete(LogicalDatastoreType.CONFIGURATION, VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName));
}
- // TODO Clean up the exception handling
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static void removeVrfTableForVpn(DataBroker broker, String vpnName, WriteTransaction writeTxn) {
- // Clean up FIB Entries Config DS
- try {
- if (writeTxn != null) {
- writeTxn.delete(LogicalDatastoreType.CONFIGURATION,
- InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class,
- new VrfTablesKey(vpnName)).build());
- } else {
- delete(broker, LogicalDatastoreType.CONFIGURATION,
- InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class,
- new VrfTablesKey(vpnName)).build(),
- DEFAULT_CALLBACK);
- }
- } catch (Exception e) {
- LOG.error("removeVrfTableForVpn: Exception during clean up of VrfTable from FIB for VPN {}",
- vpnName, e);
- }
+ public static void removeVpnIdToVpnInstance(long vpnId, @Nonnull WriteTransaction confTx) {
+ confTx.delete(LogicalDatastoreType.CONFIGURATION, getVpnIdToVpnInstanceIdentifier(vpnId));
}
- // TODO Clean up the exception handling
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static void removeL3nexthopForVpnId(DataBroker broker, long vpnId, WriteTransaction writeTxn) {
- try {
- // Clean up L3NextHop Operational DS
- if (writeTxn != null) {
- writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class,
- new VpnNexthopsKey(vpnId)).build());
- } else {
- delete(broker, LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class,
- new VpnNexthopsKey(vpnId)).build(),
- DEFAULT_CALLBACK);
- }
- } catch (Exception e) {
- LOG.error("removeL3nexthopForVpnId: Exception during cleanup of L3NextHop for VPN ID {}", vpnId, e);
- }
+ public static void removeL3nexthopForVpnId(long vpnId, @Nonnull WriteTransaction operTx) {
+ // Clean up L3NextHop Operational DS
+ operTx.delete(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class, new VpnNexthopsKey(vpnId)).build());
}
public static void scheduleVpnInterfaceForRemoval(DataBroker broker,String interfaceName, BigInteger dpnId,
static void bindService(final String vpnInstanceName, final String interfaceName, DataBroker dataBroker,
boolean isTunnelInterface, JobCoordinator jobCoordinator) {
jobCoordinator.enqueueJob(interfaceName,
- () -> {
- WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
- BoundServices serviceInfo = isTunnelInterface
- ? VpnUtil.getBoundServicesForTunnelInterface(vpnInstanceName, interfaceName)
- : getBoundServicesForVpnInterface(dataBroker, vpnInstanceName, interfaceName);
- writeTxn.put(LogicalDatastoreType.CONFIGURATION, InterfaceUtils.buildServiceId(interfaceName,
- ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX)),
- serviceInfo, WriteTransaction.CREATE_MISSING_PARENTS);
- return Collections.singletonList(writeTxn.submit());
- }, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
+ () -> Collections.singletonList(
+ new ManagedNewTransactionRunnerImpl(dataBroker).callWithNewReadWriteTransactionAndSubmit(tx -> {
+ BoundServices serviceInfo = isTunnelInterface
+ ? VpnUtil.getBoundServicesForTunnelInterface(vpnInstanceName, interfaceName)
+ : getBoundServicesForVpnInterface(dataBroker, vpnInstanceName, interfaceName);
+ tx.put(LogicalDatastoreType.CONFIGURATION, InterfaceUtils.buildServiceId(interfaceName,
+ ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME,
+ NwConstants.L3VPN_SERVICE_INDEX)),
+ serviceInfo, WriteTransaction.CREATE_MISSING_PARENTS);
+ })), SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
}
static BoundServices getBoundServicesForVpnInterface(DataBroker broker, String vpnName, String interfaceName) {
JobCoordinator jobCoordinator) {
if (!isInterfaceStateDown) {
jobCoordinator.enqueueJob(vpnInterfaceName,
- () -> {
- WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
- writeTxn.delete(LogicalDatastoreType.CONFIGURATION,
- InterfaceUtils.buildServiceId(vpnInterfaceName,
- ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME,
- NwConstants.L3VPN_SERVICE_INDEX)));
-
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- futures.add(writeTxn.submit());
- return futures;
- }, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
+ () -> Collections.singletonList(new ManagedNewTransactionRunnerImpl(
+ dataBroker).callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ tx.delete(LogicalDatastoreType.CONFIGURATION,
+ InterfaceUtils.buildServiceId(vpnInterfaceName,
+ ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME,
+ NwConstants.L3VPN_SERVICE_INDEX))))),
+ SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
}
}
public static void removePrefixToInterfaceAdj(DataBroker dataBroker, Adjacency adj, long vpnId,
VpnInterfaceOpDataEntry vpnInterfaceOpDataEntry,
WriteTransaction writeOperTxn) {
+ if (writeOperTxn == null) {
+ ListenableFutures.addErrorLogging(
+ new ManagedNewTransactionRunnerImpl(dataBroker).callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ removePrefixToInterfaceAdj(dataBroker, adj, vpnId, vpnInterfaceOpDataEntry, tx)), LOG,
+ "Error removing prefix");
+ return;
+ }
+
Optional<Prefixes> prefix = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
VpnUtil.getPrefixToInterfaceIdentifier(vpnId,
VpnUtil.getIpPrefix(adj.getIpAddress())));
}
for (Prefixes pref : prefixToInterface) {
if (VpnUtil.isMatchedPrefixToInterface(pref, vpnInterfaceOpDataEntry)) {
- if (writeOperTxn != null) {
- writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getPrefixToInterfaceIdentifier(vpnId, pref.getIpAddress()));
- } else {
- VpnUtil.delete(dataBroker, LogicalDatastoreType.OPERATIONAL,
- VpnUtil.getPrefixToInterfaceIdentifier(vpnId, pref.getIpAddress()),
- VpnUtil.DEFAULT_CALLBACK);
- }
+ writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
+ VpnUtil.getPrefixToInterfaceIdentifier(vpnId, pref.getIpAddress()));
}
}
}
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
import org.opendaylight.netvirt.fibmanager.api.FibHelper;
import org.opendaylight.netvirt.fibmanager.api.IFibManager;
private static final Logger LOG = LoggerFactory.getLogger(IVpnLinkServiceImpl.class);
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final IdManagerService idManager;
private final IBgpManager bgpManager;
private final IFibManager fibManager;
public IVpnLinkServiceImpl(final DataBroker dataBroker, final IdManagerService idMgr, final IBgpManager bgpMgr,
final IFibManager fibMgr, final InterVpnLinkCache interVpnLinkCache) {
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.idManager = idMgr;
this.bgpManager = bgpMgr;
this.fibManager = fibMgr;
.child(VrfTables.class, new VrfTablesKey(dstVpnRd))
.child(VrfEntry.class, new VrfEntryKey(newVrfEntry.getDestPrefix()))
.build();
- VpnUtil.asyncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, newVrfEntryIid, newVrfEntry);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ tx.put(LogicalDatastoreType.CONFIGURATION, newVrfEntryIid, newVrfEntry)),
+ LOG, "Error adding VRF entry {}", newVrfEntry);
// Finally, route is advertised it to the DC-GW. But while in the FibEntries the nexthop is the other
// endpoint's IP, in the DC-GW the nexthop for those prefixes are the IPs of those DPNs where the target
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
import org.opendaylight.netvirt.fibmanager.api.IFibManager;
import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
private static final long INVALID_ID = 0;
private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final IMdsalApiManager mdsalManager;
private final IdManagerService idManager;
private final IBgpManager bgpManager;
final JobCoordinator jobCoordinator,
final InterVpnLinkCache interVpnLinkCache) {
this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.idManager = idManager;
this.mdsalManager = mdsalManager;
this.bgpManager = bgpManager;
// Removing the InterVpnLinkState
InstanceIdentifier<InterVpnLinkState> interVpnLinkStateIid =
InterVpnLinkUtil.getInterVpnLinkStateIid(del.getName());
- VpnUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid);
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ tx.delete(LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid)), LOG,
+ "Error deleting inter-VPN link state {}", interVpnLinkStateIid);
}
// We're catching Exception here to continue deleting as much as possible
new InterVpnLinkStateBuilder(vpnLinkState).setState(InterVpnLinkState.State.Error)
.setErrorDescription(errorMsg)
.build();
- WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- tx.put(LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkErrorState,
- WriteTransaction.CREATE_MISSING_PARENTS);
- tx.submit();
+ ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ tx.put(LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid, vpnLinkErrorState,
+ WriteTransaction.CREATE_MISSING_PARENTS)),
+ LOG, "Error storing the VPN link error state for {}, {}", vpnLinkStateIid, vpnLinkErrorState);
// Sending out an error Notification
InterVpnLinkCreationErrorMessage errMsg =
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.netvirt.vpnmanager.VpnFootprintService;
import org.opendaylight.netvirt.vpnmanager.VpnUtil;
private static final String NBR_OF_DPNS_PROPERTY_NAME = "vpnservice.intervpnlink.number.dpns";
private final DataBroker broker;
+ private final ManagedNewTransactionRunner txRunner;
private final BigInteger dpnId;
private final IMdsalApiManager mdsalManager;
private final VpnFootprintService vpnFootprintService;
final VpnFootprintService vpnFootprintService, final BigInteger dpnId,
final InterVpnLinkCache interVpnLinkCache) {
this.broker = broker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(broker);
this.mdsalManager = mdsalMgr;
this.vpnFootprintService = vpnFootprintService;
this.dpnId = dpnId;
new InterVpnLinkStateBuilder(interVpnLinkState).setState(InterVpnLinkState.State.Active)
.setFirstEndpointState(firstEndPointState).setSecondEndpointState(secondEndPointState)
.build();
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.merge(LogicalDatastoreType.CONFIGURATION,
- InterVpnLinkUtil.getInterVpnLinkStateIid(interVpnLinkState.getInterVpnLinkName()), newInterVpnLinkState,
- true);
- return tx.submit();
+ return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ tx.merge(LogicalDatastoreType.CONFIGURATION,
+ InterVpnLinkUtil.getInterVpnLinkStateIid(interVpnLinkState.getInterVpnLinkName()),
+ newInterVpnLinkState, WriteTransaction.CREATE_MISSING_PARENTS));
}
private void installLPortDispatcherTable(InterVpnLinkState interVpnLinkState, List<BigInteger> firstDpnList,
package org.opendaylight.netvirt.vpnmanager.intervpnlink;
import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.ListenableFuture;
import java.math.BigInteger;
import java.util.ArrayList;
import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
import org.opendaylight.genius.utils.ServiceIndex;
import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
-import org.opendaylight.netvirt.fibmanager.api.FibHelper;
import org.opendaylight.netvirt.fibmanager.api.IFibManager;
import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
import org.opendaylight.netvirt.vpnmanager.VpnConstants;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkStates;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkState;
: new ArrayList<>();
}
- /**
- * Leaks a route from one VPN to another. By default, the origin for this leaked route is INTERVPN.
- *
- * @param broker dataBroker service reference
- * @param bgpManager Used to advertise routes to the BGP Router
- * @param interVpnLink Reference to the object that holds the info about the link between the 2 VPNs
- * @param srcVpnUuid UUID of the VPN that has the route that is going to be leaked to the other VPN
- * @param dstVpnUuid UUID of the VPN that is going to receive the route
- * @param prefix Prefix of the route
- * @param label Label of the route in the original VPN
- */
- // TODO Clean up the exception handling
- @SuppressWarnings("checkstyle:IllegalCatch")
- public static void leakRoute(DataBroker broker, IBgpManager bgpManager, InterVpnLink interVpnLink,
- String srcVpnUuid, String dstVpnUuid, String prefix, Long label) {
- Preconditions.checkNotNull(interVpnLink);
-
- // The source VPN must participate in the InterVpnLink
- Preconditions.checkArgument(interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(srcVpnUuid)
- || interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(srcVpnUuid),
- "The source VPN {} does not participate in the interVpnLink {}",
- srcVpnUuid, interVpnLink.getName());
- // The destination VPN must participate in the InterVpnLink
- Preconditions.checkArgument(interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(dstVpnUuid)
- || interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(dstVpnUuid),
- "The destination VPN {} does not participate in the interVpnLink {}",
- dstVpnUuid, interVpnLink.getName());
-
- boolean destinationIs1stEndpoint = interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(dstVpnUuid);
-
- String endpointIp = destinationIs1stEndpoint ? interVpnLink.getSecondEndpoint().getIpAddress().getValue()
- : interVpnLink.getFirstEndpoint().getIpAddress().getValue();
-
- VrfEntry newVrfEntry = FibHelper.getVrfEntryBuilder(prefix, label, endpointIp, RouteOrigin.INTERVPN,
- null /* parentVpnRd */).build();
-
- String dstVpnRd = VpnUtil.getVpnRd(broker, dstVpnUuid);
- InstanceIdentifier<VrfEntry> newVrfEntryIid =
- InstanceIdentifier.builder(FibEntries.class)
- .child(VrfTables.class, new VrfTablesKey(dstVpnRd))
- .child(VrfEntry.class, new VrfEntryKey(newVrfEntry.getDestPrefix()))
- .build();
- VpnUtil.asyncWrite(broker, LogicalDatastoreType.CONFIGURATION, newVrfEntryIid, newVrfEntry);
-
- // Finally, route is advertised it to the DC-GW. But while in the FibEntries the nexthop is the other
- // endpoint's IP, in the DC-GW the nexthop for those prefixes are the IPs of those DPNs where the target
- // VPN has been instantiated
- Optional<InterVpnLinkState> optVpnLinkState = getInterVpnLinkState(broker, interVpnLink.getName());
- if (optVpnLinkState.isPresent()) {
- InterVpnLinkState vpnLinkState = optVpnLinkState.get();
- List<BigInteger> dpnIdList = destinationIs1stEndpoint ? vpnLinkState.getFirstEndpointState().getDpId()
- : vpnLinkState.getSecondEndpointState().getDpId();
- List<String> nexthops = new ArrayList<>();
- for (BigInteger dpnId : dpnIdList) {
- nexthops.add(InterfaceUtils.getEndpointIpAddressForDPN(broker, dpnId));
- }
- try {
- LOG.debug("Advertising route in VPN={} [prefix={} label={} nexthops={}] to DC-GW",
- dstVpnRd, newVrfEntry.getDestPrefix(), label.intValue(), nexthops);
- bgpManager.advertisePrefix(dstVpnRd, null /*macAddress*/, newVrfEntry.getDestPrefix(), nexthops,
- VrfEntry.EncapType.Mplsgre, label.intValue(), 0 /*l3vni*/, 0 /*l2vni*/,
- null /*gatewayMacAddress*/);
- } catch (Exception ex) {
- LOG.error("Could not advertise prefix {} with label {} to VPN rd={}",
- newVrfEntry.getDestPrefix(), label.intValue(), dstVpnRd, ex);
- }
- } else {
- LOG.warn("Error when advertising leaked routes: Could not find State for InterVpnLink={}",
- interVpnLink.getName());
- }
- }
-
public static void handleStaticRoute(InterVpnLinkDataComposite interVpnLink, String vpnName,
String destination, String nexthop, int label,
DataBroker dataBroker, IFibManager fibManager, IBgpManager bgpManager) throws Exception {
package org.opendaylight.netvirt.vpnmanager.intervpnlink.tasks;
import com.google.common.util.concurrent.ListenableFuture;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.netvirt.vpnmanager.intervpnlink.InterVpnLinkUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
import org.slf4j.Logger;
private static final Logger LOG = LoggerFactory.getLogger(InterVpnLinkCreatorTask.class);
- private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
private final InterVpnLink interVpnLinkToPersist;
public InterVpnLinkCreatorTask(DataBroker dataBroker, InterVpnLink interVpnLink) {
- this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.interVpnLinkToPersist = interVpnLink;
}
interVpnLinkToPersist.getSecondEndpoint().getVpnUuid(),
interVpnLinkToPersist.getSecondEndpoint().getIpAddress());
- List<ListenableFuture<Void>> result = new ArrayList<>();
-
- WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
- writeTx.merge(LogicalDatastoreType.CONFIGURATION,
- InterVpnLinkUtil.getInterVpnLinkPath(interVpnLinkToPersist.getName()),
- interVpnLinkToPersist,
- true /* create missing parents */);
- result.add(writeTx.submit());
- return result;
+ return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ tx.merge(LogicalDatastoreType.CONFIGURATION,
+ InterVpnLinkUtil.getInterVpnLinkPath(interVpnLinkToPersist.getName()),
+ interVpnLinkToPersist, WriteTransaction.CREATE_MISSING_PARENTS)));
}
}
import java.util.List;
import java.util.concurrent.Callable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
private final InstanceIdentifier<InterVpnLink> interVpnLinkIid;
private final String interVpnLinkName;
- private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
public InterVpnLinkRemoverTask(DataBroker dataBroker, InstanceIdentifier<InterVpnLink> interVpnLinkPath) {
this.interVpnLinkIid = interVpnLinkPath;
this.interVpnLinkName = interVpnLinkPath.firstKeyOf(InterVpnLink.class).getName();
- this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
}
@Override
public List<ListenableFuture<Void>> call() {
LOG.debug("Removing InterVpnLink {} from storage", interVpnLinkName);
- WriteTransaction removeTx = dataBroker.newWriteOnlyTransaction();
- removeTx.delete(LogicalDatastoreType.CONFIGURATION, this.interVpnLinkIid);
-
- return Collections.singletonList(removeTx.submit());
+ return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
+ tx.delete(LogicalDatastoreType.CONFIGURATION, this.interVpnLinkIid)));
}
}