¿Cómo se puede configurar @MessagingGateway con Spring Cloud Stream MessageChannels?

He desarrollado servicios asincrónicos de Spring Cloud Stream, y estoy tratando de desarrollar un servicio perimetral que use @MessagingGateway para proporcionar acceso sincrónico a servicios que son asíncronos por naturaleza.

Actualmente estoy obteniendo el siguiente seguimiento de pila:

Caused by: org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:355)
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:271)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:188)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
... 47 common frames omitted

Mi @MessagingGateway:

@EnableBinding(AccountChannels.class)
@MessagingGateway

public interface AccountService {
  @Gateway(requestChannel = AccountChannels.CREATE_ACCOUNT_REQUEST,replyChannel = AccountChannels.ACCOUNT_CREATED, replyTimeout = 60000, requestTimeout = 60000)
  Account createAccount(@Payload Account account, @Header("Authorization") String authorization);
}

Si consumo el mensaje en el canal de respuesta a través de @StreamListener, funciona bien:

  @HystrixCommand(commandKey = "acounts-edge:accountCreated", fallbackMethod = "accountCreatedFallback", commandProperties = {@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE")}, ignoreExceptions = {ClientException.class})
  @StreamListener(AccountChannels.ACCOUNT_CREATED)
  public void accountCreated(Account account, @Header(name = "spanTraceId", required = false) String traceId) {
    try {
      if (log.isInfoEnabled()) {
        log.info(new StringBuilder("Account created: ").append(objectMapper.writeValueAsString(account)).toString());
      }
    } catch (JsonProcessingException e) {
      log.error(e.getMessage(), e);
    }
  }

En el lado del productor, estoy configurandorequiredGroups para garantizar que múltiples consumidores puedan procesar el mensaje y, en consecuencia, los consumidores tienen coincidenciasgroup configuraciones.

Consumidor:

spring:
  cloud:
    stream:
      bindings:
        create-account-request:
          binder: rabbit1
          contentType: application/json
          destination: create-account-request
          requiredGroups: accounts-service-create-account-request
        account-created:
          binder: rabbit1
          contentType: application/json
          destination: account-created
          group: accounts-edge-account-created

Productor:

spring:
  cloud:
    stream:
      bindings:
        create-account-request:
          binder: rabbit1
          contentType: application/json
          destination: create-account-request
          group: accounts-service-create-account-request
        account-created:
          binder: rabbit1
          contentType: application/json
          destination: account-created
          requiredGroups: accounts-edge-account-created

El bit de código en el lado del productor que procesa la solicitud y envía la respuesta:

  accountChannels.accountCreated().send(MessageBuilder.withPayload(accountService.createAccount(account)).build());

Puedo depurar y ver que la solicitud se recibe y procesa, pero cuando la respuesta se envía al canal de respuesta, es cuando ocurre el error.

Para que funcione @MessagingGateway, ¿qué configuraciones y / o código me estoy perdiendo? Sé que estoy combinando Spring Integration y Spring Cloud Gateway, por lo que no estoy seguro de si usarlos juntos está causando los problemas.

Respuestas a la pregunta(3)

Su respuesta a la pregunta