Datastore-constrained txes: vpnmanager
[netvirt.git] / vpnmanager / impl / src / main / java / org / opendaylight / netvirt / vpnmanager / TunnelInterfaceStateListener.java
index db3d126fc647f4787b55d7e9317fe1e9eec47d18..7eab70efeb2e312d230bab47b7f08b208426745f 100644 (file)
@@ -8,6 +8,8 @@
 package org.opendaylight.netvirt.vpnmanager;
 
 import static java.util.stream.Collectors.toList;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Strings;
@@ -27,9 +29,12 @@ 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.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.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
@@ -76,13 +81,17 @@ import org.slf4j.LoggerFactory;
 @Singleton
 public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBase<StateTunnelList,
         TunnelInterfaceStateListener> {
+
     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;
     private final VpnSubnetRouteHandler vpnSubnetRouteHandler;
     private final JobCoordinator jobCoordinator;
+    private final VpnUtil vpnUtil;
 
     protected enum UpdateRouteAction {
         ADVERTISE_ROUTE, WITHDRAW_ROUTE
@@ -96,6 +105,13 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
 
     /**
      * Responsible for listening to tunnel interface state change.
+     * @param dataBroker Data Broker
+     * @param fibManager FIB APIs
+     * @param ifaceMgrRpcService Interface Manager RPC
+     * @param vpnInterfaceManager Vpn Interface APIs
+     * @param vpnSubnetRouteHandler Subnet-Route APIs
+     * @param jobCoordinator Key based job serialization mechanism
+     * @param vpnUtil Vpn Utility
      */
     @Inject
     public TunnelInterfaceStateListener(final DataBroker dataBroker,
@@ -103,14 +119,17 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
                                         final OdlInterfaceRpcService ifaceMgrRpcService,
                                         final VpnInterfaceManager vpnInterfaceManager,
                                         final VpnSubnetRouteHandler vpnSubnetRouteHandler,
-                                        final JobCoordinator jobCoordinator) {
+                                        final JobCoordinator jobCoordinator,
+                                        VpnUtil vpnUtil) {
         super(StateTunnelList.class, TunnelInterfaceStateListener.class);
         this.dataBroker = dataBroker;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.fibManager = fibManager;
         this.intfRpcService = ifaceMgrRpcService;
         this.vpnInterfaceManager = vpnInterfaceManager;
         this.vpnSubnetRouteHandler = vpnSubnetRouteHandler;
         this.jobCoordinator = jobCoordinator;
+        this.vpnUtil = vpnUtil;
     }
 
     @PostConstruct
@@ -135,7 +154,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
         if (isGreTunnel(del)) {
             programDcGwLoadBalancingGroup(del, NwConstants.DEL_FLOW);
         }
-        handleTunnelEventForDPN(del, UpdateRouteAction.WITHDRAW_ROUTE, TunnelAction.TUNNEL_EP_DELETE);
+        handleTunnelEventForDPN(del, TunnelAction.TUNNEL_EP_DELETE);
     }
 
     @Override
@@ -158,42 +177,38 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
 
         //Remove the corresponding nexthop from the routepath under extraroute in fibentries.
         BigInteger srcDpnId = new BigInteger(update.getSrcInfo().getTepDeviceId());
-        String srcTepIp = String.valueOf(update.getSrcInfo().getTepIp().getValue());
-        List<VpnInstanceOpDataEntry> vpnInstanceOpData = VpnUtil.getAllVpnInstanceOpData(dataBroker);
+        String srcTepIp = update.getSrcInfo().getTepIp().stringValue();
+        List<VpnInstanceOpDataEntry> vpnInstanceOpData = vpnUtil.getAllVpnInstanceOpData();
         if (vpnInstanceOpData == null) {
             LOG.trace("update: No vpnInstanceOpdata present");
             return;
         }
-        WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
-        if (tunOpStatus == TunnelOperStatus.Up) {
-            handleTunnelEventForDPN(update, UpdateRouteAction.ADVERTISE_ROUTE, 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(dataBroker, opData.getVrfId(),
-                                    destPrefix.getDestPrefix(), srcTepIp, routePath.getLabel(),
-                                    false, writeConfigTxn);
+        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(opData.getVrfId(),
+                                destPrefix.getDestPrefix());
+                        if (vrfEntry == null || vrfEntry.getRoutePaths() == null) {
+                            return;
                         }
+                        List<RoutePaths> routePaths = vrfEntry.getRoutePaths();
+                        routePaths.forEach(routePath -> {
+                            if (routePath.getNexthopAddress().equals(srcTepIp)) {
+                                String prefix = destPrefix.getDestPrefix();
+                                String vpnPrefixKey = VpnUtil.getVpnNamePrefixKey(opData.getVpnInstanceName(),
+                                        prefix);
+                                synchronized (vpnPrefixKey.intern()) {
+                                    fibManager.refreshVrfEntry(opData.getVrfId(), prefix);
+                                }
+                            }
+                        });
                     });
                 });
