Spring Integration Dynamic Selector for JMS messages - jms

Spring Integration Dynamic Selector for JMS messages
I have a requirement to use dynamic selectors to retrieve messages from the queue. For example i need to get messages from the queue at regular intervals that are > then 1 hr old. It seems the message selector is initialized just once . Can it be changed everytime the poller is used? and how?

With the polled adapter, you can use a Smart Poller to change the selector expression before each poll; call setMessageSelector() on the JmsDestinationPollingSource.
You cannot dynamically change the selector on a message-driven adapter; you have to stop the adapter first.

Related

Apache Camel JMS/AMQP component create destination queue only if required

I am currently working on an Integration application that uses Camel with Spring Boot. There is a camel route in integration application that receive messages from source Artemis broker that is transformed and sent to another Artemis broker.
The camel route looks like this:
from(sourceQueue).process(transformProcessor).to(destinationQueue)
When the camel route starts, it recreates the queue names mentioned in the from and to and the previous messages are lost. We do not expect this to happen.
One way I found to do this is in the Artemis ActiveMQ broker.xml, disable the queue and topic auto creation and create the queue(s) using Artemis API.
My question is, can we configure camel JMS / AMQP component to create the queue only if it is not present and if present use the existing ones?
By default Camel will use DynamicDestinationResolver. You can create your own custom DestinationResolver and plug it in your endpoint (or into your component)
.to("jms:queue:myQueue?destinationResolver=MyCustomDestinationResolver");
You can also use JndiDestinationResolver, which by default does not fallback into creating a dynamic destination.
I don't know Artemis but it sounds weird for a broker to delete a queue with its messages. At least its "brother" ActiveMQ has by default the behavior you expect: queues are automatically created if they do not exist, but they just stay if they already exist.
Are you sure the queues are recreated on route start? Are these queues persistent? Could it be that a consumer just drains the queue? I also found a queue attribute of Artemis named auto-delete-queues that would delete the queue if it was drained by a consumer.
auto-delete-queues Whether or not to the broker should automatically delete auto-created JMS queues when they have both 0 consumers and 0 messages.

Spring integration dsl with multiple listeners on same queue but with different selectors

I am trying to get multiple listeners configured on same queue, but with different message selector. I am using Solace JMS provider.
The behavior is that the first loaded listener will have its selector registered and is receiving the messages.
the second listener is NOT receiving the message. And using Spring integration DSL 1.1.3
what could be wrong?
I tried with two different Queue connection factory, but could not get it working.
How can we have two Selective consumers configured ?
I think you should start from your vendor first of all and try to figure out if it supports concurrent selective consumers.
Although you have to bear in mind that with the Queue only one consumer accepts message anyway. So, if first one is able to process the message, the second one won't receive it, even with different selector.
Consider to switch to the Topic.

WSO2 ESB Proxy - JMS Message Selector

We have WSO2 ESB listening on to a single ActiveMQ Queue. However we want to configure multiple proxies on listening on to the JMS queue.. however we want the proxy to only consume message meant for it.
Is there a mechanism to set JMS Message selector on the ESB Proxy so that it consumes only message designated for it. ?
Thanks
Rajiv Patil
AFAIK it is not possible to perform such a selection. However there are two possible approaches to achieve the above.
Let each proxy read all the messages and select which to process inside the proxy itself
Use an EIP pattern to achieve the above. One possible pattern would be Message Routing where you can select the messages and direct the message to the desired sequence or proxy which will do the processing.
Yes, you can have multiple proxy services listening to the same queue, each following a certain JMS MessageSelector. You will have to set the transport.jms.MessageSelector parameter for each proxy like this (value 100 is variable, each proxy service containing a different number):
<parameter name="transport.jms.MessageSelector">account='100'</parameter>
And the Java message producer sending the message to the JMS broker is setting the message selector with:
// this will set a key/value pair as JMS message selector
// 100 should be a variable in your case
message.setStringProperty("account", "100");
This was tested on ActiveMQ 4.7 and WSO2 ESB 4+.

Websphere equivalent for Weblogic bridge level message filter

In weblogic it is possible to create a message bridge between two JMS message queues. While configuring this bridge, a message filter can be applied so that the bridge will route messages that match the filter only.
Is it possible to achieve the same with Websphere?
Specifically I'm trying to achieve this scenario.
I have one source queue on which messages are received. Each message will have a custom JMS property set up. I would like to forward the messages on the source queue, to separate queues based on the JMS property and its value. This is easily configured in WLS using message bridges with filtering. How can I do the same in WAS?
Thanks
Savio
You need to use SIB Mediation.
The WAS info center have an example called writing a routing mediation which seems like what you need.
At the bottom of the example there is a link to what to do next which also explains how to configure WAS to use that mediation.
Without writing custom code (as per your comment on Aviram's answer), it is not possible to achieve the exact same thing, but nonetheless it is possible to achieve same effect;
You say that a 'source queue' distributes messages to other 'separate queues' according to a custom JMS property. I'm assume that you have MDBs (message driven beans) configured to process messages in these separate queues.
What you can do with WebSphere is distribute messages to these MDBs directly from the 'source queue', without having to filter/distribute them to separate queues.
This is managed by using JMS Message Selectors. You can point all your MDBs to the source queue using activation specification definitions, and for each (one for each type of message) MDB, define a JMS Message Selector that matches the ones you use in WLS. This way each message is only delivered the MDB whose filter matches the message's properties. This effectively filters/distributes messages to different MDB's as in WLS.
You may read details on configuring message selectors (during development in RAD, or at/after deploy time) at infocenter. Below is a quote to give you an idea about what it look like;
messageSelector
This attribute determines the JMS message selector
that is used to select which messages the message-driven bean
receives. For example:
JMSType='car' AND color='blue' AND weight>2500
The selector string can refer to fields in the JMS message header and
fields in the message properties. Message selectors cannot reference
message body values.
For the record, we finally ended up writing our own routing algorithm within the application to ensure that messages are sent to separate queues for each client. This way we are independent of app server implementations and the integration effort is the same across app servers, viz., adding custom queues per integrating client.
In brief, We published a JMS custom property that must be set. Using a published convention, we look up for a queue and send responses to the queue. If the property is not set, a default queue is created to route all messages. If the property is set, and the queue cannot be found an exception is raised and processing halted.
This suited our purpose. Hope it helps...

ActiveMQ / JMS Message Handler Test

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)

Resources