Search code examples
spring-integrationspring-integration-dsl

Way to get messages from previous flows in a linear chain


I recently had a scenario like below:

Flow_A ------>  Flow_B ------>  Flow_C ------>  Flow_D

Where

  • Flow_A is the initiator and should pass messageA.
  • Flow_B should pass messageA+messageB.
  • Flow_C should pass messageA+messageB+messageC
  • Flow_D should pass messageA+messageB+messageC+messageD.

So, I was thinking to enhance the headers with an old message and again pass to another flow. But, it will be very bulky at the end.

Should I store the message somewhere and then pass the messageId in the header, so that the next flow can get the old message with the messageId?

What should be the best way to achieve this?


Solution

  • See Claim Check pattern: https://docs.spring.io/spring-integration/docs/current/reference/html/message-transformation.html#claim-check

    1. You store a message using ClaimCheckInTransformer and get its id as an output payload.
    2. You move this id into a header and produce the next message.
    3. Repeat #1 and #2 steps for this second message to be ready for the third one.
    4. And so on to prepare environment for the fourth message.

    To restore those messages you need to repeat the procedure opposite direction. Get a header from the message into a payload, remove it and call ClaimCheckOutTransformer to restore a stored message. I say "remove header" to let the stack to be restored properly: the ClaimCheckOutTransformer has a logic like this:

    AbstractIntegrationMessageBuilder<?> responseBuilder = getMessageBuilderFactory().fromMessage(retrievedMessage);
        // headers on the 'current' message take precedence
        responseBuilder.copyHeaders(message.getHeaders());
    

    So, without removing that header, the same message id is going to be carried into the next step and you will be is a loop - StackOverflowError.

    Another is to store messages manually somewhere, e.g. MetadataStore and collect their ids in the list for payload. This way you don't need extra logic to deal with headers. Everything in a list of your payload. You can consult the store any time for any id item in that list!