-            });
-        }
-        writeConfigTxn.submit();
     }
 
     @Override
@@ -214,7 +229,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
         LOG.info("add: ITM Tunnel ,type {} ,added between src: {} and dest: {}",
                 fibManager.getTransportTypeStr(add.getTransportType().toString()),
                 add.getSrcInfo().getTepDeviceId(), add.getDstInfo().getTepDeviceId());
-        handleTunnelEventForDPN(add, UpdateRouteAction.ADVERTISE_ROUTE, TunnelAction.TUNNEL_EP_ADD);
+        handleTunnelEventForDPN(add, TunnelAction.TUNNEL_EP_ADD);
     }
 
     public enum TunnelEventProcessingMethod {
@@ -233,11 +248,10 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private void handleTunnelEventForDPN(StateTunnelList stateTunnelList, UpdateRouteAction action,
-                                         TunnelAction tunnelAction) {
+    private void handleTunnelEventForDPN(StateTunnelList stateTunnelList, TunnelAction tunnelAction) {
         final BigInteger srcDpnId = new BigInteger(stateTunnelList.getSrcInfo().getTepDeviceId());
-        final String srcTepIp = String.valueOf(stateTunnelList.getSrcInfo().getTepIp().getValue());
-        String destTepIp = String.valueOf(stateTunnelList.getDstInfo().getTepIp().getValue());
+        final String srcTepIp = stateTunnelList.getSrcInfo().getTepIp().stringValue();
+        String destTepIp = stateTunnelList.getDstInfo().getTepIp().stringValue();
         String rd;
         BigInteger remoteDpnId = null;
         boolean isTepDeletedOnDpn = false;
@@ -248,13 +262,13 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
         LOG.trace("handleTunnelEventForDPN: tunTypeVal is {}", tunTypeVal);
         try {
             if (tunnelAction == TunnelAction.TUNNEL_EP_ADD) {
-                LOG.info("handleTunnelEventForDPN: Tunnel ADD event received for Dpn {} VTEP Ip {} destTepIp",
+                LOG.info("handleTunnelEventForDPN: Tunnel ADD event received for Dpn {} VTEP Ip {} destTepIp {}",
                         srcDpnId, srcTepIp, destTepIp);
                 if (isTunnelInLogicalGroup(stateTunnelList)) {
                     return;
                 }
             } else if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE) {
-                LOG.info("handleTunnelEventForDPN: Tunnel DELETE event received for Dpn {} VTEP Ip {} DestTepIp",
+                LOG.info("handleTunnelEventForDPN: Tunnel DELETE event received for Dpn {} VTEP Ip {} DestTepIp {}",
                         srcDpnId, srcTepIp, destTepIp);
                 // When tunnel EP is deleted on a DPN , VPN gets two deletion event.
                 // One for a DPN on which tunnel EP was deleted and another for other-end DPN.
@@ -271,8 +285,8 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
                 }
 
                 if (endpointIpForDPN == null) {
-                    LOG.info("handleTunnelEventForDPN: Tunnel TEP is deleted on Dpn {} VTEP Ip {} destTepIp", srcDpnId,
-                            srcTepIp, destTepIp);
+                    LOG.info("handleTunnelEventForDPN: Tunnel TEP is deleted on Dpn {} VTEP Ip {} destTepIp {}",
+                            srcDpnId, srcTepIp, destTepIp);
                     isTepDeletedOnDpn = true;
                 }
             }
@@ -293,8 +307,8 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
                     srcDpninterfacelist = rpcResult.getResult().getInterfaces();
                 }
             } catch (Exception e) {
-                LOG.error("handleTunnelEventForDPN: Exception {} when querying for GetDpnInterfaceList for srcDpnid {}"
-                        + " srcTepIp {} destTepIp {}, trace {}", e, srcDpnId, srcTepIp, destTepIp, e.getStackTrace());
+                LOG.error("handleTunnelEventForDPN: Exception when querying for GetDpnInterfaceList for srcDpnid {}"
+                        + " srcTepIp {} destTepIp {}", srcDpnId, srcTepIp, destTepIp, e);
             }
             // Get the list of VpnInterfaces from Intf Mgr for a destDPN only for internal tunnel.
             if (tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
@@ -311,9 +325,9 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
                         destDpninterfacelist = rpcResult.getResult().getInterfaces();
                     }
                 } catch (Exception e) {
-                    LOG.error("handleTunnelEventForDPN: Exception {} when querying for GetDpnInterfaceList"
-                                    + " for remoteDpnid {} srcTepIp {} destTepIp {}, trace {}", e, remoteDpnId,
-                            srcTepIp, destTepIp, e.getStackTrace());
+                    LOG.error("handleTunnelEventForDPN: Exception when querying for GetDpnInterfaceList"
+                                    + " for remoteDpnid {} srcTepIp {} destTepIp {}", remoteDpnId,
+                            srcTepIp, destTepIp, e);
                 }
             }
 
