Bump upstreams for Silicon
[netvirt.git] / fibmanager / impl / src / main / java / org / opendaylight / netvirt / fibmanager / NexthopManager.java
index e08a34c54c70823ea9885fe7f87a4c4d3de56b0e..3e7270160cd3d572ba0472e473ee6f7843b6874a 100644 (file)
@@ -7,15 +7,13 @@
  */
 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;
@@ -24,6 +22,7 @@ import java.util.List;
 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;
@@ -32,13 +31,8 @@ import java.util.concurrent.TimeoutException;
 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;
@@ -59,7 +53,13 @@ import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
 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;
@@ -93,6 +93,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.Tun
 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;
@@ -148,10 +149,11 @@ public class NexthopManager implements AutoCloseable {
     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;
@@ -281,7 +283,7 @@ public class NexthopManager implements AutoCloseable {
                             ifName, rpcResult.getErrors());
                     return Collections.emptyList();
                 } else {
-                    actions = rpcResult.getResult().nonnullAction();
+                    actions = new ArrayList<Action>(rpcResult.getResult().nonnullAction().values());
                 }
             } else {
                 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = odlInterfaceRpcService
@@ -292,7 +294,7 @@ public class NexthopManager implements AutoCloseable {
                                     + "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<>();
@@ -466,9 +468,9 @@ public class NexthopManager implements AutoCloseable {
 
                     } 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 =
@@ -553,11 +555,19 @@ public class NexthopManager implements AutoCloseable {
             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);
@@ -614,7 +624,7 @@ public class NexthopManager implements AutoCloseable {
             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
@@ -676,9 +686,14 @@ public class NexthopManager implements AutoCloseable {
              * 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;
@@ -1072,15 +1087,15 @@ public class NexthopManager implements AutoCloseable {
 
     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);
@@ -1114,10 +1129,6 @@ public class NexthopManager implements AutoCloseable {
         }, 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();
@@ -1126,12 +1137,18 @@ public class NexthopManager implements AutoCloseable {
     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()
@@ -1144,9 +1161,15 @@ public class NexthopManager implements AutoCloseable {
             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;
     }
@@ -1163,7 +1186,7 @@ public class NexthopManager implements AutoCloseable {
                 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);
@@ -1177,12 +1200,12 @@ public class NexthopManager implements AutoCloseable {
      */
     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 -> {
@@ -1222,12 +1245,12 @@ public class NexthopManager implements AutoCloseable {
      */
     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);