Rpc changes for performance enhacements 97/68397/30
authorEdw7n <n.edwin.anthony@ericsson.com>
Thu, 19 Apr 2018 04:18:25 +0000 (09:48 +0530)
committerDimple Jain <dimple.jain@ericsson.com>
Fri, 27 Apr 2018 00:42:28 +0000 (06:12 +0530)
corresponding netvirt changes:
https://git.opendaylight.org/gerrit/#/c/68187/

Change-Id: I142de600b189ba1e803779a7ba47be714efb4764
Signed-off-by: Edw7n <n.edwin.anthony@ericsson.com>
itm/itm-impl/src/main/java/org/opendaylight/genius/itm/rpc/ItmManagerRpcService.java
itm/itm-impl/src/main/resources/org/opendaylight/blueprint/itm.xml
itm/itm-impl/src/test/java/org/opendaylight/genius/itm/impl/ItmManagerRpcServiceTest.java
itm/itm-impl/src/test/java/org/opendaylight/genius/itm/tests/ItmTestModule.java

index f19d49b1ba750660385f08c180669fb2b2a33f47..71ff9d2fc2c65c23dbd7dfd272cfe1ad83d05e4d 100644 (file)
@@ -7,6 +7,10 @@
  */
 package org.opendaylight.genius.itm.rpc;
 
+import static org.opendaylight.genius.tools.mdsal.rpc.FutureRpcResults.LogLevel.ERROR;
+import static org.opendaylight.genius.tools.mdsal.rpc.FutureRpcResults.fromListenableFuture;
+import static org.opendaylight.yangtools.yang.common.RpcResultBuilder.failed;
+
 import com.google.common.base.Objects;
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.FutureCallback;
@@ -23,6 +27,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Future;
 import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
@@ -32,19 +37,29 @@ 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.SingleTransactionDataBroker;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService;
 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
+import org.opendaylight.genius.itm.cache.DpnTepStateCache;
+import org.opendaylight.genius.itm.cache.TunnelStateCache;
 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelAddWorker;
 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelDeleteWorker;
 import org.opendaylight.genius.itm.globals.ITMConstants;
 import org.opendaylight.genius.itm.impl.ItmUtils;
+import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
+import org.opendaylight.genius.mdsalutil.ActionInfo;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.MatchInfo;
 import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
+import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
 import org.opendaylight.genius.tools.mdsal.rpc.FutureRpcResults;
 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.inet.types.rev130715.IpAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
@@ -61,6 +76,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
@@ -89,6 +105,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.G
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnInfoOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutputBuilder;
@@ -100,6 +117,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.G
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutputBuilder;
@@ -126,22 +144,32 @@ import org.slf4j.LoggerFactory;
 public class ItmManagerRpcService implements ItmRpcService {
 
     private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class);
+
     private final DataBroker dataBroker;
     private final IMdsalApiManager mdsalManager;
     private final DPNTEPsInfoCache dpnTEPsInfoCache;
     private final ItmExternalTunnelAddWorker externalTunnelAddWorker;
-    private final ItmConfig itmConfig;
     private final SingleTransactionDataBroker singleTransactionDataBroker;
+    private final IInterfaceManager interfaceManager;
+    private final InterfaceManagerService interfaceManagerService;
+    private final DpnTepStateCache dpnTepStateCache;
+    private final TunnelStateCache tunnelStateCache;
 
     @Inject
     public ItmManagerRpcService(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
-            final ItmConfig itmConfig, final DPNTEPsInfoCache dpnTEPsInfoCache) {
+                                final ItmConfig itmConfig, final DPNTEPsInfoCache dpnTEPsInfoCache,
+                                final IInterfaceManager interfaceManager, final DpnTepStateCache dpnTepStateCache,
+                                final TunnelStateCache tunnelStateCache,
+                                final InterfaceManagerService interfaceManagerService) {
         this.dataBroker = dataBroker;
         this.mdsalManager = mdsalManager;
         this.dpnTEPsInfoCache = dpnTEPsInfoCache;
         this.externalTunnelAddWorker = new ItmExternalTunnelAddWorker(dataBroker, itmConfig, dpnTEPsInfoCache);
-        this.itmConfig = itmConfig;
         this.singleTransactionDataBroker = new SingleTransactionDataBroker(dataBroker);
+        this.interfaceManager = interfaceManager;
+        this.interfaceManagerService = interfaceManagerService;
+        this.dpnTepStateCache = dpnTepStateCache;
+        this.tunnelStateCache = tunnelStateCache;
     }
 
     @PostConstruct
