首页 > 解决方案 > 服务间通信 - 将服务 B 注入到 serviceAImpl 编译失败(没有消息代理尝试远程调用)

问题描述

我是 Lagom 的初学者,并在 Scala 中使用它。到目前为止,使用它创建一个微服务对我来说是一次很棒的体验。

正如我提到的以下 https://www.lagomframework.com/documentation/1.4.x/scala/ServiceClients.html#Binding-a-service-client 我正在尝试通过远程调用在没有消息代理的情况下调用服务间. 这意味着我想将 ServiceB 注入到 serviceAImpl 并在客户端上执行调用调用。这是针对我不希望通过事件或消息代理进行调用并且应该是直接服务到服务调用的场景之一。

在 Lagom scala 中,我有 ServiceA 和 ServiceB。我在 ServiceAApplication 中创建了一个 ServiceB 客户端,并尝试在 ServiceAImpl 中注入 serviceB。我在编译过程中收到错误提示,找不到类型的值:[com.example.ServiceB] override lazy val lagomServer = serverForServiceA

在抽象类 ServiceAApplication

ApplicationLoader 类的片段,仅当我将 ServiceB 注入 ServiceAImpl 构造函数时,才会出现此错误。

ServiceAApplicationLoader.scala 的片段:

trait ServiceAComponents extends LagomServerComponents
  with SlickPersistenceComponents
  with LagomConfigComponent
  with HikariCPComponents
  with LagomKafkaComponents
{
  implicit def executionContext: ExecutionContext
  def environment: Environment

  implicit def materializer: Materializer

  override lazy val lagomServer = serverFor[ServiceA](wire[ServiceAImpl])
  lazy val serviceARepository = wire[ServiceARepository]
  lazy val jsonSerializerRegistry = ServiceASerializerRegistry

  persistentEntityRegistry.register(wire[ServiceAEntity])
  readSide.register(wire[ServiceAEventProcessor])

}

abstract class ServiceAApplication(context: LagomApplicationContext) extends LagomApplication(context)
    with ServiceAComponents
    with AhcWSComponents
    with SlickPersistenceComponents
    with LagomServiceClientComponents
  with LagomConfigComponent
    {

  lazy val serviceB = serviceClient.implement[ServiceB]

}

 `class ServiceAApplicationLoader extends LagomApplicationLoader {
  override def load(context: LagomApplicationContext) =
    new ServiceAApplication(context) with LagomServiceLocatorComponents

  override def loadDevMode(context: LagomApplicationContext) =
    new ServiceAApplication(context) with LagomDevModeComponents

  override def describeService = Some(readDescriptor[ServiceA])
}

`

ServiceAImpl.scala 的片段:

    class ServiceAImpl (registry: PersistentEntityRegistry, serviceARepository:ServiceARepository ,serviceB: ServiceB )
                          (implicit ec: ExecutionContext) extends ServiceA {

///   Here in one of the method calling serviceB which is injected in constructor.

编译时出现以下错误:找不到类型的值:[com.example.ServiceB] override lazy val lagomServer = serverForServiceA

注意:当我以下列方式执行应用程序加载器时,我没有收到错误,但正如您将在下面看到的,我没有定义组件,因此失去了可测试性:

我没有像上面那样的 ServiceAComponent 的特征,而是定义如下。

abstract class ServiceAApplication(context: LagomApplicationContext) extends LagomApplication(context)
    with ServiceAComponents
    with AhcWSComponents
    with SlickPersistenceComponents
    with LagomServiceClientComponents
  with LagomConfigComponent
    {

 override lazy val lagomServer = serverFor[ServiceA](wire[ServiceAImpl])
  lazy val serviceARepository = wire[ServiceARepository]
  lazy val jsonSerializerRegistry = ServiceASerializerRegistry

  persistentEntityRegistry.register(wire[ServiceAEntity])
  readSide.register(wire[ServiceAEventProcessor])

  lazy val serviceB = serviceClient.implement[ServiceB]

}

class ServiceAApplicationLoader extends LagomApplicationLoader {
  override def load(context: LagomApplicationContext) =
    new ServiceAApplication(context) with LagomServiceLocatorComponents

  override def loadDevMode(context: LagomApplicationContext) =
    new ServiceAApplication(context) with LagomDevModeComponents

  override def describeService = Some(readDescriptor[ServiceA])
}

此应用程序加载器与 runAll 一起工作正常,但如果我必须使用单元测试运行,因为没有找到组件特征,则无法与 ServiceB 一起运行。

单元测试片段:

class ServiceAImplIntegrationTest extends AsyncWordSpec with Matchers with BeforeAndAfterAll {

  private val server = ServiceTest.startServer(ServiceTest.defaultSetup.withCassandra(true)) { ctx=>
    new ServiceAApplication(ctx) with LocalServiceLocator{
      override def additionalConfiguration: AdditionalConfiguration =
        super.additionalConfiguration ++ ConfigFactory.parseString(
          "cassandra-query-journal.eventual-consistency-delay = 0"
        )

    }
  }

注意:如果您看到测试用例,它并没有按照示例 ItemIntegrationTest 中的方式完成,而是使用 Component 启动服务器,我只使用 ServiceAApplication 启动,因此测试失败,表明服务 B 没有运行。如何处理这个。

问题: 1. 将 serviceB 注入到 ServiceAImpl 中是否正确并使用调用方法调用它?(没有订户) 2.如何测试这个作为 serviceA 和 serviceB 的集成?

标签: lagom

解决方案


我在以下链接中得到了答案

https://discuss.lightbend.com/t/inter-service-communication-with-out-message-broker-unable-to-inject-if-creating-component-extending-lagomservercomponent/3257

我更改了上面链接中提到的组件定义,这解决了这个问题。


推荐阅读