Genius Neon MRI changes
[genius.git] / interfacemanager / interfacemanager-impl / src / main / java / org / opendaylight / genius / interfacemanager / InterfacemgrProvider.java
index 7bc1ecc2cc9d13266f3429502778c592d47fc2e7..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,
@@ -8,7 +8,7 @@
 package org.opendaylight.genius.interfacemanager;
 
 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
-import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 
 import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
@@ -20,19 +20,22 @@ 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.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.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;
@@ -40,16 +43,16 @@ import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 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.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.rev140508.L2vlan;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
+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;
@@ -59,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;
@@ -105,7 +110,8 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     private final JobCoordinator coordinator;
     private final InterfaceManagerCommonUtils interfaceManagerCommonUtils;
     private final InterfaceMetaUtils interfaceMetaUtils;
-    private final InterfaceStatusMonitor interfaceStatusMonitor = new InterfaceStatusMonitor();
+    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;
@@ -116,7 +122,8 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     public InterfacemgrProvider(final DataBroker dataBroker, final EntityOwnershipService entityOwnershipService,
             final IdManagerService idManager, final InterfaceManagerRpcService interfaceManagerRpcService,
             final JobCoordinator coordinator, final InterfaceManagerCommonUtils interfaceManagerCommonUtils,
-            final InterfaceMetaUtils interfaceMetaUtils) {
+            final InterfaceMetaUtils interfaceMetaUtils, final IfmConfig ifmConfig,
+            final IfmDiagStatusProvider ifmStatusProvider) {
         this.dataBroker = dataBroker;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.entityOwnershipService = entityOwnershipService;
@@ -125,42 +132,36 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         this.coordinator = coordinator;
         this.interfaceManagerCommonUtils = interfaceManagerCommonUtils;
         this.interfaceMetaUtils = interfaceMetaUtils;
+        this.ifmConfig = ifmConfig;
+        this.ifmStatusProvider = ifmStatusProvider;
+        start();
     }
 
-    @PostConstruct
     @SuppressWarnings("checkstyle:IllegalCatch")
     public void start() {
         try {
-            interfaceStatusMonitor.registerMbean();
             createIdPool();
-
-            try {
-                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));
-            } catch (CandidateAlreadyRegisteredException e) {
-                LOG.error("Failed to register entity {} with EntityOwnershipService", e.getEntity());
-            }
-
+            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<>();
-
-            interfaceStatusMonitor.reportStatus("OPERATIONAL");
-        } catch (Exception e) {
-            interfaceStatusMonitor.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 {
-        interfaceStatusMonitor.unregisterMbean();
-
         if (configEntityCandidate != null) {
             configEntityCandidate.close();
         }
@@ -168,7 +169,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         if (bindingEntityCandidate != null) {
             bindingEntityCandidate.close();
         }
-
+        ifmStatusProvider.reportStatus(ServiceState.UNREGISTERED);
         LOG.info("InterfacemgrProvider Closed");
     }
 
@@ -180,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");
         }
     }
 
@@ -238,7 +235,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
 
         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;
         }
 
@@ -258,14 +255,6 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
             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);
@@ -274,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());
@@ -300,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);
@@ -315,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());
@@ -347,21 +328,13 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
             } else {
                 Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(interfaceName);
                 if (iface != null) {
-                    ParentRefs parentRefs = iface.getAugmentation(ParentRefs.class);
+                    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);
@@ -369,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());
@@ -394,6 +367,12 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         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 {
@@ -401,9 +380,9 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     }
 
     @Override
-    public void createVLANInterface(String interfaceName, String portName, Integer vlanId,
+    public ListenableFuture<Void> createVLANInterface(String interfaceName, String portName, Integer vlanId,
             String description, IfL2vlan.L2vlanMode l2vlanMode) throws InterfaceAlreadyExistsException {
-        createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, false);
+        return createVLANInterface(interfaceName, portName, vlanId, description, l2vlanMode, false);
     }
 
     @Override
@@ -414,15 +393,16 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     }
 
     @Override
-    public void createVLANInterface(String interfaceName, String portName, Integer vlanId,
-            String description, IfL2vlan.L2vlanMode l2vlanMode, boolean isExternal)
+    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));
         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);
@@ -438,10 +418,10 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         }
         InstanceIdentifier<Interface> interfaceIId = interfaceManagerCommonUtils
                 .getInterfaceIdentifier(new InterfaceKey(interfaceName));
-        ListenableFutures.addErrorLogging(
-            txRunner.callWithNewWriteOnlyTransactionAndSubmit(
-                tx -> tx.put(CONFIGURATION, interfaceIId, interfaceBuilder.build(), CREATE_MISSING_PARENTS)),
-            LOG, "Failed to (async) write {}", interfaceIId);
+        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,
@@ -475,11 +455,13 @@ 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);
         }
     }
 
@@ -545,7 +527,17 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
 
     @Override
     public List<Interface> getChildInterfaces(String parentInterface) {
-        InterfaceParentEntry parentEntry = interfaceMetaUtils.getInterfaceParentEntryFromConfigDS(parentInterface);
+        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();
@@ -560,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);
+            Interface iface = interfaceManagerCommonUtils.getInterfaceFromConfigDS(tx, interfaceName);
             if (iface != null) {
                 childInterfaces.add(iface);
             } else {
@@ -578,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());
     }
 
@@ -602,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);
         }
     }
@@ -677,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
@@ -739,7 +765,7 @@ 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);
                 if (iface == null) {
@@ -747,7 +773,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
                     return null;
                 }
             }
-            return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
+            return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
                 tx -> IfmUtil.updateInterfaceParentRef(tx, interfaceName, parentInterfaceName)));
         }
     }
@@ -783,8 +809,8 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         List<OvsdbTerminationPointAugmentation> ports = new ArrayList<>();
         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);
@@ -806,7 +832,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         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);
             }
@@ -835,7 +861,7 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
         if (ovsPorts != null) {
             for (TerminationPoint ovsPort : ovsPorts) {
                 OvsdbTerminationPointAugmentation portAug =
-                        ovsPort.getAugmentation(OvsdbTerminationPointAugmentation.class);
+                        ovsPort.augmentation(OvsdbTerminationPointAugmentation.class);
                 if (portAug != null && portAug.getInterfaceType() != null) {
                     portMap.computeIfAbsent(portAug.getInterfaceType(), k -> new ArrayList<>()).add(portAug);
                 }
@@ -848,4 +874,9 @@ public class InterfacemgrProvider implements AutoCloseable, IInterfaceManager {
     public long getLogicalTunnelSelectGroupId(int lportTag) {
         return IfmUtil.getLogicalTunnelSelectGroupId(lportTag);
     }
+
+    @Override
+    public boolean isItmDirectTunnelsEnabled() {
+        return ifmConfig.isItmDirectTunnels();
+    }
 }