mardi 2 février 2021

Using TestChannelBinderConfiguration but two handlers get registered

I have a Spring Cloud Stream application that processes (credit card) events -- some of which are processed synchronously and some asynchronously. I came up with roughly the following in Kotlin:

spring-cloud-starter-stream-rabbit = 3.1.0

@Service
class CardEventProcessor(
    private val streamBridge: StreamBridge,
) : Consumer<AsyncCardEvent> {

    fun process(cardEvent: SyncCardEvent): Result { return businessLogic() }

    fun processAsynchronously(cardEvent: AsyncCardEvent) {
        streamBridge.send("cardEventProcessor-out-0", cardEvent)
    }

    override fun accept(cardEvent: AsyncCardEvent) { businessLogic() }
}

and have configured it like so:

  rabbitmq: ...
  cloud:
    stream:
      bindings:
        cardEventProcessor-in-0:
          destination: cardevents
          group: CardEventProcessor
        cardEventProcessor-out-0:
          destination: cardevents

It all seems to work fine, except in integration tests the processing fails after the second async card event. I was able to debug / reduce the issue down to two handlers being registered in UnicastingDispatcher, which has a round robin strategy: one for TestChannelBinder and another for OutputDestination$lamdba.

This is what my integration test class looks like:

@SpringBootTest
@Transactional
@AutoConfigureMockMvc
@AutoConfigureEmbeddedDatabase
@Import(TestChannelBinderConfiguration::class)
class IntegrationTests {

    @Test
    fun `Use case one`() {
        sendFirstAsyncRequest()  // processed correctly in CardEventProcessor.accept()
        sendSecondAsyncRequest() // message never arrives in CardEventProcessor.accept()
    }
}

I was following the Testing section in Spring cloud stream docs and can't figure out what I'm missing to get this working. The example there is a Function<> not a Consumer<> and I produce within the same @Service class as the consumer (because the queue is just an implementation detail to solve async, not the typical use case of queues between micro-services) but as far as I understand that should work, and does in fact work when not running as integration test.

I saw Disable Spring Cloud Stream Rabbit for tests but didn't want to depend on the deprecated spring-cloud-stream-test-support and the other two suggestions didn't work either. Any ideas?

Aucun commentaire:

Enregistrer un commentaire