Genius Neon MRI changes
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / InterfacemgrProvider.java
index 9fd96b564c60bb57b0b807c7ddc2de1b6484dda1..44552c392cc3cdfcf9da004c83597caf5ce9ca5e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ * Copyright (c) 2016, 2018 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -7,45 +7,52 @@
  */
 package org.opendaylight.genius.interfacemanager;
 
-import com.google.common.util.concurrent.CheckedFuture;
+import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
 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.Map;
-import java.util.Optional;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
-import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 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.clustering.EntityOwnershipService;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.interfacemanager.commons.InterfaceManagerCommonUtils;
 import org.opendaylight.genius.interfacemanager.commons.InterfaceMetaUtils;
+import org.opendaylight.genius.interfacemanager.diagstatus.IfmDiagStatusProvider;
 import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo.InterfaceAdminState;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
-import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.BatchingUtils;
-import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.IfmClusterUtils;
 import org.opendaylight.genius.interfacemanager.renderer.ovs.utilities.SouthboundUtils;
 import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerRpcService;
 import org.opendaylight.genius.interfacemanager.servicebindings.flowbased.utilities.FlowBasedServicesUtils;
-import org.opendaylight.genius.interfacemanager.statusanddiag.InterfaceStatusMonitor;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
+import org.opendaylight.infrautils.diagstatus.ServiceState;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
+import org.opendaylight.mdsal.eos.binding.api.Entity;
+import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
+import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
+import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev170119.Tunnel;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
@@ -55,7 +62,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.config.rev160406.IfmConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info.InterfaceParentEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._interface.child.info._interface.parent.entry.InterfaceChildEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternal;
@@ -92,47 +101,75 @@ import org.slf4j.LoggerFactory;
 @Singleton
 public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     private static final Logger LOG = LoggerFactory.getLogger(InterfacemgrProvider.class);
-    private static final InterfaceStatusMonitor INTERFACE_STATUS_MONITOR = InterfaceStatusMonitor.getInstance();
+
     private final DataBroker dataBroker;
+    private final ManagedNewTransactionRunner txRunner;
     private final IdManagerService idManager;
     private final InterfaceManagerRpcService interfaceManagerRpcService;
     private final EntityOwnershipService entityOwnershipService;
+    private final JobCoordinator coordinator;
+    private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
+    private final InterfaceMetaUtils interfaceMetaUtils;
+    private final IfmConfig ifmConfig;
+    private final IfmDiagStatusProvider ifmStatusProvider;
     private Map<String, OvsdbTerminationPointAugmentation> ifaceToTpMap;
     private Map<String, InstanceIdentifier<Node>> ifaceToNodeIidMap;
     private Map<InstanceIdentifier<Node>, OvsdbBridgeAugmentation> nodeIidToBridgeMap;
+    private EntityOwnershipCandidateRegistration configEntityCandidate;
+    private EntityOwnershipCandidateRegistration bindingEntityCandidate;
 
     @Inject
     public InterfacemgrProvider(final DataBroker dataBroker, final EntityOwnershipService entityOwnershipService,
-            final IdManagerService idManager, final InterfaceManagerRpcService interfaceManagerRpcService) {
+            final IdManagerService idManager, final InterfaceManagerRpcService interfaceManagerRpcService,
+            final JobCoordinator coordinator, final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
+            final InterfaceMetaUtils interfaceMetaUtils, final IfmConfig ifmConfig,
+            final IfmDiagStatusProvider ifmStatusProvider) {
         this.dataBroker = dataBroker;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.entityOwnershipService = entityOwnershipService;
         this.idManager = idManager;
         this.interfaceManagerRpcService = interfaceManagerRpcService;
+        this.coordinator = coordinator;
+        this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
+        this.interfaceMetaUtils = interfaceMetaUtils;
+        this.ifmConfig = ifmConfig;
+        this.ifmStatusProvider = ifmStatusProvider;
+        start();
     }
 
