Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

JmsOutboundGateway correlation strategy #8555

Unanswered
robertgosz asked this question in Q&A
Feb 17, 2023 · 2 comments · 4 replies
Discussion options

Hello,
This time I have some questions about correlation logic. I'm using SpringIntegration 5.5.15 and JmsOudboundGateway.
The default strategy is to use final gatewayCorrelation (UUID) concatenated with incrementing message number "_X".

  1. Is there any reason behind this approach instead of generating new UUID for each message ?
  2. Can this behaviour be changed/customized somehow, so that for example Base64 representation of UUID could be used ? (or any other approach that would fit inside 24 bytes).

I'm asking because for native IBM MQ provider the correlationID header is 24 bytes long.
If it's longer - it's being truncated by MQ specific solutions (Oracle Service Bus for example) and replies are not being matched.
This forces the use of custom JMS header for correlation and requires custom handling of those.

Best Regards
Robert

You must be logged in to vote

Replies: 2 comments · 4 replies

Comment options

This correlation is used then in the selector for replies:

String messageSelector = this.correlationKey + " LIKE '" + this.gatewayCorrelation + "%'";
container.setMessageSelector(messageSelector);

Therefore it is really a single prefix for all the messages emitted by this gateway with that incrementor for uniqueness.

We may consider to expose that gatewayCorrelation as a setter, so you can change.
But how that may guarantee that eventually with a counter it won't exceed expected 24 bytes again?

You can use a custom property for this correlation algorithm though:


	/**
	 * Provide the name of a JMS property that should hold a generated UUID that
	 * the receiver of the JMS Message would expect to represent the CorrelationID.
	 * When waiting for the reply Message, a MessageSelector will be configured
	 * to match this property name and the UUID value that was sent in the request.
	 * <p>If this value is NULL (the default) then the reply consumer's MessageSelector
	 * will be expecting the JMSCorrelationID to equal the Message ID of the request.
	 * <p>If you want to store the outbound correlation UUID value in the actual
	 * JMSCorrelationID property, then set this value to "JMSCorrelationID".
	 * <p>If you want to use and existing "JMSCorrelationID" from the inbound message
	 * (mapped from 'jms_correlationId'),
	 * you can set this property to "JMSCorrelationID*" with the trailing asterisk.
	 * If the message has a correlation id, it will be used, otherwise a new one will
	 * be set in the 'JMSCorrelationID' header. However, understand that the
	 * gateway has no means to ensure uniqueness and unexpected side effects can
	 * occur if the correlation id is not unique.
	 * <p>This setting is not allowed if a reply listener is used.
	 * @param correlationKey The correlation key.
	 */
	public void setCorrelationKey(String correlationKey) {

This way the logic will remain the same, but it won't be set to the standard JMSCorrelationID.
Although I guess it may cause some other problem that the server side must do exactly opposite to deal with your custom key to correlate properly...

You must be logged in to vote
0 replies
Comment options

Hi Artem.
Thanks for your response. I actually already use the custom correlation key as a workaround for those native apps.
Unfortunately I got new requirement to stop using it and only use the MQ 24 byte one.
That put's me in a very uncomfortable position, therefore I have asked the question.

Best Regards
Robert

You must be logged in to vote
4 replies
@artembilan
Comment options

OK. So, tell us, please, if exposing a gatewayCorrelation as a property on the JmsOutboundGateway would fix your problem?
Then we can convert this discussion into an issue.
The Base64 might still not help though, since we would continue to use that AtomicLong for each request message.
We do use the final value as this.replies.put(correlation, replyQueue); to correlate reply back to the request then.
Another way could be to fully override this value from end-user callback, e.g. SpEL expression against request message, but then we would not be able to use a messageSelector JMS feature...

@robertgosz
Comment options

Hmm. That does not sound good. Exposing gatewayCorrelation wont be enough as there will still be the concatenated integer _XXX. Having a possibility to provide a custom ID trough a message header or some expression as you say would be great, but if either of those would break the message selector, then it's also not a way to go. I'm wondering why using a custom correlation value would break it though, considering the value still being unique ?

@artembilan
Comment options

Right, but with user-provided custom ID, we cannot use a selector at all, just because we cannot have some common LIKE expression.
Probably it is not so bad since we would still have the correlation via custom property, but we might have a side-effect to consume messages by the container which don't belong to us.
I guess that is a main reason behind that selector.

@robertgosz
Comment options

I see. Looks like there is no such thing as one solution that fits all purposes. Thanks very much for your time Artem.
And thanks to you and the whole Spring team for doing such a great job with all this awesome stuff!

Best Regards
Robert

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.