@@ -178,26 +206,104 @@ public class ItmManagerRpcService implements ItmRpcService {
                 resultBld = RpcResultBuilder.success();
                 resultBld.withResult(output.build());
             } else {
-                resultBld = RpcResultBuilder.failed();
+                resultBld = failed();
             }
 
         } else {
-            resultBld = RpcResultBuilder.failed();
+            resultBld = failed();
         }
         return Futures.immediateFuture(resultBld.build());
     }
 
     @Override
-    public Future<RpcResult<GetEgressActionsForTunnelOutput>> getEgressActionsForTunnel(
-            GetEgressActionsForTunnelInput input) {
-        //TODO
-        return null;
+    public Future<RpcResult<GetEgressActionsForTunnelOutput>>
+        getEgressActionsForTunnel(GetEgressActionsForTunnelInput input) {
+        String tunnelName = input.getIntfName();
+        if (tunnelName == null) {
+            return Futures.immediateFuture(RpcResultBuilder.<GetEgressActionsForTunnelOutput>failed()
+                    .withError(RpcError.ErrorType.APPLICATION,
+                    "tunnel name not set for GetEgressActionsForTunnel call").build());
+        }
+
+        if (!dpnTepStateCache.isInternal(tunnelName) && !interfaceManager.isItmDirectTunnelsEnabled()) {
+            // Re-direct the RPC to Interface Manager
+            // From the rpc input and get the output and copy to output
+            org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406
+                    .GetEgressActionsForInterfaceInputBuilder inputIfmBuilder =
+                    new org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406
+                            .GetEgressActionsForInterfaceInputBuilder().setIntfName(input.getIntfName())
+                            .setTunnelKey(input.getTunnelKey()).setActionKey(input.getActionKey());
+            SettableFuture<RpcResult<GetEgressActionsForTunnelOutput>> settableFuture = SettableFuture.create();
+            Futures.addCallback(interfaceManagerService.getEgressActionsForInterface(inputIfmBuilder.build()),
+                    new FutureCallback<org.opendaylight.yang.gen.v1.urn.opendaylight.genius
+                            .interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput>() {
+                        @Override
+                        public void onSuccess(@Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.genius
+                                .interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput result) {
+                            GetEgressActionsForTunnelOutputBuilder output =
+                                    new GetEgressActionsForTunnelOutputBuilder().setAction(result.getAction());
+                            settableFuture.set(RpcResultBuilder.<GetEgressActionsForTunnelOutput>success()
+                                    .withResult(output.build()).build());
+                        }
+
+                        @Override
+                        public void onFailure(Throwable throwable) {
+                            LOG.debug("RPC Call to Get egress actions failed for interface {}", tunnelName);
+                            String errMsg = String.format("RPC call to get egress actions failed for interface %s",
+                                    tunnelName);
+                            settableFuture.set(RpcResultBuilder.<GetEgressActionsForTunnelOutput>failed()
+                                    .withError(RpcError.ErrorType.APPLICATION, errMsg, throwable).build());
+                        }
+                });
+            return  settableFuture;
+        } else {
+            return fromListenableFuture(LOG, input, () -> getEgressActionsForInterface(input.getIntfName(),
+                    input.getTunnelKey(), input.getActionKey())).onFailureLogLevel(ERROR).build();
+        }
     }
 
     @Override
     public Future<RpcResult<GetTunnelTypeOutput>> getTunnelType(GetTunnelTypeInput input) {
-        //TODO
-        return null;
+        String tunnelName = input.getIntfName();
+        if (tunnelName == null) {
+            return Futures.immediateFuture(RpcResultBuilder.<GetTunnelTypeOutput>failed()
+                    .withError(RpcError.ErrorType.APPLICATION,
+                    "tunnel name not set for getTunnelType call").build());
+        }
+
+        if (!dpnTepStateCache.isInternal(tunnelName) || !interfaceManager.isItmDirectTunnelsEnabled()) {
+            org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406
+                    .GetTunnelTypeInputBuilder inputBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight
+                    .genius.interfacemanager.rpcs.rev160406.GetTunnelTypeInputBuilder()
+                    .setIntfName(input.getIntfName());
+            SettableFuture<RpcResult<GetTunnelTypeOutput>> settableFuture = SettableFuture.create();
+            Futures.addCallback(interfaceManagerService.getTunnelType(inputBuilder.build()),
+                    new FutureCallback<org.opendaylight.yang.gen.v1.urn.opendaylight.genius
+                            .interfacemanager.rpcs.rev160406.GetTunnelTypeOutput>() {
+                        public void onSuccess(@Nonnull org.opendaylight.yang.gen.v1.urn.opendaylight.genius
+                                .interfacemanager.rpcs.rev160406.GetTunnelTypeOutput result) {
+                            GetTunnelTypeOutputBuilder output = new GetTunnelTypeOutputBuilder()
+                                    .setTunnelType(result.getTunnelType());
+                            settableFuture.set(RpcResultBuilder.<GetTunnelTypeOutput>success()
+                                    .withResult(output.build()).build());
+                        }
+
+                        public void onFailure(Throwable throwable) {
+                            LOG.debug("RPC Call to Get tunnel type failed for interface {}", tunnelName);
+                            String errMsg = String.format("RPC to Get tunnel type failed for interface %s",
+                                    tunnelName);
+                            settableFuture.set(RpcResultBuilder.<GetTunnelTypeOutput>failed()
+                                    .withError(RpcError.ErrorType.APPLICATION, errMsg, throwable).build());
+                        }
+                });
+            return settableFuture;
+        } else {
+            LOG.debug("get tunnel type from ITM for interface name {}", input.getIntfName());
+            return FutureRpcResults.fromBuilder(LOG, input, () -> {
+                DpnTepInterfaceInfo ifInfo = dpnTepStateCache.getTunnelFromCache(input.getIntfName());
+                return new GetTunnelTypeOutputBuilder().setTunnelType(ifInfo.getTunnelType());
+            }).build();
+        }
     }
 
     @Override
@@ -334,7 +440,7 @@ public class ItmManagerRpcService implements ItmRpcService {
             resultBld = RpcResultBuilder.success();
             resultBld.withResult(output.build());
         } else {
-            resultBld = RpcResultBuilder.failed();
+            resultBld = failed();
         }
 
         return Futures.immediateFuture(resultBld.build());
@@ -426,7 +532,7 @@ public class ItmManagerRpcService implements ItmRpcService {
     @Override
     public Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
             GetInternalOrExternalInterfaceNameInput input) {
-        RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = RpcResultBuilder.failed();
+        RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = failed();
         BigInteger srcDpn = input.getSourceDpid() ;
         IpAddress dstIp = input.getDestinationIp() ;
         InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(ExternalTunnelList.class)
@@ -835,7 +941,7 @@ public class ItmManagerRpcService implements ItmRpcService {
     @Override
     public Future<RpcResult<GetDpnEndpointIpsOutput>> getDpnEndpointIps(GetDpnEndpointIpsInput input) {
         BigInteger srcDpn = input.getSourceDpid() ;
-        RpcResultBuilder<GetDpnEndpointIpsOutput> resultBld = RpcResultBuilder.failed();
+        RpcResultBuilder<GetDpnEndpointIpsOutput> resultBld = failed();
         InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
                 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class,
                         new DPNTEPsInfoKey(srcDpn)).build();
@@ -952,4 +1058,46 @@ public class ItmManagerRpcService implements ItmRpcService {
                 .firstKeyOf(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021
                         .network.topology.topology.Node.class).getNodeId().getValue();
     }
+
+    private ListenableFuture<GetEgressActionsForTunnelOutput> getEgressActionsForInterface(String interfaceName,
+           long tunnelKey, Integer actionKey) throws ReadFailedException {
+        int actionKeyStart = actionKey == null ? 0 : actionKey;
+        DpnTepInterfaceInfo interfaceInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
+        if (interfaceInfo == null) {
+            throw new IllegalStateException("Interface information not present in config DS for" + interfaceName);
+        }
+        Optional<StateTunnelList> ifState = tunnelStateCache
+                .get(tunnelStateCache.getStateTunnelListIdentifier(interfaceName));
+        if (ifState.isPresent()) {
+            String tunnelType = ItmUtils.convertTunnelTypetoString(interfaceInfo.getTunnelType());
+            List<Action> actions = getEgressActionInfosForInterface(tunnelType, ifState.get().getPortNumber(),
+                    tunnelKey, actionKeyStart).stream().map(ActionInfo::buildAction).collect(Collectors.toList());
+            return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder().setAction(actions).build());
+        }
+        throw new IllegalStateException("Interface information not present in oper DS for" + interfaceName);
+    }
+
+    private static List<ActionInfo> getEgressActionInfosForInterface(String tunnelType, String portNo, Long tunnelKey,
+                                                                     int actionKeyStart) {
+        List<ActionInfo> result = new ArrayList<>();
+        switch (tunnelType) {
+            case ITMConstants.TUNNEL_TYPE_GRE:
+            case ITMConstants.TUNNEL_TYPE_MPLSoGRE:
+                // Invoke IFM RPC and pass it on to the caller.
+                LOG.warn("Interface Type {} not handled by ITM", tunnelType);
+                break;
+            case ITMConstants.TUNNEL_TYPE_VXLAN:
+                //TODO tunnel_id to encode GRE key, once it is supported
+                // Until then, tunnel_id should be "cleaned", otherwise it stores the value coming from a VXLAN tunnel
+                result.add(new ActionSetFieldTunnelId(actionKeyStart++,
+                        BigInteger.valueOf(tunnelKey != null ? tunnelKey : 0L)));
+                result.add(new ActionOutput(actionKeyStart, new Uri(portNo)));
+                break;
+
+            default:
+                LOG.warn("Interface Type {} not handled yet", tunnelType);
+                break;
+        }
+        return result;
+    }
 }
index 988abc9c8945306a92b96425d2494869f0117e4c..0b34e14a7d7354079edbb20b25a06228e0b3eb9a 100644 (file)
@@ -25,6 +25,9 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
     <reference id="iInterfaceManager"
                interface="org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager" />
 
+    <reference id="interfaceManagerService"
+               interface="org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService" />
+
     <reference id="diagStatusService"
                interface="org.opendaylight.infrautils.diagstatus.DiagStatusService" />
 
index 82cdc54f47533396735f23e04e587cccf1c9f011..f4b6b879c0686d5dc594f779068f9d67df6eddad 100644 (file)
@@ -27,7 +27,11 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService;
 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
+import org.opendaylight.genius.itm.cache.DpnTepStateCache;
+import org.opendaylight.genius.itm.cache.TunnelStateCache;
 import org.opendaylight.genius.itm.globals.ITMConstants;
 import org.opendaylight.genius.itm.rpc.ItmManagerRpcService;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
@@ -174,6 +178,8 @@ public class ItmManagerRpcServiceTest {
     @Mock WriteTransaction mockWriteTx;
     @Mock IMdsalApiManager mdsalApiManager;
     @Mock ItmConfig itmConfig;
+    @Mock IInterfaceManager interfaceManager;
+    @Mock InterfaceManagerService interfaceManagerService;
 
     ItmManagerRpcService itmManagerRpcService ;
 
@@ -204,8 +210,16 @@ public class ItmManagerRpcServiceTest {
         doReturn(Futures.immediateCheckedFuture(transportZonesOptional)).when(mockReadTx).read(LogicalDatastoreType
                 .CONFIGURATION,transportZonesIdentifier);
 
+        DPNTEPsInfoCache dpntePsInfoCache =
+                new DPNTEPsInfoCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl()));
+        DpnTepStateCache dpnTepStateCache =
+                new DpnTepStateCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl()),
+                        dpntePsInfoCache);
+        TunnelStateCache tunnelStateCache =
+                new TunnelStateCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl()));
+
         itmManagerRpcService = new ItmManagerRpcService(dataBroker, mdsalApiManager, itmConfig,
-                new DPNTEPsInfoCache(dataBroker, new GuavaCacheProvider(new CacheManagersRegistryImpl())));
+                dpntePsInfoCache, interfaceManager, dpnTepStateCache, tunnelStateCache, interfaceManagerService);
     }
 
     @After
