Я новичок в 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?