-    @PostConstruct
     @SuppressWarnings("checkstyle:IllegalCatch")
     public void start() {
         try {
-            INTERFACE_STATUS_MONITOR.registerMbean();
             createIdPool();
-            IfmClusterUtils.registerEntityForOwnership(this, this.entityOwnershipService);
-            BatchingUtils.registerWithBatchManager(this.dataBroker);
+            configEntityCandidate = entityOwnershipService.registerCandidate(
+                    new Entity(IfmConstants.INTERFACE_CONFIG_ENTITY, IfmConstants.INTERFACE_CONFIG_ENTITY));
+            bindingEntityCandidate = entityOwnershipService.registerCandidate(
+                    new Entity(IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY,
+                            IfmConstants.INTERFACE_SERVICE_BINDING_ENTITY));
             this.ifaceToTpMap = new ConcurrentHashMap<>();
             this.ifaceToNodeIidMap = new ConcurrentHashMap<>();
             this.nodeIidToBridgeMap = new ConcurrentHashMap<>();
-
-            INTERFACE_STATUS_MONITOR.reportStatus("OPERATIONAL");
-        } catch (Exception e) {
-            INTERFACE_STATUS_MONITOR.reportStatus("ERROR");
-            throw e;
+            ifmStatusProvider.reportStatus(ServiceState.OPERATIONAL);
+            LOG.info("InterfacemgrProvider Started");
+        } catch (CandidateAlreadyRegisteredException e) {
+            LOG.error("Failed to register entity {} with EntityOwnershipService", e.getEntity());
+            ifmStatusProvider.reportStatus(e);
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Failed to create idPool for InterfaceMgr", e);
         }
-        LOG.info("InterfacemgrProvider Started");
     }
 
     @Override
     @PreDestroy
     public void close() throws Exception {
+        if (configEntityCandidate != null) {
+            configEntityCandidate.close();
+        }
+
+        if (bindingEntityCandidate != null) {
+            bindingEntityCandidate.close();
+        }
+        ifmStatusProvider.reportStatus(ServiceState.UNREGISTERED);
         LOG.info("InterfacemgrProvider Closed");
     }
 
@@ -144,17 +181,13 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         return this.dataBroker;
     }
 
-    private void createIdPool() {
+    private void createIdPool() throws ExecutionException, InterruptedException {
         CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(IfmConstants.IFM_IDPOOL_NAME)
                 .setLow(IfmConstants.IFM_ID_POOL_START).setHigh(IfmConstants.IFM_ID_POOL_END).build();
         // TODO: Error handling
-        Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
-        try {
-            if (result != null && result.get().isSuccessful()) {
-                LOG.debug("Created IdPool for InterfaceMgr");
-            }
-        } catch (InterruptedException | ExecutionException e) {
-            LOG.error("Failed to create idPool for InterfaceMgr", e);
+        ListenableFuture<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
+        if (result != null && result.get().isSuccessful()) {
+            LOG.debug("Created IdPool for InterfaceMgr");
         }
     }
 
@@ -192,22 +225,22 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     public InterfaceInfo getInterfaceInfo(String interfaceName) {
 
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
-            .ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
-                .getInterfaceState(interfaceName, dataBroker);
+            .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
+                .getInterfaceState(interfaceName);
 
         if (ifState == null) {
-            LOG.error("Interface {} is not present", interfaceName);
+            LOG.debug("Interface {} is not present", interfaceName);
             return null;
         }
 
-        Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName),
-                dataBroker);
+        Interface intf = interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
         if (intf == null) {
-            LOG.error("Interface {} doesn't exist in config datastore", interfaceName);
+            LOG.warn("Interface {} doesn't exist in config datastore", interfaceName);
             return null;
         }
 
-        NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(intf.getName(), dataBroker);
+        NodeConnectorId ncId = FlowBasedServicesUtils.getNodeConnectorIdFromInterface(intf.getName(),
+                interfaceManagerCommonUtils);
         InterfaceInfo.InterfaceType interfaceType = IfmUtil.getInterfaceType(intf);
         InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
         BigInteger dpId = org.opendaylight.genius.interfacemanager.globals.IfmConstants.INVALID_DPID;
@@ -217,19 +250,11 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
             portNo = Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId));
         }
         if (interfaceType == InterfaceInfo.InterfaceType.VLAN_INTERFACE) {
-            interfaceInfo = IfmUtil.getVlanInterfaceInfo(interfaceName, intf, dpId);
+            interfaceInfo = IfmUtil.getVlanInterfaceInfo(intf, dpId);
         } else if (interfaceType == InterfaceInfo.InterfaceType.UNKNOWN_INTERFACE) {
             LOG.error("Type of Interface {} is unknown", interfaceName);
             return null;
         }
