Межсервисная связь - внедрение службы B в serviceAImpl не компилируется (без посредника сообщений, пытающегося выполнить удаленный вызов) - PullRequest
0 голосов
/ 21 января 2019

Я новичок в Lagom и использую его со Scala.Для меня это прекрасный опыт создания микросервиса с его использованием до сих пор.

Как я уже говорил, https://www.lagomframework.com/documentation/1.4.x/scala/ServiceClients.html#Binding-a-service-client, и я пытаюсь вызвать межсервисный сервис с брокером сообщений через удаленные вызовы.Это означает, что я хотел внедрить ServiceB в serviceAImpl и выполнить вызов invoke на клиенте. Это для одного из сценариев, где я не хочу, чтобы вызов происходил через Event или брокер сообщений и должен был быть прямым вызовом service to service.

В Lagom scala у меня есть ServiceA и ServiceB.Я создал клиента ServiceB в ServiceAApplication и пытаюсь внедрить serviceB в ServiceAImpl.Я получаю сообщение об ошибке во время компиляции: «Не удается найти значение типа: [com.example.ServiceB] переопределить 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] переопределить lazy val lagomServer = serverForServiceA

Примечание:Когда я выполняю загрузчик приложений следующим образом, я не получаю сообщение об ошибке, но, как вы увидите ниже, я не определяю компонент и, следовательно, теряю тестируемость:

У меня нет черты для th 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.

фрагмент unittest:

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 и вызвать его с помощью метода invoke?(без подписчика) 2. Как проверить это как интеграцию службы A и службы B?

1 Ответ

0 голосов
/ 29 января 2019

Я получил ответ по следующей ссылке

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

Я изменил определение компонента, как упомянуто в приведенной выше ссылке, и это решило проблему.

...