服务间通信-将服务B注入serviceAImpl失败(没有消息代理尝试远程调用)

时间:2019-01-21 07:10:22

标签: lagom

我是Lagom的初学者,并与Scala结合使用。到目前为止,使用它创建微服务对我来说都是很棒的经历。

我提到了以下内容 https://www.lagomframework.com/documentation/1.4.x/scala/ServiceClients.html#Binding-a-service-client 并且我正在尝试通过远程调用与不带消息代理的服务间进行调用。这意味着我想将ServiceB注入serviceAImpl并在客户端上进行调用调用。这是针对其中一种情况,即我不希望通过事件或消息代理进行调用,并且应该将其作为服务调用的直接服务。 / p>

在Lagom scala中,我有ServiceA和ServiceB。我已经在ServiceAApplication中创建了ServiceB客户端,并尝试将ServiceB注入ServiceAImpl。在编译过程中出现以下错误, 找不到以下类型的值:[com.example.ServiceB] 覆盖惰性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] 覆盖惰性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中的方式进行操作,而是使用ServiceAApplication来启动服务器,而不是使用Component来启动服务器,因此测试失败,表明服务B不是运行。该如何处理。

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

1 个答案:

答案 0 :(得分:0)

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

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

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