@@ -326,21 +340,21 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
             String intfName = null;
             List<Uuid> subnetList = new ArrayList<>();
             Map<Long, String> vpnIdRdMap = new HashMap<>();
-            Set<String> listVpnName = new HashSet<String>();
+            Set<String> listVpnName = new HashSet<>();
 
             while (interfacelistIter.hasNext()) {
                 interfaces = interfacelistIter.next();
                 if (!L2vlan.class.equals(interfaces.getInterfaceType())) {
                     LOG.info("handleTunnelEventForDPN: Interface {} not of type L2Vlan", interfaces.getInterfaceName());
-                    return;
+                    continue;
                 }
                 intfName = interfaces.getInterfaceName();
                 VpnInterface vpnInterface =
-                     VpnUtil.getConfiguredVpnInterface(dataBroker, intfName);
-                if (vpnInterface != null && !vpnInterface.isScheduledForRemove()) {
+                     vpnUtil.getConfiguredVpnInterface(intfName);
+                if (vpnInterface != null) {
                     listVpnName.addAll(VpnHelper
                         .getVpnInterfaceVpnInstanceNamesString(vpnInterface.getVpnInstanceNames()));
-                    handleTunnelEventForDPNVpn(stateTunnelList, action, vpnIdRdMap,
+                    handleTunnelEventForDPNVpn(stateTunnelList, vpnIdRdMap,
                             tunnelAction, isTepDeletedOnDpn,
                             subnetList, TunnelEventProcessingMethod.POPULATESUBNETS,
                             vpnInterface);
@@ -355,13 +369,13 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
                 interfaces = interfacelistIter.next();
                 if (!L2vlan.class.equals(interfaces.getInterfaceType())) {
                     LOG.info("handleTunnelEventForDPN: Interface {} not of type L2Vlan", interfaces.getInterfaceName());
-                    return;
+                    continue;
                 }
                 intfName = interfaces.getInterfaceName();
                 VpnInterface vpnInterface =
-                        VpnUtil.getConfiguredVpnInterface(dataBroker, intfName);
+                        vpnUtil.getConfiguredVpnInterface(intfName);
                 if (vpnInterface != null) {
-                    handleTunnelEventForDPNVpn(stateTunnelList, action, vpnIdRdMap,
+                    handleTunnelEventForDPNVpn(stateTunnelList, vpnIdRdMap,
                             tunnelAction, isTepDeletedOnDpn,
                             subnetList, TunnelEventProcessingMethod.MANAGEREMOTEROUTES,
                             vpnInterface);
@@ -387,7 +401,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
                         vpnSubnetRouteHandler.updateSubnetRouteOnTunnelUpEvent(subnetId, srcDpnId);
                     }
                 }
-                if ((tunnelAction == TunnelAction.TUNNEL_EP_DELETE) && isTepDeletedOnDpn) {
+                if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE && isTepDeletedOnDpn) {
                     for (Uuid subnetId : subnetList) {
                         // Populate the List of subnets
                         vpnSubnetRouteHandler.updateSubnetRouteOnTunnelDownEvent(subnetId, srcDpnId);
@@ -402,7 +416,7 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
-    private void handleTunnelEventForDPNVpn(StateTunnelList stateTunnelList, UpdateRouteAction action,
+    private void handleTunnelEventForDPNVpn(StateTunnelList stateTunnelList,
                                             Map<Long, String> vpnIdRdMap, TunnelAction tunnelAction,
                                             boolean isTepDeletedOnDpn, List<Uuid> subnetList,
                                             TunnelEventProcessingMethod method,
@@ -410,8 +424,8 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
         String rd;
         String intfName = cfgVpnInterface.getName();
         final BigInteger srcDpnId = new BigInteger(stateTunnelList.getSrcInfo().getTepDeviceId());
-        String destTepIp = String.valueOf(stateTunnelList.getDstInfo().getTepIp().getValue());
-        String srcTepIp = String.valueOf(stateTunnelList.getSrcInfo().getTepIp().getValue());
+        String destTepIp = stateTunnelList.getDstInfo().getTepIp().stringValue();
+        String srcTepIp = stateTunnelList.getSrcInfo().getTepIp().stringValue();
         int tunTypeVal = getTunnelType(stateTunnelList);
         BigInteger remoteDpnId = null;
         if (tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
@@ -421,70 +435,78 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
             LOG.warn("handleTunnelEventForDpn: no vpnName found for interface {}", intfName);
             return;
         }
-        for (VpnInstanceNames vpnInstance : cfgVpnInterface.getVpnInstanceNames()) {
-            String vpnName = vpnInstance.getVpnName();
-            if (method == TunnelEventProcessingMethod.POPULATESUBNETS) {
-                Optional<VpnInterfaceOpDataEntry> opVpnInterface = VpnUtil
-                           .getVpnInterfaceOpDataEntry(dataBroker, intfName, vpnName);
-                if (opVpnInterface.isPresent() && !opVpnInterface.get().isScheduledForRemove()) {
-                    VpnInterfaceOpDataEntry vpnInterface  = opVpnInterface.get();
-                    jobCoordinator.enqueueJob("VPNINTERFACE-" + intfName,
-                            new UpdateVpnInterfaceOnTunnelEvent(tunnelAction,
-                                    vpnInterface,
-                                    stateTunnelList,
-                                    isTepDeletedOnDpn));
-
-                    // Populate the List of subnets
-                    InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
-                            InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
-                                    new PortOpDataEntryKey(intfName)).build();
-                    Optional<PortOpDataEntry> optionalPortOp =
-                            VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
-                    if (optionalPortOp.isPresent()) {
-                        List<Uuid> subnetIdList = optionalPortOp.get().getSubnetIds();
-                        if (subnetIdList != null) {
-                            for (Uuid subnetId : subnetIdList) {
-                                if (!subnetList.contains(subnetId)) {
-                                    subnetList.add(subnetId);
+        try {
+            for (VpnInstanceNames vpnInstance : cfgVpnInterface.getVpnInstanceNames()) {
+                String vpnName = vpnInstance.getVpnName();
+                if (method == TunnelEventProcessingMethod.POPULATESUBNETS) {
+                    Optional<VpnInterfaceOpDataEntry> opVpnInterface = vpnUtil
+                            .getVpnInterfaceOpDataEntry(intfName, vpnName);
+                    if (opVpnInterface.isPresent()) {
+                        VpnInterfaceOpDataEntry vpnInterface  = opVpnInterface.get();
+                        jobCoordinator.enqueueJob("VPNINTERFACE-" + intfName,
+                                new UpdateVpnInterfaceOnTunnelEvent(tunnelAction,
+                                        vpnInterface,
+                                        stateTunnelList,
+                                        isTepDeletedOnDpn));
+
+                        // Populate the List of subnets
+                        InstanceIdentifier<PortOpDataEntry> portOpIdentifier =
+                                InstanceIdentifier.builder(PortOpData.class).child(PortOpDataEntry.class,
+                                        new PortOpDataEntryKey(intfName)).build();
+                        Optional<PortOpDataEntry> optionalPortOp =
+                                SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                                        LogicalDatastoreType.OPERATIONAL, portOpIdentifier);
+                        if (optionalPortOp.isPresent()) {
+                            List<Uuid> subnetIdList = optionalPortOp.get().getSubnetIds();
+                            if (subnetIdList != null) {
+                                for (Uuid subnetId : subnetIdList) {
+                                    if (!subnetList.contains(subnetId)) {
+                                        subnetList.add(subnetId);
+                                    }
                                 }
                             }
                         }
+                        //Populate the map for VpnId-to-Rd
+                        long vpnId = vpnUtil.getVpnId(vpnName);
+                        rd = vpnUtil.getVpnRd(vpnName);
+                        vpnIdRdMap.put(vpnId, rd);
                     }
-                    //Populate the map for VpnId-to-Rd
-                    long vpnId = VpnUtil.getVpnId(dataBroker, vpnName);
-                    rd = VpnUtil.getVpnRd(dataBroker, vpnName);
-                    vpnIdRdMap.put(vpnId, rd);
-                }
-            } else if (method == TunnelEventProcessingMethod.MANAGEREMOTEROUTES) {
-                Optional<VpnInterfaceOpDataEntry> opVpnInterface = VpnUtil.getVpnInterfaceOpDataEntry(dataBroker,
-                        intfName, vpnName);
-                if (opVpnInterface.isPresent()) {
-                    VpnInterfaceOpDataEntry vpnInterface  = opVpnInterface.get();
-                    AdjacenciesOp adjacencies = vpnInterface.getAugmentation(AdjacenciesOp.class);
-                    List<Adjacency> adjList = adjacencies != null ? adjacencies.getAdjacency()
-                            : Collections.emptyList();
-                    String prefix = null;
-                    long vpnId = VpnUtil.getVpnId(dataBroker, vpnInterface.getVpnInstanceName());
-                    if (vpnIdRdMap.containsKey(vpnId)) {
-                        rd = vpnIdRdMap.get(vpnId);
-                        LOG.info("handleTunnelEventForDPN: Remote DpnId {} VpnId {} rd {} VpnInterface {} srcTepIp "
-                                + "{} destTepIp {}", remoteDpnId, vpnId, rd , vpnInterface, srcTepIp, destTepIp);
-                        for (Adjacency adj : adjList) {
-                            prefix = adj.getIpAddress();
-                            long label = adj.getLabel();
-                            if (tunnelAction == TunnelAction.TUNNEL_EP_ADD
-                                    && tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
-                                fibManager.manageRemoteRouteOnDPN(true, srcDpnId, vpnId, rd, prefix, destTepIp, label);
-                            }
-
-                            if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE
-                                    && tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
-                                fibManager.manageRemoteRouteOnDPN(false, srcDpnId, vpnId, rd, prefix, destTepIp, label);
+                } else if (method == TunnelEventProcessingMethod.MANAGEREMOTEROUTES) {
+                    Optional<VpnInterfaceOpDataEntry> opVpnInterface = vpnUtil.getVpnInterfaceOpDataEntry(intfName,
+                            vpnName);
+                    if (opVpnInterface.isPresent()) {
+                        VpnInterfaceOpDataEntry vpnInterface  = opVpnInterface.get();
+                        AdjacenciesOp adjacencies = vpnInterface.augmentation(AdjacenciesOp.class);
+                        List<Adjacency> adjList = adjacencies != null ? adjacencies.getAdjacency()
+                                : Collections.emptyList();
+                        String prefix = null;
+                        long vpnId = vpnUtil.getVpnId(vpnInterface.getVpnInstanceName());
+                        if (vpnIdRdMap.containsKey(vpnId)) {
+                            rd = vpnIdRdMap.get(vpnId);
+                            LOG.info("handleTunnelEventForDPN: Remote DpnId {} VpnId {} rd {} VpnInterface {}"
+                                    + " srcTepIp {} destTepIp {}", remoteDpnId, vpnId, rd , vpnInterface, srcTepIp,
+                                    destTepIp);
+                            for (Adjacency adj : adjList) {
+                                prefix = adj.getIpAddress();
+                                long label = adj.getLabel();
+                                if (tunnelAction == TunnelAction.TUNNEL_EP_ADD
+                                        && tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
+                                    fibManager.manageRemoteRouteOnDPN(true, srcDpnId, vpnId, rd, prefix, destTepIp,
+                                            label);
+                                }
+                                if (tunnelAction == TunnelAction.TUNNEL_EP_DELETE
+                                        && tunTypeVal == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
+                                    fibManager.manageRemoteRouteOnDPN(false, srcDpnId, vpnId, rd, prefix, destTepIp,
+                                            label);
+                                }
                             }
                         }
                     }
                 }
             }
+        } catch (ReadFailedException e) {
+            LOG.error("handleTunnelEventForDPN: Failed to read data store for interface {} srcDpn {} srcTep {} "
+                    + "dstTep {}", intfName, srcDpnId, srcTepIp, destTepIp);
         }
     }
 
@@ -506,26 +528,18 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
 
         @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(CONFIGURATION, confTx ->
+                futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, 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;
         }
     }
@@ -550,11 +564,12 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
 
     private void programDcGwLoadBalancingGroup(StateTunnelList tunnelState, int addOrRemove) {
         IpAddress dcGwIp = tunnelState.getDstInfo().getTepIp();
-        String dcGwIpAddress = String.valueOf(dcGwIp.getValue());
+        String dcGwIpAddress = dcGwIp.stringValue();
         List<String> availableDcGws = getDcGwIps();
         BigInteger dpId = new BigInteger(tunnelState.getSrcInfo().getTepDeviceId());
         boolean isTunnelUp = TunnelOperStatus.Up == tunnelState.getOperState();
-        fibManager.programDcGwLoadBalancingGroup(availableDcGws, dpId, dcGwIpAddress, addOrRemove, isTunnelUp);
+        fibManager.programDcGwLoadBalancingGroup(availableDcGws, dpId, dcGwIpAddress, addOrRemove, isTunnelUp,
+                tunnelState.getTransportType());
     }
 
     private List<String> getDcGwIps() {
@@ -563,12 +578,12 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
         DcGatewayIpList dcGatewayIpListConfig =
                 MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, dcGatewayIpListid).orNull();
         if (dcGatewayIpListConfig == null) {
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
         return dcGatewayIpListConfig.getDcGatewayIp()
                 .stream()
                 .filter(dcGwIp -> dcGwIp.getTunnnelType().equals(TunnelTypeMplsOverGre.class))
-                .map(dcGwIp -> String.valueOf(dcGwIp.getIpAddress().getValue())).sorted()
+                .map(dcGwIp -> dcGwIp.getIpAddress().stringValue()).sorted()
                 .collect(toList());
     }
 
@@ -576,9 +591,9 @@ public class TunnelInterfaceStateListener extends AsyncDataTreeChangeListenerBas
         String ifaceName = stateTunnelList.getTunnelInterfaceName();
         if (getTunnelType(stateTunnelList) == VpnConstants.ITMTunnelLocType.Internal.getValue()) {
             Interface configIface = InterfaceUtils.getInterface(dataBroker, stateTunnelList.getTunnelInterfaceName());
-            IfTunnel ifTunnel = configIface != null ? configIface.getAugmentation(IfTunnel.class) : null;
+            IfTunnel ifTunnel = configIface != null ? configIface.augmentation(IfTunnel.class) : null;
             if (ifTunnel != null && ifTunnel.getTunnelInterfaceType().isAssignableFrom(TunnelTypeVxlan.class)) {
-                ParentRefs refs = configIface.getAugmentation(ParentRefs.class);
+                ParentRefs refs = configIface.augmentation(ParentRefs.class);
                 if (refs != null && !Strings.isNullOrEmpty(refs.getParentInterface())) {
                     return true; //multiple VxLAN tunnels enabled, i.e. only logical tunnel should be treated
                 }