How to get a specific message body from a queue using a unique ID
I want to know the best way to get the message Body of a specific message instance in a queue.
The method I use is the following:
My software is calling the SEMP API to get a list of messages metadata like this:
{{solace-admin-url}}/SEMP/v2/monitor/msgVpns/my-vpn-name/queues/myqueuename/msgs
and the json response looks like:
{
"collections": [
{},
{}
],
"data": [
{
"attachmentSize": 44324,
"contentSize": 0,
"dmqEligible": true,
"msgId": 1422343,
"msgVpnName": "my-vpn-name",
"publisherId": 107,
"queueName": "my-article",
"redeliveryCount": 0,
"replicationGroupMsgId": "rmid1:1cc48-55f51da1eea-00000000-08d7537f",
"replicationState": "not-replicated",
"spooledTime": 1694422243,
"undelivered": true
},
{
"attachmentSize": 33293,
"contentSize": 0,
"dmqEligible": true,
"msgId": 1422344,
"msgVpnName": "my-vpn-name",
"publisherId": 670,
"queueName": "my-article",
"redeliveryCount": 0,
"replicationGroupMsgId": "rmid1:1cc48-55f51da1eea-00000000-08d753c8",
"replicationState": "not-replicated",
"spooledTime": 1694422291,
"undelivered": true
}
],
"links": [
{
"uri": "https://my-host.company.com:943/SEMP/v2/monitor/msgVpns/my-vpn-name/queues/my-article/msgs/1422343"
},
{
"uri": "https://my-host.company.com:943/SEMP/v2/monitor/msgVpns/my-vpn-name/queues/my-article/msgs/1422344"
}
],
"meta": {
"count": 2,
"request": {
"method": "GET",
"uri": "https://my-host.company.com:943/SEMP/v2/monitor/msgVpns/my-vpn-name/queues/my-article/msgs"
},
"responseCode": 200
}
}
If I follow the uri's in links
section, they are not showing the message body and I assume this is not possible to get it with SEPMV2 API.
Then, what I want to do is to browse the queue using one of the Messaging API (Java or JCSMP or JMS) by providing the MessageId to a selector -> this is because I did not find a better way to do it
-> if that way exist, let me know.
I arrive to the same issue as in this post: https://solace.community/discussion/798/selector-on-browser-how-to-do
It seems the selector on the JMS header is not always possible as the JMS header seems not filled by the broker but by the client (which seems weird as other brokers like ActiveMQ does that out of the box).
On the the same idea, I noticed the method: bytesXMLMessage.getMessageId()
is deprecated and documentation says the MessageId should not be used for retriving messages:
https://docs.solace.com/API-Developer-Online-Ref-Documentation/java/com/solacesystems/jcsmp/XMLMessage.html#getMessageId--
However the alternative to call method ackMessage
seems unrelevant when we want to browse the queue and not consuming the messages and with this ackMessage I do not see how I can get the message Body.
Can you please advice?
Answers
-
There are a number of issues to unpack here.
- SEMP/management interfaces do not provide access to message bodies. This is a security thing because those messages are governed by Client Usernames/ACLs/Profiles whereas management access is not. Management users are separate from messaging users.
- The right way to do what you are looking for, viewing the payload of a message but not consume it, is to use a queue browser interface in the client API of choice. This is what you have suggested, but I think you are saying you would use the browser to view the message after getting the message ID from SEMP. I am suggesting the list of messages is done in the queue browser. Then you get the message you want and "drill down" on it using the selector.
- Don't use message id - there is a message property called:
ReplicationGroupMessageId
which can be used for a unique message id across a broker cluster. Use this in your selector.
There is also some more info in the above link.
1 -
Thanks for your answer. For point 1, I totally agree and that why I started to use the Messaging API.
For point 2, it does not matter if I use SEMP or messaging API as the replicationGroupId is the same whichever api I use.
For point 3, I cannot uses that field for selector.
Here is my code:
final String filterSelectorExpression = String.format("ReplicationGroupMessageId = '%s'", replicationGroupMessageId); MessagingService messagingService = createMessagingService(clientUser, clientPass); final MessageQueueBrowser queueBrowser = messagingService .createMessageQueueBrowserBuilder() .withMessageSelector(filterSelectorExpression) .withQueueBrowserWindowSize(1) .build(Queue.durableExclusiveQueue(queueToBrowse)).start(); final InboundMessage message = queueBrowser.receiveMessage(1000); if (message != null) { return message.dump(); } else { throw new ResourceNotFoundException("message with replication-id: " + replicationGroupMessageId + " not found."); }
(I also tried with JMS and JCSMP API's without success)
I tried to select on different field name variations (ReplicationGroupMessageId, ReplicationGroupMessageID, ReplicationGroupMsgId and ReplicationGroupMsgID) but none are working.
The format of the value is:
rmid1:28abf-b43c2f526f6-00000000-0000039a
and I also tried "28abf-b43c2f526f6-00000000-0000039a" but still not working.
Can you please confirm this is correct or what is wrong with my code.
Note that without selector the code is working well.
0 -
hi @amackenzie
I asked the Solace support team and they told me this field (
ReplicationGroupMessageId
) is not usable for a selector.I also have found in this post:
that the SpoolTime is available only from SEMPv2 but no timestamp available in the messaging API's (unless the sender explicitly set it).
For all these reasons I am thinking to use SEMPv2 for displaying message metadata and only Messaging API's for getting the content or searching with selector (all in browse mode).
0