-        InterfaceInfo.InterfaceOpState opState;
-        if (ifState.getOperStatus() == OperStatus.Up) {
-            opState = InterfaceInfo.InterfaceOpState.UP;
-        } else if (ifState.getOperStatus() == OperStatus.Down) {
-            opState = InterfaceInfo.InterfaceOpState.DOWN;
-        } else {
-            opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
-        }
         interfaceInfo.setDpId(dpId);
         interfaceInfo.setPortNo(portNo);
         interfaceInfo.setAdminState(intf.isEnabled() ? InterfaceAdminState.ENABLED : InterfaceAdminState.DISABLED);
@@ -238,7 +263,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         interfaceInfo.setInterfaceTag(lportTag);
         interfaceInfo.setInterfaceType(interfaceType);
         interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
-        interfaceInfo.setOpState(opState);
+        interfaceInfo.setOpState(InterfaceInfo.InterfaceOpState.fromModel(ifState.getOperStatus()));
         PhysAddress phyAddress = ifState.getPhysAddress();
         if (phyAddress != null) {
             interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
@@ -254,10 +279,9 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         InterfaceInfo interfaceInfo = new InterfaceInfo(interfaceName);
         org.opendaylight.yang.gen.v1.urn
             .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState =
-                InterfaceManagerCommonUtils
-                .getInterfaceState(interfaceName, dataBroker);
+                interfaceManagerCommonUtils.getInterfaceState(interfaceName);
         if (ifState == null) {
-            LOG.error("Interface {} is not present", interfaceName);
+            LOG.debug("Interface {} is not present", interfaceName);
             return null;
         }
         NodeConnectorId ncId = IfmUtil.getNodeConnectorIdFromInterface(ifState);
@@ -265,14 +289,6 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
             interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
             interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
         }
-        InterfaceInfo.InterfaceOpState opState;
-        if (ifState.getOperStatus() == OperStatus.Up) {
-            opState = InterfaceInfo.InterfaceOpState.UP;
-        } else if (ifState.getOperStatus() == OperStatus.Down) {
-            opState = InterfaceInfo.InterfaceOpState.DOWN;
-        } else {
-            opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
-        }
         interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
                 : InterfaceAdminState.DISABLED);
         interfaceInfo.setInterfaceName(interfaceName);
@@ -280,7 +296,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         interfaceInfo.setInterfaceTag(lportTag);
         interfaceInfo.setInterfaceType(interfaceType);
         interfaceInfo.setGroupId(IfmUtil.getGroupId(lportTag, interfaceType));
