*/
package org.opendaylight.netvirt.fibmanager;
+import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;
-import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
-import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
import static org.opendaylight.genius.mdsalutil.NWUtil.isIpv4Address;
+import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
+import static org.opendaylight.mdsal.binding.util.Datastore.OPERATIONAL;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.ListenableFuture;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Singleton;
-
import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
-import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.itm.globals.ITMConstants;
import org.opendaylight.genius.mdsalutil.ActionInfo;
import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
import org.opendaylight.netvirt.elanmanager.api.IElanService;
+import org.opendaylight.netvirt.fibmanager.api.FibHelper;
import org.opendaylight.netvirt.fibmanager.api.L3VPNTransportTypes;
import org.opendaylight.netvirt.vpnmanager.api.VpnExtraRouteHelper;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameInputBuilder;
private static final Logger LOG = LoggerFactory.getLogger(NexthopManager.class);
private static final String NEXTHOP_ID_POOL_NAME = "nextHopPointerPool";
private static final long WAIT_TIME_FOR_SYNC_INSTALL = Long.getLong("wait.time.sync.install", 300L);
- private static final long WAIT_TIME_TO_ACQUIRE_LOCK = 3000L;
+ // We set the total wait time for lock to be obtained at 9 seconds since GC pauses can be upto 8 seconds
+ //in scale setups.
+ private static final long WAIT_TIME_TO_ACQUIRE_LOCK = 9000L;
private static final int SELECT_GROUP_WEIGHT = 1;
private static final int RETRY_COUNT = 6;
- private static final String NEXTHOPMANAGER_JOB_KEY_PREFIX = "NextHopManager";
private final DataBroker dataBroker;
private final ManagedNewTransactionRunner txRunner;
ifName, rpcResult.getErrors());
return Collections.emptyList();
} else {
- actions = rpcResult.getResult().nonnullAction();
+ actions = new ArrayList<Action>(rpcResult.getResult().nonnullAction().values());
}
} else {
RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = odlInterfaceRpcService
+ "Errors {}", ifName, vpnId, destIpPrefix, rpcResult.getErrors());
return Collections.emptyList();
} else {
- actions = rpcResult.getResult().nonnullAction();
+ actions = new ArrayList<Action>(rpcResult.getResult().nonnullAction().values());
}
}
List<ActionInfo> listActionInfo = new ArrayList<>();
} else {
// Ignore adding new prefix , if it already exists
- List<IpAdjacencies> prefixesList = nexthop.getIpAdjacencies();
+ Map<IpAdjacenciesKey, IpAdjacencies> keyIpAdjacenciesMap = nexthop.getIpAdjacencies();
IpAdjacencies prefix = new IpAdjacenciesBuilder().setIpAdjacency(currDestIpPrefix).build();
- if (prefixesList != null && prefixesList.contains(prefix)) {
+ if (keyIpAdjacenciesMap != null && keyIpAdjacenciesMap.values().contains(prefix)) {
LOG.trace("Prefix {} is already present in l3nextHop {} ", currDestIpPrefix, nexthop);
} else {
IpAdjacenciesBuilder ipPrefixesBuilder =
InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class,
new VpnNexthopsKey(vpnId));
InstanceIdentifier<VpnNexthops> id = idBuilder.build();
- Optional<VpnNexthops> vpnNexthops = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+ Optional<VpnNexthops> vpnNexthops;
+ try {
+ vpnNexthops = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.OPERATIONAL, id);
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("getVpnNexthop: Exception while reading VpnNexthops DS for the address {} vpn {}", ipAddress,
+ vpnId, e);
+ return null;
+ }
if (vpnNexthops.isPresent()) {
- // get nexthops list for vpn
- List<VpnNexthop> nexthops = vpnNexthops.get().nonnullVpnNexthop();
- for (VpnNexthop nexthop : nexthops) {
+ // get keyVpnNexthopMap list for vpn
+ Map<VpnNexthopKey, VpnNexthop> keyVpnNexthopMap = vpnNexthops.get().nonnullVpnNexthop();
+ for (VpnNexthop nexthop : keyVpnNexthopMap.values()) {
if (Objects.equals(nexthop.getIpAddress(), ipAddress)) {
// return nexthop
LOG.trace("VpnNextHop : {}", nexthop);
if (FibUtil.lockCluster(lockManager, nextHopLockStr, WAIT_TIME_TO_ACQUIRE_LOCK)) {
VpnNexthop nh = getVpnNexthop(vpnId, primaryIpAddress);
if (nh != null) {
- List<IpAdjacencies> prefixesList = new ArrayList<>(nh.nonnullIpAdjacencies());
+ List<IpAdjacencies> prefixesList = new ArrayList<IpAdjacencies>(nh.nonnullIpAdjacencies().values());
IpAdjacencies prefix = new IpAdjacenciesBuilder().setIpAdjacency(currDestIpPrefix).build();
prefixesList.remove(prefix);
if (prefixesList.isEmpty()) { //remove the group only if there are no more flows using this group
* if the value is Unset, cache value as VxLAN.
*/
LOG.trace("configureTransportType is not yet set.");
- Optional<ConfTransportTypeL3vpn> configuredTransTypeFromConfig =
- MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, getConfTransportTypeIdentifier());
-
+ Optional<ConfTransportTypeL3vpn> configuredTransTypeFromConfig;
+ try {
+ configuredTransTypeFromConfig = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.CONFIGURATION, getConfTransportTypeIdentifier());
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("getReqTransType: Exception while reading ConfTransportTypeL3vpn DS", e);
+ return null;
+ }
if (configuredTransTypeFromConfig.isPresent()) {
if (TunnelTypeGre.class.equals(configuredTransTypeFromConfig.get().getTransportType())) {
configuredTransportTypeL3VPN = L3VPNTransportTypes.GRE;
public void createDcGwLoadBalancingGroup(Uint64 dpnId, String destinationIp,
Class<? extends TunnelTypeBase> tunnelType) {
- jobCoordinator.enqueueJob(getJobKey(dpnId), () -> {
- List<ListenableFuture<Void>> futures = new ArrayList<>();
+ jobCoordinator.enqueueJob(FibHelper.getJobKeyForDcGwLoadBalancingGroup(dpnId), () -> {
+ List<ListenableFuture<?>> futures = new ArrayList<>();
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operationalTx -> {
synchronized (getDcGateWaySyncKey(destinationIp)) {
FibUtil.addL3vpnDcGateWay(destinationIp, operationalTx);
}
futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, configTx -> {
List<String> availableDcGws = getDcGwIps();
- Preconditions.checkNotNull(availableDcGws, "There are no dc-gws present");
+ requireNonNull(availableDcGws, "There are no dc-gws present");
int noOfDcGws = availableDcGws.size();
if (noOfDcGws == 1) {
LOG.trace("There are no enough DC GateWays {} present to program LB group", availableDcGws);
}, RETRY_COUNT);
}
- private String getJobKey(Uint64 dpnId) {
- return new StringBuilder().append(NEXTHOPMANAGER_JOB_KEY_PREFIX).append(dpnId).toString();
- }
-
private String getDcGateWaySyncKey(String destinationIp) {
String mutex = new StringBuilder().append("L3vpncDcGateWay").append(destinationIp).toString();
return mutex.intern();
private List<String> getDcGwIps() {
InstanceIdentifier<DcGatewayIpList> dcGatewayIpListid =
InstanceIdentifier.builder(DcGatewayIpList.class).build();
- DcGatewayIpList dcGatewayIpListConfig =
- MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid).orNull();
+ DcGatewayIpList dcGatewayIpListConfig;
+ try {
+ dcGatewayIpListConfig = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+ LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid).orElse(null);
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("getDcGwIps: Exception while reading DcGatewayIpList DS", e);
+ return Collections.emptyList();
+ }
if (dcGatewayIpListConfig == null) {
return Collections.emptyList();
}
- return dcGatewayIpListConfig.getDcGatewayIp()
+ return new ArrayList<DcGatewayIp>(dcGatewayIpListConfig.nonnullDcGatewayIp().values())
.stream()
.filter(dcGwIp -> dcGwIp.getTunnnelType().equals(TunnelTypeMplsOverGre.class))
.map(dcGwIp -> dcGwIp.getIpAddress().stringValue()).sorted()
InstanceIdentifier<StateTunnelList> tunnelStateId =
InstanceIdentifier.builder(TunnelsState.class).child(
StateTunnelList.class, new StateTunnelListKey(tunnelName)).build();
- return MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, tunnelStateId)
- .toJavaUtil().map(StateTunnelList::getOperState)
- .orElse(TunnelOperStatus.Down) == TunnelOperStatus.Up;
+ try {
+ return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL,
+ tunnelStateId).map(StateTunnelList::getOperState)
+ .orElse(TunnelOperStatus.Down) == TunnelOperStatus.Up;
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.error("isTunnelUp: Exception while reading StateTunnelList DS for tunnel {} tunnelType {}",
+ tunnelName, tunnelType, e);
+ return false;
+ }
}
return false;
}
LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}",
interfaceName, rpcResult.getErrors());
} else {
- actions = rpcResult.getResult().nonnullAction();
+ actions = new ArrayList<Action>(rpcResult.getResult().nonnullAction().values());
}
} catch (InterruptedException | ExecutionException e) {
LOG.warn("Exception when egress actions for interface {}", interfaceName, e);
*/
public void removeDcGwLoadBalancingGroup(Uint64 dpnId,
String destinationIp) {
- jobCoordinator.enqueueJob(getJobKey(dpnId), () -> {
+ jobCoordinator.enqueueJob(FibHelper.getJobKeyForDcGwLoadBalancingGroup(dpnId), () -> {
List<String> availableDcGws = fibUtil.getL3VpnDcGateWays();
if (availableDcGws.contains(destinationIp)) {
availableDcGws.remove(destinationIp);
}
- List<ListenableFuture<Void>> futures = new ArrayList<>();
+ List<ListenableFuture<?>> futures = new ArrayList<>();
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operationalTx -> {
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, configTx -> {
availableDcGws.forEach(dcGwIp -> {
*/
public void updateDcGwLoadBalancingGroup(Uint64 dpnId, String destinationIp,
boolean isTunnelUp, Class<? extends TunnelTypeBase> tunnelType) {
- jobCoordinator.enqueueJob(getJobKey(dpnId), () -> {
+ jobCoordinator.enqueueJob(FibHelper.getJobKeyForDcGwLoadBalancingGroup(dpnId), () -> {
List<String> availableDcGws = fibUtil.getL3VpnDcGateWays();
if (availableDcGws.contains(destinationIp)) {
availableDcGws.remove(destinationIp);
}
- List<ListenableFuture<Void>> futures = new ArrayList<>();
+ List<ListenableFuture<?>> futures = new ArrayList<>();
futures.add(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, configTx -> {
availableDcGws.forEach(dcGwIp -> {
List<String> dcGws = Arrays.asList(dcGwIp, destinationIp);