How to read JMS messages without consuming them - using ActiveMQ - jms

I would like to know if there is any way to read a jms and actibemq messages without consuming it ?? I know messages can be consumed from the queue , yet still I want ask this question .!!

You can browse Messages on a Queue via the JMS QueueBrowser, or in ActiveMQ you can browse the contents over JMX or with the commands line tools:
ActiveMQ console tools
JMS QueueBrowser API
ActiveMQ JMX

Rather than using Message-consumers you need to use the QueueBrowser class for doing this:
ConnectionFactory connectionFactory =
new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
Connection connection =
connectionFactory.createConnection("admin","admin");
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("Test");
QueueBrowser queueBrowser = session.createBrowser(queue);
Enumeration msgs = queueBrowser.getEnumeration();
while (msgs.hasMoreElements()) {
//do your things here
}

Another option is to "consume" the messages but just in a transaction, then when you're done, roll it back, but a browser might be better since that's "what it's for" as it were.
If you're just looking for a particular message, and manual will do, you can see (I think all, at least some of) the messages and their contents for an activemq by clicking on the "RSS feed" button in the UI. which basically dumps them all to the screen. The "atom feed" option seems to load faster than the "RSS" one FWIW.

Related

Get a Copy of MQ Message without impacting current producer and consumer

Is there a way to read the MQ message without impacting the current producer and consumer?
We have a consumer already to read from a MQ, but we want to feed the same messages in the MQ to some other places. Is there way to do that without touching the MQ producer nor the existing consumer?
I searched around and found there's something called queue browse. Can I set up another consumer for this MQ and only do browsing? Will both the old and new consumer be able to get all messages?
The producer is not owned by us, so can't change the configuration of it.
So the best option is to not touch producer + consumer; But if no other choice, we can try modify a bit of the existing consumer.
Are there any ways? Thanks a lot!

Retroactive Consumers in ActiveMQ JMS API

I'm investigating ActiveMQ to see if it will work for a project. The current use case I need to demonstrate is that late-joining subscribers will receive topics published prior to the creation of the subscription. It seemed that ActiveMQ Retroactive Consumers would satisfy this need, but I can't get the code to work.
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("[url]");
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createTopic("testAddress?consumer.retroactive=true");
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("Hello, World!");
producer.send(message);
Thread.sleep(5000);
session.createConsumer(destination).setMessageListener(message2 -> processMessage(message2));
session.close();
connection.close();
connectionFactory.close();
All I'm trying to demonstrate here is that a topic can be published, and then some arbitrary amount of time later (eg. 5 seconds) a consumer can subscribe to the topic and receive the previous message.
As far as I can tell, the issue seems to be that creating the topic creates an address but doesn't create any associated queues. If I send a topic to the address before the queue is made (either in code or manually via the web interface to the broker), the message seems to be ignored and the "un routed message count" is immediately incremented.
The ActiveMQ documentation ( https://activemq.apache.org/retroactive-consumer ) doesn't provide any greater detail on how to set up a retroactive consumer than appending "?consumer.retroactive=true" when making the topic, so I wonder if there are some other configuration aspects I'm missing.
To my knowledge ActiveMQ Artemis doesn't support the retroactive consumer feature that 5.x does. The client side option just tells the broker you want it, but since Artemis doesn't handle that you won't see any difference from sending it. The feature itself in 5.x shouldn't be relied upon as a 100% stand in for a durable consumer, broker restart for instance will cause all those messages (of which the amount stored is finite) to be lost.
If you want to guarantee that you get messages sent when the topic consumer is offline then a durable consumer is the safe way to do this
To accomplish the desired behavior (a subscriber receives topics that were published before the subscription was made) in ActiveMQ Artemis, I used a Last Value Queue with non-destructive reads. This has the limitation that I'm only receiving only the most recent copy of a topic published, but that will work for my situation.

Checkpointing position of a Consumer Group in Azure Event Hubs with AMQP

I am developing some code to process events off of an Azure Event Hub using AMQP with the Apache Qpid library. One of the things I'm noticing is that when my application restarts, all messages are re-read from the consumer group / partition.
My assumption is that my consumer is not checkpointing as it should (based on https://learn.microsoft.com/en-us/azure/event-hubs/event-hubs-features#event-consumers), but I am not sure what I options would need to be set on the JMS consumer to do this.
My current connection code (prior to attaching message listeners) looks something like this:
final ConnectionFactory factory = new JmsConnectionFactory(uri);
final Connection connection = factory.createConnection();
connection.start();
final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Is there something I need to do in terms of URL options to cause checkpointing to occur?
The short answer to this question is that AMQP has no notion of checkpointing built in and, by extension, neither does JMS. The result of this is that every time an application that reads via AMQP starts up, it will begin reading from the beginning of the event stream and reprocess everything.
If the application is developed properly (because an intentional rewind is quite possible), this shouldn't cause a functional problem, but it does have the potential to be very wasteful of resources. In the end I settled on using Microsoft's Event Hub client for Java, which has checkpointing support built in.
I sketched this out in some sample code on my github page, comparing https://github.com/michaeljmcd/eventhub-qpid-example and https://github.com/michaeljmcd/eventhub-client-example

Implementing IBM.XMS in dot net windows service

I am developing a windows service which will read the messages from MQ using IBM.XMS listeners.
I need to read only messages which are older than 120 seconds. I have successfully created a listener which is reading all the messages coming into the queue but I am not able to put a filter on the listener.
Below is my code which is reading all the messages
ISession sess = connection.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
IDestination readqueue = sess.CreateQueue("XYZ");
IMessageConsumer consumer = sess.CreateConsumer(readqueue);
MessageListener list = new MessageListener(OnMessage);
consumer.MessageListener = list;
connection.Start();
This code is reading all messages, which I do not want.
I think a same question was asked on IBM developerWorks forum also.
I am not sure what your business logic is but I would suggest you explore the option of sender of the messages setting message expiry to value you want, 2 minutes in this case. When message expiry is set, any message not consumed before the expiry will not be delivered to application. So you don't need another application to clear the messages older than 120 seconds.

Automatically clear messages from queue in IBM MQ

I was wondering if there is a way for you to configure a queue to automatically clear messages? We are striving to partially implement a component of our architecture and want to be able to send to the queue, but have the queue automatically remove the messages that are being sent so that we don't have to run scripts, etc to perform the clean-up.
So far the only thing I have been able to find is to run CLEAR QLOCAL or set the messages to expire from the publishing application.
For you use case there are a few options in IBM MQ:
Create a QALIAS that points to a TOPIC object which has a topic string with no subscribers, messages put to the QA will just disappear.
Have the sending application set message expiry.
Use the IBM MQ CAPEXPRY feature to administratively force message expiry at the queue level.
Run a script to issue CLEAR QLOCAL against the queue. There can not be open handles on the queue for this to work.
Programmatically issue the equivalent PCF command to CLEAR QLOCAL against the queue. There cannot be open handles on the queue for this to work.
Run the IBM MQ dmpmqmsg utility against the queue to read and discard the messages.

Resources