This is not totally on JMS Queue handler test. So, continue reading.
We have an architecture where spring channel listens to a queue from ActiveMQ. The listener of this queue will receive messages and has a static list of sub-listeners (identified by unique subjects). All the messages will have some parameters including the subject to which this message has to be delivered.
SMSService will drop its messages to the activemq with a subject SEND_SMS. It will be listened either by some HTTP Service or SMPP Service. You can even design your own Listener and wire that as a spring component with the required "subject".
Problem:
There is a better chance that this internal subject might change. This doesn't even throw an explicit Runtime Exception when there are no listeners. Is there a way to test this message being actually received by the intended listener?
`
As tim Bish siad, your problem statement is much too vague.
Have you tried to create your own ActivemMQ interceptor (I do not know if it could be usefull for your problem)
Related
We implemented a filter, or plugin, in ActiveMq broker that intercepts inbound messages and validates them from a security standpoint.
We are needing a programmer friendly way of receiving these exceptions on the producer side (ideally not at connection level, but at session or producer level, since they may need session specific reaction).
We are doing message level authorization in the broker side in the following way: In the ActiveMq provider (server) we implement BrokerFilter (plugin) in order to intercept the incoming JMS message, and validate a JWT access token attached to the message as property. If the JWT token is valid, then the message is let through downstream chain, if it is not valid, a SecurityException is thrown.
We notice that the message does reach back to the sending JVM which reports that no ExceptionListener instances registered for the specific exception.
Our question is, where can we best register an ExceptionListener in Spring JMS for this scenario? We have direct access to the producer and JMS session, but not to the JMS connection.
It is true that registering an ExceptionListener to the connection would be useful for connection level events, but for session level events it may make the code more understandable and cohesive if we could register such exception listeners locally to the session or producer, since they are kind of direct responses to a message send attempt.
Of course it would be also possible to implement local exception listeners via connection level and a thread local structure of local listeners, but i am wondering if JMS or Spring already provides such possibility of the session or producer finding out directly that their message was not authorized, so that they answer upstream to calling microservice rather then retyrying to send it for instance.
We are using persistent messages but unsure if we do synchronous or asynchronous send. I believe on asynchronous send, an ExceptionListener of some kind will be called back on such an event (exception thrown in BrokerFilter.send method). While on the synchronous send perhaps the exception will directly be thrown there (but the thread blocking may decrease robustness of the microservice).
This is solvable with connection.setExceptionListener but to us it would likely be more convenient a session.setExceptionListener or even a message request level listener.
We would like to see any other options possible with Spring JMS except registering an exception listener at connection level and except synchronous send, if any such other options are possible.
Since Spring JMS uses the JMS API then you're pretty much limited to what the JMS API provides and it doesn't provide a session or request level exception listener. It provides a connection level exception listener for exceptions which are reported asynchronously and normal Java checked exceptions for the synchronous use-case.
For a Spring Framework app working with ActiveMQ and with/without WebSocket
The requirement is prior to send any message to a Topic a check should be done about Number Of Consumers, if it returns 1 the message can be sent safely. If it returns 0, the message can't be sent.
The clients could be come from websocket and consider there is no durable subscription. Thus if a message is sent, and there are no clients, the message arrives to the Topic and practically is lost (never consumed) and Messages Enqueued increments +1
I already did a research and I have read the following:
JMSTemplate check if topic exists and get subscriber count
Notify ActiveMQ producer if consumer on the destination is down
ActiveMQ get number of consumers listening to a topic from java
Detect change in Consumers of an ActiveMQ topic
Practically all is based on Advisory Message. I already have read:
Advisory Message
Handling Advisory Messages
Apache ActiveMQ Advisory Example
I understand that if exists a Topic named abc.xyz then ActiveMQ creates ActiveMQ.Advisory.Consumer.Topic.abc.xyz, until here I am ok with this pattern. I can confirm this approach through ActiveMQ Web Console
What is confuse for me is that practically all the examples available from the previous links works around creating a Session and uses mostly the onMessage method. For the latter I know it works how a listener.
Question 01: Thus who is expected to call that ActiveMQ.Advisory.Consumer.Topic.abc.xyz? It to trigger that onMessage method? That is my confusion.
What I need is work with the Spring Framework API (The app is already working and running with a CachingConnectionFactory, thus a Connection can be retrieved and other #Beans about infrastructure about ActiveMQ) and get access to that ActiveMQ.Advisory.Consumer.Topic.abc.xyz destination and retrieve the Number Of Consumers value.
Note: even when exists ActiveMQTopic declared with #Bean and is possible to retrieve that Destination for some #Component, sadly the API does not offer a method such getConsumers().
Question 02: How can be accomplished this?
I am assuming the JMS API for 2.0.x could help perhaps in someway.
I have a simple JMS topic listener that i would like to hook with a spring-integration chain.
Basically, when a JMS message is received in the listener it has to be pushed into the chain's channel. Eventually the message is processed and pushed to an outbound-channel-adapter to be consumed.
The Spring Integration documentation mentions the use of asynchronous gateways but that uses Futures.
Isn't there a simple way to just put the message on a channel?
If there is an example that you can point to it would be great.
Thanks
Regards
Martin
If you want to run the flow on the listener thread, simply use a regular gateway (not an async one); this will allow the message to roll-back if the flow fails for any reason.
If you want to "fire and forget" you can make the request channel from the gateway an ExecutorChannel - see here.
I am developing an application in which I have jms message queue.
There is a producer which enqueue message to the queue and a consumer to dequeue the message.
There might be cases when consumer is not running. If a message is not consumed by the consumer within a certain amount of time I need to catch that from producer.
I want to use JMX to monitor message queue's message whether it is expired.
Any suggestion or sample code how to this.....
It depends on the JMX implementer... Some servers provide JMX implementations to monitor its resources. If its not provided, then you will need to write the JMX implementation that uses the API provided by the MQ implementer.
An easier way to solve this problem is to use the request-response pattern with expiry. The consumer needs to respond in a specified internal of time. If it can't then the message on the queue can expire. If the response is not received the producer can take further action. JMS selector with correlation ID can be used to relate the responses with the request.
All,
i am new to JMS and i have a question about Session.rollBack() method in JMS. AFAIK, this method is used to roll back all operations to JMS server (sending/receiving) by the session when using *SESSION_TRANSACTED* acknowledge mode. Now suppose I am calling this method in a catch block of a receiving/processing operation (is reasonable?), to tell JMS server to redeliver the message for processing, But even if it is redelivered the processing still throws the same exception which cause the JMS server to redeliver the message again, so it seems a infinite process. How to handle this problem? or are there any other JMS features that is designed for it? Thanks in advance!
The rollback method in JMS will rollback any message sends and receives in that "transaction". Transaction here is local to the JMS session.
Whether a redelivery will cause a problem really depends on why the exception occurred. If it was due to some transitory issue then a redelivery may work. If you have the kind of problem that is once it occurs will always occur (an example of this would be a JMS TextMessage whose body should contain XML, but doesn't).
The JMS API doesn't provide any solution to this itself. This is typically taken care of by the JMS provider and how it behaves will depend on which one you use. WebSphere MQ for instance will redeliver up to a configurable maximum at which point it will move it off to a queue for bad messages. The Service Integration Bus in WebSphere Application Server has similar behaviour. I suggest you consult your JMS provider documentation to determine exactly how it behaves in this situation.
If you are running in an application server rollback typically doesn't do anything because the application server will be managing transactions for you.