NETVIRT-1630 migrate to md-sal APIs
[netvirt.git] / vpnmanager / impl / src / main / java / org / opendaylight / netvirt / vpnmanager / intervpnlink / InterVpnLinkUtil.java
index 80b11e6755cc84510b30fe3617bcb6823d0e55aa..61e7cd4f9d0eeb0ce1af5ce035b7236cc035e1e3 100755 (executable)
@@ -7,16 +7,16 @@
  */
 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 java.util.Collections;
 import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
 import java.util.stream.Collectors;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.MatchInfo;
 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
@@ -24,8 +24,9 @@ import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
 import org.opendaylight.genius.utils.ServiceIndex;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 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;
@@ -34,14 +35,9 @@ import org.opendaylight.netvirt.vpnmanager.VpnUtil;
 import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkCache;
 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.InterVpnLinkDataComposite;
-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;
@@ -54,17 +50,36 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLinkKey;
 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;
 
 /**
  * This class contains methods to be used as utilities related with inter-vpn-link.
  */
+@Singleton
 public final class InterVpnLinkUtil {
 
     private static final Logger LOG = LoggerFactory.getLogger(InterVpnLinkUtil.class);
-
-    private InterVpnLinkUtil() { }
+    private final DataBroker dataBroker;
+    private final IMdsalApiManager mdsalManager;
+    private final VpnUtil vpnUtil;
+    private final VpnFootprintService vpnFootprintService;
+    private final IBgpManager bgpManager;
+    private final IFibManager fibManager;
+
+    @Inject
+    public InterVpnLinkUtil(final VpnUtil vpnUtil, final VpnFootprintService vpnFootprintService,
+                            final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
+                            final IBgpManager bgpManager, final IFibManager fibManager) {
+        this.dataBroker = dataBroker;
+        this.mdsalManager = mdsalManager;
+        this.vpnUtil = vpnUtil;
+        this.vpnFootprintService = vpnFootprintService;
+        this.bgpManager = bgpManager;
+        this.fibManager = fibManager;
+    }
 
     /**
      * Retrieves the Instance Identifier that points to an InterVpnLink object
@@ -92,7 +107,7 @@ public final class InterVpnLinkUtil {
             .build();
     }
 
-    public static String buildInterVpnLinkIfaceName(String vpnName, BigInteger dpnId) {
+    public static String buildInterVpnLinkIfaceName(String vpnName, Uint64 dpnId) {
         return String.format("InterVpnLink.%s.%s", vpnName, dpnId.toString());
     }
 
@@ -102,18 +117,16 @@ public final class InterVpnLinkUtil {
      * first one on the any of the specified DPNs, the installation of
      * Fib flows on that DPN will be triggered.
      *
-     * @param vpnFootprintService VpnFootprintService service reference
      * @param vpnName Name of the VPN to which the fake interfaces belong
      * @param dpnList List of DPNs where the fake InterVpnLink interface must be added
      */
-    public static void updateVpnFootprint(VpnFootprintService vpnFootprintService, String vpnName,
-        String primaryRd, List<BigInteger> dpnList) {
+    void updateVpnFootprint(String vpnName, String primaryRd, List<Uint64> dpnList) {
         LOG.debug("updateVpnFootprint (add):  vpn={}  dpnList={}", vpnName, dpnList);
         // Note: when a set of DPNs is calculated for Vpn1, these DPNs are added to the VpnToDpn map of Vpn2. Why?
         // because we do the handover from Vpn1 to Vpn2 in those DPNs, so in those DPNs we must know how to reach
         // to Vpn2 targets. If new Vpn2 targets are added later, the Fib will be maintained in these DPNs even if
         // Vpn2 is not physically present there.
-        for (BigInteger dpnId : dpnList) {
+        for (Uint64 dpnId : dpnList) {
             String ifaceName = buildInterVpnLinkIfaceName(vpnName, dpnId);
             vpnFootprintService.updateVpnToDpnMapping(dpnId, vpnName, primaryRd, ifaceName,
                     null/*ipAddressSourceValuePair*/, true /* addition */);
@@ -124,12 +137,10 @@ public final class InterVpnLinkUtil {
      * Updates VpnToDpn map by removing the fake VpnInterface related to an
      * InterVpnLink in the corresponding DPNs.
      *
-     * @param vpnFootprintService VpnFootprintService service reference
      * @param vpnName Name of the VPN to which the fake interfaces belong
      * @param dpnId DPN where the fake InterVpnLink interface must be removed from
      */
-    public static void removeIVpnLinkIfaceFromVpnFootprint(VpnFootprintService vpnFootprintService,
-        String vpnName, String rd, BigInteger dpnId) {
+    void removeIVpnLinkIfaceFromVpnFootprint(String vpnName, String rd, Uint64 dpnId) {
         String ifaceName = buildInterVpnLinkIfaceName(vpnName, dpnId);
         LOG.debug("updateVpnFootprint (remove):  vpn={}  dpn={}  ifaceName={}", vpnName, dpnId, ifaceName);
         vpnFootprintService.updateVpnToDpnMapping(dpnId, vpnName, rd, ifaceName,
@@ -138,7 +149,7 @@ public final class InterVpnLinkUtil {
 
 
     public static FirstEndpointState buildFirstEndpointState(FirstEndpointState original,
-                                                             Optional<List<BigInteger>> new1stEndpointDpns,
+                                                             Optional<List<Uint64>> new1stEndpointDpns,
                                                              Optional<Long> new1stEndpointLportTag) {
         FirstEndpointStateBuilder builder = new FirstEndpointStateBuilder(original);
         if (new1stEndpointDpns.isPresent()) {
@@ -150,13 +161,8 @@ public final class InterVpnLinkUtil {
         return builder.build();
     }
 
-    public static FirstEndpointState buildFirstEndpointState(String vpnName, List<BigInteger> dpnList, long lportTag) {
-        return new FirstEndpointStateBuilder().setVpnUuid(new Uuid(vpnName)).setDpId(dpnList).setLportTag(lportTag)
-                                              .build();
-    }
-
     public static SecondEndpointState buildSecondEndpointState(SecondEndpointState original,
-                                                               Optional<List<BigInteger>> new2ndEndpointDpns,
+                                                               Optional<List<Uint64>> new2ndEndpointDpns,
                                                                Optional<Long> new2ndEndpointLportTag) {
         SecondEndpointStateBuilder builder = new SecondEndpointStateBuilder(original);
         if (new2ndEndpointDpns.isPresent()) {
@@ -168,12 +174,6 @@ public final class InterVpnLinkUtil {
         return builder.build();
     }
 
-    public static SecondEndpointState buildSecondEndpointState(String vpnName, List<BigInteger> dpnList,
-                                                               long lportTag) {
-        return new SecondEndpointStateBuilder().setVpnUuid(new Uuid(vpnName)).setDpId(dpnList).setLportTag(lportTag)
-                                              .build();
-    }
-
     /**
      * Creates an InterVpnLinkState out of an existing one and modifying only the desired attributes.
      *
@@ -203,35 +203,34 @@ public final class InterVpnLinkUtil {
     /**
      * Updates inter-VPN link state.
      *
-     * @param broker dataBroker service reference
      * @param vpnLinkName The name of the InterVpnLink
      * @param state Sets the state of the InterVpnLink to Active or Error
      * @param newFirstEndpointState Updates the lportTag and/or DPNs of the 1st endpoint of the InterVpnLink
      * @param newSecondEndpointState Updates the lportTag and/or DPNs of the 2nd endpoint of the InterVpnLink
      * @param interVpnLinkCache the InterVpnLinkCache
      */
-    public static void updateInterVpnLinkState(DataBroker broker, String vpnLinkName, InterVpnLinkState.State state,
+    void updateInterVpnLinkState(String vpnLinkName, InterVpnLinkState.State state,
             FirstEndpointState newFirstEndpointState, SecondEndpointState newSecondEndpointState,
             InterVpnLinkCache interVpnLinkCache) {
-        Optional<InterVpnLinkState> optOldVpnLinkState = getInterVpnLinkState(broker, vpnLinkName);
+        Optional<InterVpnLinkState> optOldVpnLinkState = getInterVpnLinkState(vpnLinkName);
         if (optOldVpnLinkState.isPresent()) {
             InterVpnLinkState newVpnLinkState =
                 new InterVpnLinkStateBuilder(optOldVpnLinkState.get()).setState(state)
                             .setFirstEndpointState(newFirstEndpointState)
                             .setSecondEndpointState(newSecondEndpointState)
                             .build();
-            VpnUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION,
+            vpnUtil.syncUpdate(LogicalDatastoreType.CONFIGURATION,
                 InterVpnLinkUtil.getInterVpnLinkStateIid(vpnLinkName), newVpnLinkState);
             interVpnLinkCache.addInterVpnLinkStateToCaches(newVpnLinkState);
         } else {
             InterVpnLinkState newIVpnLinkState =
-                new InterVpnLinkStateBuilder().setKey(new InterVpnLinkStateKey(vpnLinkName))
+                new InterVpnLinkStateBuilder().withKey(new InterVpnLinkStateKey(vpnLinkName))
                     .setInterVpnLinkName(vpnLinkName)
                     .setFirstEndpointState(newFirstEndpointState)
                     .setSecondEndpointState(newSecondEndpointState)
                     .setState(InterVpnLinkState.State.Active)
                     .build();
-            VpnUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION,
+            vpnUtil.syncWrite(LogicalDatastoreType.CONFIGURATION,
                 InterVpnLinkUtil.getInterVpnLinkStateIid(vpnLinkName), newIVpnLinkState);
             interVpnLinkCache.addInterVpnLinkStateToCaches(newIVpnLinkState);
         }
@@ -242,23 +241,18 @@ public final class InterVpnLinkUtil {
      * the lportTag of one InterVpnLink's endpoint and sets the vrfTag of the
      * other endpoint and sends to FIB table.
      *
-     * @param broker dataBroker service reference
-     * @param mdsalManager MDSAL API accessor
      * @param interVpnLinkName Name of the InterVpnLink.
      * @param dpnList The list of DPNs where this flow must be installed
      * @param vpnUuidOtherEndpoint UUID of the other endpoint of the InterVpnLink
      * @param lportTagOfOtherEndpoint Dataplane identifier of the other endpoint of the InterVpnLink
      * @return the list of Futures for each and every flow that has been installed
      */
-    public static List<ListenableFuture<Void>> installLPortDispatcherTableFlow(DataBroker broker,
-                                                                               IMdsalApiManager mdsalManager,
-                                                                               String interVpnLinkName,
-                                                                               List<BigInteger> dpnList,
-                                                                               String vpnUuidOtherEndpoint,
-                                                                               Long lportTagOfOtherEndpoint) {
+    List<ListenableFuture<Void>> installLPortDispatcherTableFlow(String interVpnLinkName, List<Uint64> dpnList,
+                                                                 String vpnUuidOtherEndpoint,
+                                                                 Long lportTagOfOtherEndpoint) {
         List<ListenableFuture<Void>> result = new ArrayList<>();
-        long vpnId = VpnUtil.getVpnId(broker, vpnUuidOtherEndpoint);
-        for (BigInteger dpnId : dpnList) {
+        Uint32 vpnId = vpnUtil.getVpnId(vpnUuidOtherEndpoint);
+        for (Uint64 dpnId : dpnList) {
             // insert into LPortDispatcher table
             Flow lportDispatcherFlow = buildLPortDispatcherFlow(interVpnLinkName, vpnId,
                                                                 lportTagOfOtherEndpoint.intValue());
@@ -277,7 +271,7 @@ public final class InterVpnLinkUtil {
      * @param lportTag DataPlane identifier of the LogicalPort.
      * @return the Flow ready to be installed
      */
-    public static Flow buildLPortDispatcherFlow(String interVpnLinkName, long vpnId, int lportTag) {
+    public static Flow buildLPortDispatcherFlow(String interVpnLinkName, Uint32 vpnId, int lportTag) {
         LOG.info("Inter-vpn-link : buildLPortDispatcherFlow. vpnId {}   lportTag {} ", vpnId, lportTag);
         List<MatchInfo> matches = Collections.singletonList(new MatchMetadata(
                         MetaDataUtil.getMetaDataForLPortDispatcher(lportTag,
@@ -287,7 +281,7 @@ public final class InterVpnLinkUtil {
 
         return MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef,
                                       VpnConstants.DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY, flowRef,
-                                      0, 0, VpnUtil.getCookieL3((int) vpnId), matches,
+                                      0, 0, VpnUtil.getCookieL3(vpnId.intValue()), matches,
                                       buildLportDispatcherTableInstructions(vpnId));
     }
 
@@ -308,10 +302,10 @@ public final class InterVpnLinkUtil {
     }
 
 
-    public static List<Instruction> buildLportDispatcherTableInstructions(long vpnId) {
+    public static List<Instruction> buildLportDispatcherTableInstructions(Uint32 vpnId) {
         int instructionKey = 0;
         List<Instruction> instructions = new ArrayList<>();
-        instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(MetaDataUtil.getVpnIdMetadata(vpnId),
+        instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(MetaDataUtil.getVpnIdMetadata(vpnId.intValue()),
             MetaDataUtil.METADATA_MASK_VRFID,
             ++instructionKey));
         instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_FIB_TABLE, ++instructionKey));
@@ -319,130 +313,30 @@ public final class InterVpnLinkUtil {
         return instructions;
     }
 
-    /**
-     * Retrieves the States of all InterVpnLinks.
-     *
-     * @param broker dataBroker service reference
-     * @return the list of objects that holds the InterVpnLink state information
-     */
-    public static List<InterVpnLinkState> getAllInterVpnLinkState(DataBroker broker) {
-        InstanceIdentifier<InterVpnLinkStates> interVpnLinkStateIid =
-            InstanceIdentifier.builder(InterVpnLinkStates.class).build();
-
-        Optional<InterVpnLinkStates> interVpnLinkStateOpData =
-            MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, interVpnLinkStateIid);
-
-        return interVpnLinkStateOpData.isPresent() ? interVpnLinkStateOpData.get().getInterVpnLinkState()
-            : new ArrayList<>();
-    }
-
     /**
      * Retrieves the State of an InterVpnLink.
      *
-     * @param broker dataBroker service reference
      * @param interVpnLinkName The name of the InterVpnLink
-     * @return the object that contains the State of the specified InterVpnLink or Optional.absent() if it doesnt exist
-     */
-    public static Optional<InterVpnLinkState> getInterVpnLinkState(DataBroker broker, String interVpnLinkName) {
-        return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, getInterVpnLinkStateIid(interVpnLinkName));
-    }
-
-    /**
-     * Retrieves all configured InterVpnLinks.
-     *
-     * @param broker dataBroker service reference
-     * @return the list of InterVpnLinks
-     */
-    public static List<InterVpnLink> getAllInterVpnLinks(DataBroker broker) {
-        InstanceIdentifier<InterVpnLinks> interVpnLinksIid = InstanceIdentifier.builder(InterVpnLinks.class).build();
-
-        Optional<InterVpnLinks> interVpnLinksOpData =
-            MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, interVpnLinksIid);
-
-        return interVpnLinksOpData.isPresent() ? interVpnLinksOpData.get().getInterVpnLink()
-            : 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
+     * @return the object that contains the State of the specified InterVpnLink or Optional.empty() if it doesnt exist
      */
-    // 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 Optional<InterVpnLinkState> getInterVpnLinkState(String interVpnLinkName) {
+        Optional<InterVpnLinkState> interVpnLinkStateOptional = Optional.empty();
+        try {
+            interVpnLinkStateOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, getInterVpnLinkStateIid(interVpnLinkName));
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("getInterVpnLinkState: Failed to read intervpn link state for {}", interVpnLinkName);
         }
+        return interVpnLinkStateOptional;
     }
 
-    public static void handleStaticRoute(InterVpnLinkDataComposite interVpnLink, String vpnName,
-        String destination, String nexthop, int label,
-        DataBroker dataBroker, IFibManager fibManager, IBgpManager bgpManager) throws Exception {
+    public void handleStaticRoute(InterVpnLinkDataComposite interVpnLink, String vpnName,
+        String destination, String nexthop, Uint32 label) throws Exception {
 
         LOG.debug("handleStaticRoute [vpnLink={} srcVpn={} destination={} nextHop={} label={}]",
             interVpnLink.getInterVpnLinkName(), vpnName, destination, nexthop, label);
 
-        String vpnRd = VpnUtil.getVpnRd(dataBroker, vpnName);
+        String vpnRd = vpnUtil.getVpnRd(vpnName);
         if (vpnRd == null) {
             LOG.warn("Could not find Route-Distinguisher for VpnName {}", vpnName);
             return;
@@ -451,19 +345,20 @@ public final class InterVpnLinkUtil {
             vpnRd, destination, label, nexthop);
         fibManager.addOrUpdateFibEntry(vpnRd, null /*macAddress*/, destination,
                 Collections.singletonList(nexthop), VrfEntry.EncapType.Mplsgre, label,
-                0 /*l3vni*/, null /*gatewayMacAddress*/, null /*parentVpnRd*/, RouteOrigin.STATIC, null /*writeTxn*/);
+                Uint32.ZERO/*l3vni*/, null /*gatewayMacAddress*/, null /*parentVpnRd*/,
+                RouteOrigin.STATIC, null /*writeTxn*/);
 
         // Now advertise to BGP. The nexthop that must be advertised to BGP are the IPs of the DPN where the
         // VPN's endpoint have been instantiated
         // List<String> nexthopList = new ArrayList<>(); // The nexthops to be advertised to BGP
-        List<BigInteger> endpointDpns = interVpnLink.getEndpointDpnsByVpnName(vpnName);
+        List<Uint64> endpointDpns = interVpnLink.getEndpointDpnsByVpnName(vpnName);
         List<String> nexthopList =
             endpointDpns.stream().map(dpnId -> InterfaceUtils.getEndpointIpAddressForDPN(dataBroker, dpnId))
                         .collect(Collectors.toList());
         LOG.debug("advertising IVpnLink route to BGP:  vpnRd={}, prefix={}, label={}, nexthops={}",
             vpnRd, destination, label, nexthopList);
         bgpManager.advertisePrefix(vpnRd, null /*macAddress*/, destination, nexthopList,
-                VrfEntry.EncapType.Mplsgre, label, 0 /*l3vni*/, 0 /*l2vni*/,
+                VrfEntry.EncapType.Mplsgre, label, Uint32.ZERO/*l3vni*/, Uint32.ZERO /*l2vni*/,
                 null /*gatewayMacAddress*/);
     }
 }