Search code examples
spring-integrationspring-integration-dslspring-integration-httpspring-integration-ws

Spring Integration: replying messages with gateways


I have this Spring Integration code that receives a SOAP message and then replies it.

This is the configuration:

  @Bean
  public MessageChannel wsGatewayInboundChannel() {
    return MessageChannels.direct(GATEWAY_INBOUND_CHANNEL_NAME).get();
  }

  @Bean
  public MessageChannel wsGatewayOutboundChannel() {
    return MessageChannels.direct(GATEWAY_OUTBOUND_CHANNEL_NAME).get();
  }

  @Bean
  public IntegrationFlow soapMessageFlow(SimpleWebServiceInboundGateway webServiceInboundGateway) {
    return IntegrationFlows.from(webServiceInboundGateway)
            .log(LoggingHandler.Level.INFO)
            .channel(SOAP_MESSAGE_SERVICE_CHANNEL_NAME).get();
  }

  @Bean
  public SimpleWebServiceInboundGateway webServiceInboundGateway() {
    SimpleWebServiceInboundGateway simpleWebServiceInboundGateway = new SimpleWebServiceInboundGateway();
    simpleWebServiceInboundGateway.setRequestChannel(wsGatewayInboundChannel());
    simpleWebServiceInboundGateway.setReplyChannel(wsGatewayOutboundChannel());
    simpleWebServiceInboundGateway.setExtractPayload(false);
    simpleWebServiceInboundGateway.setLoggingEnabled(true);
    return simpleWebServiceInboundGateway;
  }

And this is the service that processes the message:

@Service
public class SoapMessageService {

  @ServiceActivator(inputChannel = SOAP_MESSAGE_SERVICE_CHANNEL_NAME, outputChannel = GATEWAY_OUTBOUND_CHANNEL_NAME)
  public SoapMessage receive(SoapMessage request) {
    //...
    return reply;
  }
}

This works fine.

I don't know how the reply channel works behind the curtains, but I want to be really sure that replies don't mix up. For instance, if I receive:

Request_1 from A, which reply is Reply_1
Request_2 from B, which reply is Reply_2

I want Reply_1 to be delivered to A and Reply_2 to be delivered to B and NOT Reply_1 being delivered to B and Reply_2 being delivered to A.

Can reply channel guarantee the behaviour previously described?

Thanks in advance.


Solution

  • They do guarantee. The gateway implementation in Spring Integration us fully based on the Return Address EI pattern: https://www.enterpriseintegrationpatterns.com/patterns/messaging/ReturnAddress.html.

    Every gateway request is set with a replyChannel header to the TemporaryReplyChannel. When no outputChannel configured downstream, the framework consults that header to deliver the current message.

    In most cases we really don't need that setReplyChannel to be configured on the inbound gateway. Just because we simply can rely on the replyChannel header.

    See more info in docs: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints.html#gateway-default-reply-channel

    And also this GH issue: https://github.com/spring-projects/spring-integration/issues/3985

    There see if it would make sense for your to get rid off that GATEWAY_OUTBOUND_CHANNEL_NAME at all everywhere.