index d77dfb82d8ede88b435e4f8cf541e9b8e30c29ef..055b91491e536dd5c4feecf0791bf0049dc3c03d 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.genius.idmanager.IdManager;
 import org.opendaylight.genius.interfacemanager.InterfacemgrProvider;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService;
+import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerRpcService;
 import org.opendaylight.genius.interfacemanager.rpcservice.InterfaceManagerServiceImpl;
 import org.opendaylight.genius.itm.globals.ITMConstants;
 import org.opendaylight.genius.itm.impl.ItmProvider;
@@ -37,6 +38,7 @@ import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
 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.config.rev160406.IfmConfigBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfigBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
@@ -80,6 +82,7 @@ public class ItmTestModule extends AbstractGuiceJsr250Module {
         bind(DataBroker.class).toInstance(dataBroker);
         bind(DataBroker.class).annotatedWith(OsgiService.class).toInstance(dataBroker);
         bind(InterfaceManagerService.class).to(InterfaceManagerServiceImpl.class);
+        bind(OdlInterfaceRpcService.class).to(InterfaceManagerRpcService.class);
         bind(IInterfaceManager.class).to(InterfacemgrProvider.class);
         bind(ServiceRecoveryRegistry.class).toInstance(mock(ServiceRecoveryRegistry.class));