NETVIRT-1630 migrate to md-sal APIs
[netvirt.git] / fibmanager / impl / src / main / java / org / opendaylight / netvirt / fibmanager / BaseVrfEntryHandler.java
index 05b5b1af09ba9043ac4eacdc26fc74c37cc76675..c502c0f6292428b07aa75abaa43fdc8cb8634243 100644 (file)
@@ -10,8 +10,6 @@ package org.opendaylight.netvirt.fibmanager;
 import static java.util.stream.Collectors.toList;
 import static org.opendaylight.genius.mdsalutil.NWUtil.isIpv4Address;
 
-import com.google.common.base.Optional;
-import java.math.BigInteger;
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
@@ -20,13 +18,13 @@ import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
 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.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+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;
@@ -59,6 +57,10 @@ import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
 import org.opendaylight.genius.utils.batching.SubTransaction;
 import org.opendaylight.genius.utils.batching.SubTransactionImpl;
 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
+import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.WriteTransaction;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.netvirt.fibmanager.NexthopManager.AdjacencyResult;
 import org.opendaylight.netvirt.fibmanager.api.FibHelper;
 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
@@ -91,6 +93,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.RoutesKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -98,7 +102,7 @@ import org.slf4j.LoggerFactory;
 public class BaseVrfEntryHandler implements AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(BaseVrfEntryHandler.class);
-    private static final BigInteger COOKIE_VM_FIB_TABLE =  new BigInteger("8000003", 16);
+    private static final Uint64 COOKIE_VM_FIB_TABLE =  Uint64.valueOf("8000003", 16).intern();
     private static final int DEFAULT_FIB_FLOW_PRIORITY = 10;
 
     private final DataBroker dataBroker;
@@ -144,19 +148,20 @@ public class BaseVrfEntryHandler implements AutoCloseable {
         }
     }
 
-    protected void deleteLocalAdjacency(final BigInteger dpId, final long vpnId, final String ipAddress,
+    protected void deleteLocalAdjacency(final Uint64 dpId, final Uint32 vpnId, final String ipAddress,
                               final String ipPrefixAddress) {
         LOG.trace("deleteLocalAdjacency called with dpid {}, vpnId{}, primaryIpAddress {} currIpPrefix {}",
                 dpId, vpnId, ipAddress, ipPrefixAddress);
         try {
             nextHopManager.removeLocalNextHop(dpId, vpnId, ipAddress, ipPrefixAddress);
         } catch (NullPointerException e) {
-            LOG.trace("", e);
+            // FIXME: NPEs should not be caught but rather their root cause should be eliminated
+            LOG.trace("Failed to remove nexthop", e);
         }
     }
 
-    @Nonnull
-    protected List<AdjacencyResult> resolveAdjacency(final BigInteger remoteDpnId, final long vpnId,
+    @NonNull
+    protected List<AdjacencyResult> resolveAdjacency(final Uint64 remoteDpnId, final Uint32 vpnId,
                                                      final VrfEntry vrfEntry, String rd) {
         List<RoutePaths> routePaths = new ArrayList<>(vrfEntry.nonnullRoutePaths());
         FibHelper.sortIpAddress(routePaths);
@@ -227,12 +232,15 @@ public class BaseVrfEntryHandler implements AutoCloseable {
                         .collect(toList()));
             }
         } catch (NullPointerException e) {
-            LOG.trace("", e);
+            // FIXME: NPEs should not be caught but rather their root cause should be eliminated
+            LOG.trace("Failed to remove adjacency", e);
         }
         return adjacencyList;
     }
 