-        interfaceInfo.setOpState(opState);
+        interfaceInfo.setOpState(InterfaceInfo.InterfaceOpState.fromModel(ifState.getOperStatus()));
         PhysAddress phyAddress = ifState.getPhysAddress();
         if (phyAddress != null) {
             interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
@@ -291,10 +307,10 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     @Override
     public InterfaceInfo getInterfaceInfoFromOperationalDataStore(String interfaceName) {
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
-            .ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
-                .getInterfaceState(interfaceName, dataBroker);
+            .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
+                .getInterfaceState(interfaceName);
         if (ifState == null) {
-            LOG.error("Interface {} is not present", interfaceName);
+            LOG.debug("Interface {} is not present", interfaceName);
             return null;
         }
 
@@ -310,21 +326,15 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
             if (Tunnel.class.equals(ifState.getType())) {
                 interfaceInfo.setPortName(interfaceName);
             } else {
-                Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
-                ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
-                interfaceInfo.setPortName(parentRefs.getParentInterface());
+                Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
+                if (iface != null) {
+                    ParentRefs parentRefs = iface.augmentation(ParentRefs.class);
+                    interfaceInfo.setPortName(parentRefs.getParentInterface());
+                }
             }
             interfaceInfo.setDpId(IfmUtil.getDpnFromNodeConnectorId(ncId));
             interfaceInfo.setPortNo(Integer.parseInt(IfmUtil.getPortNoFromNodeConnectorId(ncId)));
         }
-        InterfaceInfo.InterfaceOpState opState;
-        if (ifState.getOperStatus() == OperStatus.Up) {
-            opState = InterfaceInfo.InterfaceOpState.UP;
-        } else if (ifState.getOperStatus() == OperStatus.Down) {
-            opState = InterfaceInfo.InterfaceOpState.DOWN;
-        } else {
-            opState = InterfaceInfo.InterfaceOpState.UNKNOWN;
-        }
         interfaceInfo.setAdminState(ifState.getAdminStatus() == AdminStatus.Up ? InterfaceAdminState.ENABLED
                 : InterfaceAdminState.DISABLED);
         interfaceInfo.setInterfaceName(interfaceName);
@@ -332,7 +342,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         if (lportTag != null) {
             interfaceInfo.setInterfaceTag(lportTag);
         }
-        interfaceInfo.setOpState(opState);
+        interfaceInfo.setOpState(InterfaceInfo.InterfaceOpState.fromModel(ifState.getOperStatus()));
         PhysAddress phyAddress = ifState.getPhysAddress();
         if (phyAddress != null) {
             interfaceInfo.setMacAddress(ifState.getPhysAddress().getValue());
@@ -343,7 +353,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     @Override
     public InterfaceInfo getInterfaceInfoFromOperationalDSCache(String interfaceName) {
         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
-            .ietf.interfaces.rev140508.interfaces.state.Interface ifState = InterfaceManagerCommonUtils
+            .ietf.interfaces.rev140508.interfaces.state.Interface ifState = interfaceManagerCommonUtils
                 .getInterfaceStateFromCache(interfaceName);
         if (ifState == null) {
             LOG.warn("Interface {} is not present", interfaceName);
@@ -354,27 +364,45 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
 
     @Override
     public Interface getInterfaceInfoFromConfigDataStore(String interfaceName) {
-        Interface intf = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName),
-                dataBroker);
-        return intf;
+        return interfaceManagerCommonUtils.getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
+    }
+
+    @Override
+    public Interface getInterfaceInfoFromConfigDataStore(ReadTransaction tx, String interfaceName)
+            throws ReadFailedException {
+        return interfaceManagerCommonUtils.getInterfaceFromConfigDS(tx, new InterfaceKey(interfaceName));
     }
 
     @Override
     public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
             String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
-        createVLANInterface(interfaceName, portName, dpId, vlanId, description, l2vlanMode, false);
+        createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode);
+    }
+
+    @Override
+    public ListenableFuture<Void> createVLANInterface(String interfaceName, String portName, Integer vlanId,
+            String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
+        return createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, false);
     }
 
     @Override
     public void createVLANInterface(String interfaceName, String portName, BigInteger dpId, Integer vlanId,
             String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
             throws InterfaceAlreadyExistsException {
+        createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, isExternal);
+    }
+
+    @Override
+    public ListenableFuture<Void> createVLANInterface(String interfaceName, String portName, Integer vlanId,
+                                                      String description, IfL2vlan.L2vlanMode l2vlanMode,
+                                                      boolean isExternal)
+            throws InterfaceAlreadyExistsException {
 
         LOG.info("Create VLAN interface : {}", interfaceName);
-        Interface interfaceOptional = InterfaceManagerCommonUtils
-                .getInterfaceFromConfigDS(new InterfaceKey(interfaceName), dataBroker);
+        Interface interfaceOptional = interfaceManagerCommonUtils
+                .getInterfaceFromConfigDS(new InterfaceKey(interfaceName));
         if (interfaceOptional != null) {
-            LOG.debug("VLAN interface is already exist", interfaceOptional.getDescription());
+            LOG.debug("VLAN interface already exists {} ", interfaceOptional.getDescription());
             throw new InterfaceAlreadyExistsException(interfaceOptional.getName());
         }
         IfL2vlanBuilder l2vlanBuilder = new IfL2vlanBuilder().setL2vlanMode(l2vlanMode);
@@ -388,12 +416,12 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         if (isExternal) {
             interfaceBuilder.addAugmentation(IfExternal.class, new IfExternalBuilder().setExternal(true).build());
         }
-        InstanceIdentifier<Interface> interfaceInstanceIdentifier = InterfaceManagerCommonUtils
+        InstanceIdentifier<Interface> interfaceIId = interfaceManagerCommonUtils
                 .getInterfaceIdentifier(new InterfaceKey(interfaceName));
-        WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
-        writeTransaction.put(LogicalDatastoreType.CONFIGURATION, interfaceInstanceIdentifier, interfaceBuilder.build(),
-                true);
-        writeTransaction.submit();
+        ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+            tx -> tx.put(interfaceIId, interfaceBuilder.build(), CREATE_MISSING_PARENTS));
+        ListenableFutures.addErrorLogging(future, LOG, "Failed to (async) write {}", interfaceIId);
+        return future;
     }
 
     private boolean isServiceBoundOnInterface(short servicePriority, String interfaceName,
@@ -427,18 +455,20 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
 
     @Override
     public void bindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
-            BoundServices serviceInfo, WriteTransaction tx) {
-        WriteTransaction writeTransaction = tx != null ? tx : dataBroker.newWriteOnlyTransaction();
-        IfmUtil.bindService(writeTransaction, interfaceName, serviceInfo, serviceMode);
+            BoundServices serviceInfo, TypedWriteTransaction<Configuration> tx) {
         if (tx == null) {
-            writeTransaction.submit();
+            ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                wtx -> IfmUtil.bindService(wtx, interfaceName, serviceInfo, serviceMode)), LOG,
+                "Error binding the InterfacemgrProvider service");
+        } else {
+            IfmUtil.bindService(tx, interfaceName, serviceInfo, serviceMode);
         }
     }
 
     @Override
     public void unbindService(String interfaceName, Class<? extends ServiceModeBase> serviceMode,
             BoundServices serviceInfo) {
-        IfmUtil.unbindService(dataBroker, interfaceName,
+        IfmUtil.unbindService(txRunner, coordinator, interfaceName,
                 FlowBasedServicesUtils.buildServiceId(interfaceName, serviceInfo.getServicePriority(), serviceMode));
     }
 
@@ -482,23 +512,32 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
 
     @Override
     public List<ActionInfo> getInterfaceEgressActions(String ifName) {
-        return IfmUtil.getEgressActionInfosForInterface(ifName, 0, dataBroker, false);
+        return IfmUtil.getEgressActionInfosForInterface(ifName, 0, interfaceManagerCommonUtils, false);
     }
 
     @Override
     public List<Interface> getVlanInterfaces() {
-        return InterfaceManagerCommonUtils.getAllVlanInterfacesFromCache();
+        return interfaceManagerCommonUtils.getAllVlanInterfacesFromCache();
     }
 
     @Override
     public List<Interface> getVxlanInterfaces() {
-        return InterfaceManagerCommonUtils.getAllTunnelInterfacesFromCache();
+        return interfaceManagerCommonUtils.getAllTunnelInterfacesFromCache();
     }
 
     @Override
     public List<Interface> getChildInterfaces(String parentInterface) {
-        InterfaceParentEntry parentEntry = InterfaceMetaUtils.getInterfaceParentEntryFromConfigDS(parentInterface,
-                dataBroker);
+        try (ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction()) {
+            return getChildInterfaces(tx, parentInterface);
+        } catch (ReadFailedException e) {
+            LOG.error("Error retrieving child interfaces of {} from config", parentInterface, e);
+            throw new RuntimeException("Error retrieving child interfaces of " + parentInterface + " from config", e);
+        }
+    }
+
+    @Override
+    public List<Interface> getChildInterfaces(ReadTransaction tx, String parentInterface) throws ReadFailedException {
+        InterfaceParentEntry parentEntry = interfaceMetaUtils.getInterfaceParentEntryFromConfigDS(tx, parentInterface);
         if (parentEntry == null) {
             LOG.debug("No parent entry found for {}", parentInterface);
             return Collections.emptyList();
@@ -513,7 +552,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         List<Interface> childInterfaces = new ArrayList<>();
         for (InterfaceChildEntry childEntry : childEntries) {
             String interfaceName = childEntry.getChildInterface();
-            Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
+            Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(tx, interfaceName);
             if (iface != null) {
                 childInterfaces.add(iface);
             } else {
@@ -531,12 +570,17 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         return isExternalInterface(getInterfaceInfoFromConfigDataStore(interfaceName));
     }
 
+    @Override
+    public boolean isExternalInterface(ReadTransaction tx, String interfaceName) throws ReadFailedException {
+        return isExternalInterface(getInterfaceInfoFromConfigDataStore(tx, interfaceName));
+    }
+
     private boolean isExternalInterface(Interface iface) {
         if (iface == null) {
             return false;
         }
 
-        IfExternal ifExternal = iface.getAugmentation(IfExternal.class);
+        IfExternal ifExternal = iface.augmentation(IfExternal.class);
         return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
     }
 
@@ -555,10 +599,16 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         return new ConcurrentHashMap<>(this.ifaceToTpMap);
     }
 
+    @Override
+    public Map<String, OperStatus> getBfdStateCache() {
+        return interfaceManagerCommonUtils.getBfdStateMap();
+    }
+
     public void addTerminationPointForInterface(String interfaceName,
             OvsdbTerminationPointAugmentation terminationPoint) {
-        LOG.debug("Adding TerminationPoint {} to cache for Interface {}", terminationPoint.getName(), interfaceName);
         if (interfaceName != null && terminationPoint != null) {
+            LOG.debug("Adding TerminationPoint {} to cache for Interface {}", terminationPoint.getName(),
+                    interfaceName);
             ifaceToTpMap.put(interfaceName, terminationPoint);
         }
     }
@@ -630,10 +680,33 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     }
 
     public OvsdbBridgeAugmentation getBridgeForNodeIid(InstanceIdentifier<Node> nodeIid) {
-        if (nodeIid != null) {
-            return nodeIidToBridgeMap.get(nodeIid);
+        if (nodeIid == null) {
+            return null;
         }
-        return null;
+
+        OvsdbBridgeAugmentation ret = nodeIidToBridgeMap.get(nodeIid);
+        if (ret != null) {
+            return ret;
+        }
+
+        LOG.info("Node {} not found in cache, reading from md-sal", nodeIid);
+        Node node;
+        try {
+            node = SingleTransactionDataBroker.syncRead(
+                                        dataBroker, LogicalDatastoreType.OPERATIONAL, nodeIid);
+        } catch (ReadFailedException e) {
+            LOG.error("Failed to read Node for {} ", nodeIid, e);
+            return null;
+        }
+
+        OvsdbBridgeAugmentation bridge = node.augmentation(OvsdbBridgeAugmentation.class);
+        if (bridge == null) {
+            LOG.error("Node {} has no bridge augmentation");
+            return null;
+        }
+
+        addBridgeForNodeIid(nodeIid, bridge);
+        return bridge;
     }
 
     @Override
@@ -674,10 +747,9 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
             return;
         }
 
-        DataStoreJobCoordinator jobCoordinator = DataStoreJobCoordinator.getInstance();
         ParentRefUpdateWorker parentRefUpdateWorker = new ParentRefUpdateWorker(interfaceName, parentInterface,
                 readInterfaceBeforeWrite);
-        jobCoordinator.enqueueJob(interfaceName, parentRefUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
+        coordinator.enqueueJob(interfaceName, parentRefUpdateWorker, IfmConstants.JOB_MAX_RETRIES);
     }
 
     public class ParentRefUpdateWorker implements Callable<List<ListenableFuture<Void>>> {
@@ -693,20 +765,16 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         }
 
         @Override
-        public List<ListenableFuture<Void>> call() throws Exception {
+        public List<ListenableFuture<Void>> call() {
             if (readInterfaceBeforeWrite) {
-                Interface iface = InterfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName, dataBroker);
+                Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
                 if (iface == null) {
                     LOG.debug("Interface doesn't exist in config DS - no need to update parentRef, skipping");
                     return null;
                 }
             }
-            WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
-            IfmUtil.updateInterfaceParentRef(writeTransaction, interfaceName, parentInterfaceName);
-            CheckedFuture<Void, TransactionCommitFailedException> submitFuture = writeTransaction.submit();
-            List<ListenableFuture<Void>> futures = new ArrayList<>();
-            futures.add(submitFuture);
-            return futures;
+            return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
+                tx -> IfmUtil.updateInterfaceParentRef(tx, interfaceName, parentInterfaceName)));
         }
     }
 
