1
votes

I need to audit every message that pass throught an spring-integration flow, very basic one.

The application reads from an int-redis:queue-inbound-channel-adapter and writes in an int-http:outbound-gateway.

The output gateway has a reply-channel in order to receive the response of the http method, is in this exact moment when I want to register de audit information, including the initial message and http response.

If the http method fails, the message goes to errorHandler and I can obtain the history object with timestamps and payload, what's perfect for audit.

But if the http method works (Code 200,201 ...), I get a message including the ResponseEntity object with the status code, but I've no the initial payload from redis.

So, is there any way to corelate the two messages (before sending http outbound and after http response) in order to get the full info for auditing?

Thanks in advance!

Here the integration flow:

<int:message-history/>

<int:channel id="responseChannel"/>

<int:channel id="responseError"/>

<int:logging-channel-adapter channel="responseChannel" level="INFO" 
   expression="@messageHandlerSpel.handle( #this )" id="logger"/>

<int:logging-channel-adapter channel="responseError"
    level="ERROR" expression="@errorHandlerSpel.handle( #this )"
    id="LogingERROR"/>

<int-redis:queue-inbound-channel-adapter id="inputRedis" connection-factory="redisCF" 
   channel="redisInput" queue="redis-input" serializer="" error-channel="responseError"/>

<int:channel id="redisInput" />

<int-http:outbound-gateway id="HttpOutbound" request-channel="redisInput" 
   url="http://{server}:{port}/{index}/{type}/{id}" 
   http-method="PUT" extract-request-payload="true" charset="UTF-8" 
   reply-channel="responseChannel" request-factory="requestFactory"/>

And the handler class:

@Component
public class MessageHandlerSpel {
    public String handle(Message<byte[]> message) {
        MessageHeaders msgH = message.getHeaders();
        MessageHistory msgHistory = 
            message.getHeaders().get(MessageHistory.HEADER_NAME, MessageHistory.class);
        ... // Do whatever
    return "";
}
1

1 Answers

0
votes

One trick is to store the request payload in the custom header before performing the HTTP request.

After receiving response, the request headers will be merged with that response payload. Therefore in the downstream you will have both: the request in the header, and reply in the payload.

The MessageHistory remains the same and there is no reason to hack there somehow.

Another approach is based on the <aggregator> to correlate request and reply. But this one is for more complex or distributed scenario.

The simple copy/paste to header via:

<header-enricher>
    <header name="requestPayload" expressio="payload"/>
</header-enricher>

should be enough for you.