My Program Working in Synchronous way...I stored my msg using rabbitTemplate.convertAndSend(queueName, (messageRequestXml));
In consumer ( Message receiver) it receives msg and processing it...
but till that time I am not getting response. Once I stored msg in queue..I need to send response to user without waiting for listener action.
Please help on this.
you may use DefaultConsumer, which is asynchronous consumer and will process newly added message immediately
Related
I am subscribed to a Azure servicebus topic made by an external department. The way I want the code to work is as follows:
Trigger an http endpoint that starts processorClient and listens to the topic.
Fetches one message
Does required actions to that message
Closes processorClient connection.
Repeat
I am using the ServiceBusProcessorClient class as shown in the following documentation Receive messages from a subscription
Is there a way to utilize this code in order to only fetch one message from the topic at a time before calling the processorClient.close();
I have tried using setting maxConcurrentCalls and setting prefetchCount(0).
Our system has configured to consume and send reply to the same queue, i.e., JMSDestination and JMSReplyTo are the same. I cannot change that right now.
In my integration test, if I set replyToSameDestinationAllowed=true, Camel continues to consume the reply I sent to the queue, i.e., it "captures" the source and never stop and enters a loop.
But, if I don't set it, Camel refuses to send the reply to the queue, saying this:
JMSDestination and JMSReplyTo is the same, will skip sending a reply message to itself
That causes problem for my integration test. I want to consume the message in a separate method and assert against it.
How can I stop Camel from capturing this queue, i.e., consuming only once and ignore the rest?
At the end of my route I call stop() to send reply automatically.
When receiving the second message(the reply), I see this line:
2023-01-10 14:37:22,186 DEBUG [org.apa.cam.com.jms.EndpointMessageListener]-{Camel (camel-1) thread #19 - JmsConsumer[my.queue]}-Received Message has JMSCorrelationID [ID:hostname-1673354133272-4:1:1:10:1]
Can I use this to ignore the reply? Should I stop the route? Rollback? Or what should I do?
At last I filtered out messages based on the presence of JMSCorrelationID header.
from("activemq:xxx")
.filter(simple("${header.JMSCorrelationID} == null")) // ignore reply
.to("direct:main");
Even that I don't set it in my client side code, seems that Camel will use message id to set JMSCorrelationID when sending reply if the incoming message hasn't it. If incoming message already has JMSCorrelationID, Camel will not change it, and will copy that value to the reply.(I guess that if you manually set JMSCorrelationID in client side, Camel will stop setting it for you).
So basically, message without JMSCorrelationID means it's new message which hasn't passed through my client application. I think only client side should set it, especially in my case where original message and replies are put into the same queue, where client needs a mean to filter out replies.
Also, I find that receiving can specify a message collector stating the field you want to filter. For example:
QueueReceiver receiver = jmsSession.createReceiver(myQueue, "JMSCorrelationID='" + correlationId + "'");
This is useful when you know the correlationId. But in my case (#QuarkusIntegrationTest which is a black box test), this cannot be used.
But after doing that, in my integration test Camel still "captures" the consuming and will not let another method to consume the message properly(the other method never receives anything) when I run the whole test class(with other test cases); when running individually, this test case passes. So at last I disabled the test case.
Seems that after filtering out the message, Camel behaves exactly same as if I called .stop(), executing the callback (sending reply); and will send the original message to reply queue, in my case, the original queue, so it's looping and never let go. Even I enable duplicate check, it still captures.
At the very last, we separate the queues so even capturing is happening, it does not matter any more.
I have a method that sends a message to a SQS Standard queue. The method returns a successful response upon execution. But the console does not show any messages in the queue. Any ideas on what could be the reason this is happening?? Can provide a code snippet if that is helpful. Thanks!
Visibility timeout has been set to 10 minutes.
I have a problem concerning receiving messages (I use #ManagedService). I use the same connection to send and receive messages between browser and my Java program. I can see that all the messages pass through ManagedAtmosphereHandler.message(AtmosphereResource resource, Object o) method.
If it is an incoming message, Atmosphere iterates through all methods marked #Message. Then it tries to find a decoder and eventually invokes correct method.
For outgoing messages, Atmosphere retrieves invoked method. It does so by getting localAttribute named "ManagedAtmosphereHandler" (name of current class). It is present only for outgoing messages. Then the message is encoded and send to browser.
The problem is, sometimes invokedMethod is set for incoming messages. It results in treating my incoming messages as outgoing. Does anybody know why it happens? My outgoing messages are scheduled and I suppose that's the reason why it happens, but I'm not sure. When are these localAttributes set and what are they for?
I updated Atmosphere 2.3.0-RC6 to 2.3.0 and it works like a charm now.
What would be a nice and good way to temporarily disable a message listener? The problem I want to solve is:
A JMS message is received by a message listener
I get an error when trying to process the message.
I wait for my system to get ready again to be able to process the message.
Until my system is ready, I don't want any more messages, so...
...I want to disable the message listener.
My system is ready for processing again.
The failed message gets processed, and the JMS message gets acknowledged.
Enable the message listener again.
Right now, I'm using Sun App Server. I disabled the message listener by setting it to null in the MessageConsumer, and enabled it again using setMessageListener(myOldMessageListener), but after this I don't get any more messages.
How about if you don't return from the onMessage() listener method until your system is ready to process messages again? That'll prevent JMS from delivering another message on that consumer.
That's the async equivalent of not calling receive() in a synchronous case.
There's no multi-threading for a given JMS session, so the pipeline of messages is held up until the onMessage() method returns.
I'm not familiar with the implications of dynamically calling setMessageListener(). The javadoc says there's undefined behavior if called "when messages are being consumed by an existing listener or sync consumer". If you're calling from within onMessage(), it sounds like you're hitting that undefined case.
There are start/stop methods at the Connection level, if that's not too coarse-grained for you.
Problem solved by a workaround replacing the message listener by a receive() loop, but I'm still interested in how to disable a message listener and enable it shortly again.
That looks to me like the messages are being delivered but nothing is happening with them because you have no listener attached. It's been a while since I've done anything with JMS but don't you want to have the message sent to the dead letter queue or something while you fix the system, and then move the messages back onto the original queue once you're ready for processing again?
On WebLogic you can set up max retries, an error queue to handle messages that exceed the max retry limit, and other parameters. I'm not certain off the top of my head, but you also might be able to specify a wait period. All this is available to you in the admin console. I'd look at the admin for the JMS provider you've got and see if it can do something similar.
In JBoss the following code will do the trick:
MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
ObjectName objName = new ObjectName("jboss.j2ee:ear=MessageGateway.ear,jar=MessageGateway-EJB.jar,name=MessageSenderMDB,service=EJB3");
JMSContainerInvokerMBean invoker = (JMSContainerInvokerMBean) MBeanProxy.get(JMSContainerInvokerMBean.class, objName, mbeanServer);
invoker.stop(); //Stop MDB
invoker.start(); //Start MDB
I think you can call
messageConsumer.setMessageListener(null);
inside your MessageListener implementation and schedule the reestablishment task (for example in ScheduledExecutorService). This task should call
connection.stop();
messageConsumer.setMessageListener(YOUR_NEW_LISTENER);
connection.start();
and it will be working. start() and stop() methods are used for restarting delivery structrues (not TCP connection).
Read the Javadoc https://docs.oracle.com/javaee/7/api/javax/jms/Connection.html#stop--
Temporarily stops a connection's delivery of incoming messages. Delivery can be restarted using the connection's start method. When the connection is stopped, delivery to all the connection's message consumers is inhibited: synchronous receives block, and messages are not delivered to message listeners.
For temporarily stops a connection's delivery of incoming messages you need to use stop() method from Connection interface: https://docs.oracle.com/javaee/7/api/javax/jms/Connection.html#stop--
Just don't call connection.stop() from MessageListener because according to JMS spec. you will get deadlock or exception. Instead you can call connection.stop() from different thread, you just need to synchronize MessageListener and thread that going to suspend connection with function connection.stop()