@@ -739,10 +807,10 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
      */
     public List<OvsdbTerminationPointAugmentation> getPortsOnBridge(BigInteger dpnId) {
         List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
-        List<TerminationPoint> portList = IfmUtil.getTerminationPointsOnBridge(dataBroker, dpnId);
+        List<TerminationPoint> portList = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
         for (TerminationPoint ovsPort : portList) {
-            if (ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class) != null) {
-                ports.add(ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class));
+            if (ovsPort.augmentation(OvsdbTerminationPointAugmentation.class) != null) {
+                ports.add(ovsPort.augmentation(OvsdbTerminationPointAugmentation.class));
             }
         }
         LOG.debug("Found {} ports on bridge {}", ports.size(), dpnId);
@@ -761,10 +829,10 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     @Override
     public List<OvsdbTerminationPointAugmentation> getTunnelPortsOnBridge(BigInteger dpnId) {
         List<OvsdbTerminationPointAugmentation> tunnelPorts = new ArrayList<>();
-        List<TerminationPoint> portList = IfmUtil.getTerminationPointsOnBridge(dataBroker, dpnId);
+        List<TerminationPoint> portList = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
         for (TerminationPoint ovsPort : portList) {
             OvsdbTerminationPointAugmentation portAug =
-                    ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
+                    ovsPort.augmentation(OvsdbTerminationPointAugmentation.class);
             if (portAug != null && SouthboundUtils.isInterfaceTypeTunnel(portAug.getInterfaceType())) {
                 tunnelPorts.add(portAug);
             }
@@ -789,19 +857,16 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
 
         Map<Class<? extends InterfaceTypeBase>, List<OvsdbTerminationPointAugmentation>> portMap;
         portMap = new ConcurrentHashMap<>();
-        Optional<List<TerminationPoint>> portList =
-                Optional.ofNullable(IfmUtil.getTerminationPointsOnBridge(dataBroker, dpnId));
-        portList.ifPresent(ovsPorts -> ovsPorts.parallelStream().forEach(ovsPort -> {
-            OvsdbTerminationPointAugmentation portAug =
-                            ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
-            if (portAug != null && portAug.getInterfaceType() != null) {
-                if (portMap.get(portAug.getInterfaceType()) ==  null) {
-                    portMap.put(portAug.getInterfaceType(), new ArrayList<>());
+        List<TerminationPoint> ovsPorts = interfaceMetaUtils.getTerminationPointsOnBridge(dpnId);
+        if (ovsPorts != null) {
+            for (TerminationPoint ovsPort : ovsPorts) {
+                OvsdbTerminationPointAugmentation portAug =
+                        ovsPort.augmentation(OvsdbTerminationPointAugmentation.class);
+                if (portAug != null && portAug.getInterfaceType() != null) {
+                    portMap.computeIfAbsent(portAug.getInterfaceType(), k -> new ArrayList<>()).add(portAug);
                 }
-                portMap.get(portAug.getInterfaceType()).add(portAug);
             }
-        }));
-
+        }
         return portMap;
     }
 
@@ -810,4 +875,8 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         return IfmUtil.getLogicalTunnelSelectGroupId(lportTag);
     }
 
+    @Override
+    public boolean isItmDirectTunnelsEnabled() {
+        return ifmConfig.isItmDirectTunnels();
+    }
 }