-    protected void makeConnectedRoute(BigInteger dpId, long vpnId, VrfEntry vrfEntry, String rd,
+    // Allow deprecated TransactionRunner calls for now
+    @SuppressWarnings("ForbidCertainMethod")
+    protected void makeConnectedRoute(Uint64 dpId, Uint32 vpnId, VrfEntry vrfEntry, String rd,
                                       @Nullable List<InstructionInfo> instructions, int addOrRemove,
                                       WriteTransaction tx, @Nullable List<SubTransaction> subTxns) {
         if (tx == null) {
@@ -262,7 +270,8 @@ public class BaseVrfEntryHandler implements AutoCloseable {
 
         List<MatchInfo> matches = new ArrayList<>();
 
-        matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
+        matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()),
+            MetaDataUtil.METADATA_MASK_VRFID));
 
         if (destPrefix instanceof Inet4Address) {
             matches.add(MatchEthernetType.IPV4);
@@ -310,7 +319,7 @@ public class BaseVrfEntryHandler implements AutoCloseable {
         }
     }
 
-    protected void addRewriteDstMacAction(long vpnId, VrfEntry vrfEntry, @Nullable Prefixes prefixInfo,
+    protected void addRewriteDstMacAction(Uint32 vpnId, VrfEntry vrfEntry, @Nullable Prefixes prefixInfo,
                                           List<ActionInfo> actionInfos) {
         if (vrfEntry.getMac() != null) {
             actionInfos.add(new ActionSetFieldEthernetDestination(actionInfos.size(),
@@ -356,7 +365,7 @@ public class BaseVrfEntryHandler implements AutoCloseable {
         actionInfos.add(new ActionSetFieldEthernetDestination(actionInfos.size(), new MacAddress(macAddress)));
     }
 
-    protected void addTunnelInterfaceActions(AdjacencyResult adjacencyResult, long vpnId, VrfEntry vrfEntry,
+    protected void addTunnelInterfaceActions(AdjacencyResult adjacencyResult, Uint32 vpnId, VrfEntry vrfEntry,
                                            List<ActionInfo> actionInfos, String rd) {
         Class<? extends TunnelTypeBase> tunnelType =
                 VpnExtraRouteHelper.getTunnelType(nextHopManager.getItmManager(), adjacencyResult.getInterfaceName());
@@ -368,13 +377,13 @@ public class BaseVrfEntryHandler implements AutoCloseable {
         // routePath this result is built for. If this is not possible construct a map which does
         // the same.
         String nextHopIp = adjacencyResult.getNextHopIp();
-        java.util.Optional<Long> optionalLabel = FibUtil.getLabelForNextHop(vrfEntry, nextHopIp);
+        java.util.Optional<Uint32> optionalLabel = FibUtil.getLabelForNextHop(vrfEntry, nextHopIp);
         if (!optionalLabel.isPresent()) {
             LOG.warn("NextHopIp {} not found in vrfEntry {}", nextHopIp, vrfEntry);
             return;
         }
-        long label = optionalLabel.get();
-        BigInteger tunnelId = null;
+        Uint32 label = optionalLabel.get();
+        Uint64 tunnelId = null;
         Prefixes prefixInfo = null;
         // FIXME vxlan vni bit set is not working properly with OVS.need to
         // revisit
@@ -392,20 +401,20 @@ public class BaseVrfEntryHandler implements AutoCloseable {
             }
             // Internet VPN VNI will be used as tun_id for NAT use-cases
             if (Prefixes.PrefixCue.Nat.equals(prefixInfo.getPrefixCue())) {
-                if (vrfEntry.getL3vni() != null && vrfEntry.getL3vni() != 0) {
-                    tunnelId = BigInteger.valueOf(vrfEntry.getL3vni());
+                if (vrfEntry.getL3vni() != null && vrfEntry.getL3vni().toJava() != 0) {
+                    tunnelId = Uint64.valueOf(vrfEntry.getL3vni().longValue());
                 }
             } else {
                 if (FibUtil.isVxlanNetwork(prefixInfo.getNetworkType())) {
-                    tunnelId = BigInteger.valueOf(prefixInfo.getSegmentationId());
+                    tunnelId = Uint64.valueOf(prefixInfo.getSegmentationId().longValue());
                 } else {
                     LOG.warn("Network is not of type VXLAN for prefix {}."
                             + "Going with default Lport Tag.", prefixInfo.toString());
-                    tunnelId = BigInteger.valueOf(label);
+                    tunnelId = Uint64.valueOf(label.longValue());
                 }
             }
         } else {
-            tunnelId = BigInteger.valueOf(label);
+            tunnelId = Uint64.valueOf(label.longValue());
         }
         LOG.debug("adding set tunnel id action for label {}", label);
         actionInfos.add(new ActionSetFieldTunnelId(tunnelId));
@@ -418,7 +427,7 @@ public class BaseVrfEntryHandler implements AutoCloseable {
         for (AdjacencyResult adjacencyResult : adjacencyResults) {
             String interfaceName = adjacencyResult.getInterfaceName();
             if (null == fibUtil.getInterfaceStateFromOperDS(interfaceName)) {
-                res = fibUtil.buildStateInterfaceId(interfaceName);
+                res = FibUtil.buildStateInterfaceId(interfaceName);
                 break;
             }
         }
@@ -426,7 +435,9 @@ public class BaseVrfEntryHandler implements AutoCloseable {
         return res;
     }
 
-    public void programRemoteFib(final BigInteger remoteDpnId, final long vpnId,
+    // Allow deprecated TransactionRunner calls for now
+    @SuppressWarnings("ForbidCertainMethod")
+    public void programRemoteFib(final Uint64 remoteDpnId, final Uint32 vpnId,
                                  final VrfEntry vrfEntry, WriteTransaction tx, String rd,
                                  List<AdjacencyResult> adjacencyResults,
                                  @Nullable List<SubTransaction> subTxns) {
@@ -439,15 +450,17 @@ public class BaseVrfEntryHandler implements AutoCloseable {
                     absentInterfaceStateIid,
                     (before, after) -> {
                         LOG.info("programRemoteFib: waited for and got interface state {}", absentInterfaceStateIid);
-                        txRunner.callWithNewWriteOnlyTransactionAndSubmit(
-                            (wtx) -> programRemoteFib(remoteDpnId, vpnId, vrfEntry, wtx, rd, adjacencyResults, null));
+                        LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+                            (wtx) -> programRemoteFib(remoteDpnId, vpnId, vrfEntry, wtx, rd, adjacencyResults, null)),
+                            LOG, "Failed to program remote FIB {}", absentInterfaceStateIid);
                         return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
                     },
                     Duration.of(15, ChronoUnit.MINUTES),
                     (iid) -> {
                         LOG.error("programRemoteFib: timed out waiting for {}", absentInterfaceStateIid);
-                        txRunner.callWithNewWriteOnlyTransactionAndSubmit(
-                            (wtx) -> programRemoteFib(remoteDpnId, vpnId, vrfEntry, wtx, rd, adjacencyResults, null));
+                        LoggingFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+                            (wtx) -> programRemoteFib(remoteDpnId, vpnId, vrfEntry, wtx, rd, adjacencyResults, null)),
+                            LOG, "Failed to program timed-out remote FIB {}", absentInterfaceStateIid);
                     });
                 return;
             }
@@ -463,7 +476,7 @@ public class BaseVrfEntryHandler implements AutoCloseable {
                 addRewriteDstMacAction(vpnId, vrfEntry, null, actionInfos);
             }
             List<ActionInfo> egressActions = nextHopManager.getEgressActionsForInterface(egressInterface,
-                    actionInfos.size(), true);
+                    actionInfos.size(), true, vpnId, vrfEntry.getDestPrefix());
             if (egressActions.isEmpty()) {
                 LOG.error(
                         "Failed to retrieve egress action for prefix {} route-paths {} interface {}. "
@@ -477,7 +490,7 @@ public class BaseVrfEntryHandler implements AutoCloseable {
         makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, instructions, NwConstants.ADD_FLOW, tx, subTxns);
     }
 
-    public boolean checkDpnDeleteFibEntry(VpnNexthop localNextHopInfo, BigInteger remoteDpnId, long vpnId,
+    public boolean checkDpnDeleteFibEntry(VpnNexthop localNextHopInfo, Uint64 remoteDpnId, Uint32 vpnId,
                                           VrfEntry vrfEntry, String rd,
                                           WriteTransaction tx, @Nullable List<SubTransaction> subTxns) {
         boolean isRemoteRoute = true;
@@ -495,8 +508,10 @@ public class BaseVrfEntryHandler implements AutoCloseable {
         }
     }
 
-    public void deleteRemoteRoute(@Nullable final BigInteger localDpnId, final BigInteger remoteDpnId,
-                                  final long vpnId, final VrfTablesKey vrfTableKey,
+    // Allow deprecated TransactionRunner calls for now
+    @SuppressWarnings("ForbidCertainMethod")
+    public void deleteRemoteRoute(@Nullable final Uint64 localDpnId, final Uint64 remoteDpnId,
+                                  final Uint32 vpnId, final VrfTablesKey vrfTableKey,
                                   final VrfEntry vrfEntry, Optional<Routes> extraRouteOptional,
                                   @Nullable WriteTransaction tx) {
         if (tx == null) {
@@ -510,7 +525,7 @@ public class BaseVrfEntryHandler implements AutoCloseable {
                 vrfEntry.getDestPrefix(), vpnId, localDpnId, remoteDpnId);
         String rd = vrfTableKey.getRouteDistinguisher();
 
-        if (localDpnId != null && localDpnId != BigInteger.ZERO) {
+        if (localDpnId != null && !Uint64.ZERO.equals(localDpnId)) {
             // localDpnId is not known when clean up happens for last vm for a vpn on a dpn
             if (extraRouteOptional.isPresent()) {
                 nextHopManager.deleteLoadBalancingNextHop(vpnId, remoteDpnId, vrfEntry.getDestPrefix());
@@ -537,19 +552,25 @@ public class BaseVrfEntryHandler implements AutoCloseable {
     }
 
     @Nullable
-    public Routes getVpnToExtraroute(Long vpnId, String vpnRd, String destPrefix) {
+    public Routes getVpnToExtraroute(Uint32 vpnId, String vpnRd, String destPrefix) {
         String optVpnName = fibUtil.getVpnNameFromId(vpnId);
         if (optVpnName != null) {
-            InstanceIdentifier<Routes> vpnExtraRoutesId = getVpnToExtrarouteIdentifier(
-                    optVpnName, vpnRd, destPrefix);
-            return MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, vpnExtraRoutesId).orNull();
+            InstanceIdentifier<Routes> vpnExtraRoutesId = getVpnToExtrarouteIdentifier(optVpnName, vpnRd, destPrefix);
+            try {
+                return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                        vpnExtraRoutesId).orElse(null);
+            } catch (ExecutionException | InterruptedException e) {
+                LOG.error("getVpnToExtraroute: Exception while reading vpn-to-extraroute DS for the prefix {} "
+                        + "rd {} vpnId {} ", destPrefix, vpnRd, vpnId, e);
+            }
         }
         return null;
     }
 
-    public FlowEntity buildL3vpnGatewayFlow(BigInteger dpId, String gwMacAddress, long vpnId) {
+    public FlowEntity buildL3vpnGatewayFlow(Uint64 dpId, String gwMacAddress, Uint32 vpnId) {
         List<MatchInfo> mkMatches = new ArrayList<>();
-        mkMatches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
+        mkMatches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()),
+            MetaDataUtil.METADATA_MASK_VRFID));
         mkMatches.add(new MatchEthernetDestination(new MacAddress(gwMacAddress)));
         List<InstructionInfo> mkInstructions = new ArrayList<>();
         mkInstructions.add(new InstructionGotoTable(NwConstants.L3_FIB_TABLE));
@@ -558,12 +579,13 @@ public class BaseVrfEntryHandler implements AutoCloseable {
                 flowId, 20, flowId, 0, 0, NwConstants.COOKIE_L3_GW_MAC_TABLE, mkMatches, mkInstructions);
     }
 
-    public void installPingResponderFlowEntry(BigInteger dpnId, long vpnId, String routerInternalIp,
-                                              MacAddress routerMac, long label, int addOrRemove) {
+    public void installPingResponderFlowEntry(Uint64 dpnId, Uint32 vpnId, String routerInternalIp,
+                                              MacAddress routerMac, Uint32 label, int addOrRemove) {
 
         List<MatchInfo> matches = new ArrayList<>();
         matches.add(MatchIpProtocol.ICMP);
-        matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
+        matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()),
+            MetaDataUtil.METADATA_MASK_VRFID));
         matches.add(new MatchIcmpv4((short) 8, (short) 0));
         matches.add(MatchEthernetType.IPV4);
         matches.add(new MatchIpv4Destination(routerInternalIp, "32"));
@@ -581,7 +603,7 @@ public class BaseVrfEntryHandler implements AutoCloseable {
         // Set the ICMP type to 0 (echo reply)
         actionsInfos.add(new ActionSetIcmpType((short) 0));
 
-        actionsInfos.add(new ActionNxLoadInPort(BigInteger.ZERO));
+        actionsInfos.add(new ActionNxLoadInPort(Uint64.ZERO));
 
         actionsInfos.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));