The Setup
I have a JMS messaging application that has messages inbound from multiple JMS destinations. The message payloads are varying JSON representations with some common headers. I am relying on Spring's dynamic Jackson type conversion at the ServiceActivators
to convert into the actual POJOs. At present the routing is trivial because the channels are essentially "datatype" channels split out by the JSON payload type (they are all JSON String payloads but the JSON represents very different object types).
The Problem
I would like to apply global validation logic to all inbound messages across several pattern matched channels e.g. "*input*"
and divert invalid messages to a validation error channel for review. Regardless of whether the message is valid or invalid, the local JMS transaction should be committed; if the message is invalid, I don't want the invalid message to be resent later.
Potential Options Considered
Channel Interceptor
My initial thought was to implement a ChannelInterceptor
that matches all the channels where this logic should be applied, but it does not appear that the capability to divert a message can be implemented in a ChannelInterceptor
. It appears that my two options with the ChannelInterceptor
are:
- Have the JMS transaction rolled back when the interceptor returns null on
preSend
, OR - the invalid message is still sent along to the original destination.
Neither of these are the desired behavior. The JMS local transaction should always be committed (provided no other error) and the message either sent to the original destination, or diverted to the invalid message channel.
Router
A Router
might be a good choice, but it doesn't appear that there is a way to apply a router to a pattern matched set of channels, so I believe I would have to apply it to each channel individually. That kind of duplication is something that I am hoping to avoid.
AspectJ Pointcut
Another option I've thought of is to break out AspectJ and implement @Around
advice on the AbstractMessageSendingTemplate.convertAndSend(destination, payload, postProcessor)
method. This seems intrusive, but appears as if it may work. If there is an option better supported directly by the framework I would be happy to hear it.
Common Input Channel w/ Payload Routing
If I can't find a way to globally apply this type of routing logic, then another option may be to route all inbound JMS messages through a single channel. A custom Router
could be applied to that inbound channel that uses payload type headers to direct messages to their proper "datatype" channels and routes invalid messages to the validation error channel.
The Question(s)
- Is there a way to apply this type of message diversion to a pattern matched set of channels?
- Have I missed an important capability of the Spring Integration framework that will make one of my considerations work?
- If not, are there better EIP options than what I've mentioned?
Many Thanks!