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

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.

Related

JMS message processing with spring integration in cloud environment

I'm currently trying to refactor the processing of JMS messages to work in a distributed/cloud environment. To allow a better retry and error handling the messages are first stored to the database with a JPA entity and then read by spring integration jpa inbound adapter. This works fine as long as just a single instance of my service is running. However when multiple instances are running, the instances try to process the same message even after introducing a processing state on the persisted messages.
I have already tried to save the JMS messages in a JDBC message store, however then I would have to define a group identifier according to which an instance could select a message which is not really possible since the number of instances is dynamic and I can not assign a group id for each instance. Another possibility could be some kind of distributed lock with a LockRegistry but I couldn't make that work.
Do you have any hint/advice how I could implement the following requirements the best with spring integration:
JMS message should be persisted
Any instance can pick up the message and process it
If the processing fails there will be a retry for x times (could also be retried by another instance)
If an instance crashes or gets killed during the processing the message must not be lost
Is there maybe some spring-cloud component which could be helpful?
I'm happy about every hint in which direction I should go.

Pattern for handeling multiple message types with spring JMS in a multi module maven setup

I' m currently investigation the implementation of queue's or topic, based on activeMQ within our project. The setup is pretty straight forward in which we are using maven modules to seprate business logic according to the business domain. One common module allows us to assemble common logic.
simplified Example:
common module
products module
clients module
One of the requirements is that certain operations are asynchronous towards a backend (by means of a activeMQ) which in turn responds with a result message.
The second requirement is that it should be possible to horizontally scale the application by creating a new deployable artifact with only that module that needs more juice.
We are using spring 4 with of course jms and activeMQ.
On to my question. We would like to use just one queue or topic for backend connectivity. Which would mean our common module would handle jms configuration (jms factory, jms-configuration) and different types of messages will be send over that one queue/topic.
How would can I make sure that product related messages get handled by the "products" module and client related messages get handled by the "clients" module? How can I make sure only one of the "products" modules logic would handle a message if the module was deployed two times? What approach would you recommend or is this one queue/topic "nuts"?
I was myself thinking in the direction of using a topic because of the publ/subsc pattern... , or maybe queue listener acting as publisher in a observer pattern to which product- or client subscribers might subscribe to take over handling the message?
Thanks for your help.
Why using a Topic if you want just one of the "products" modules to handle one message? With Topic you'd have one message - multiple subscribers each getting the message. The Queue ensures only one consumer gets a message (point-to-point), with Topic you'd have one message dispatched to all subscribers.
Regarding the "filtering" of messages, this should be something provider specific. Looking at ActiveMQ docs I see this. So, basically each consumer should get the messages the broker, based on selector, will dispatch. I don't know the specifics, but this would be the first place I would start this investigation.
On the same idea, have a look at this discussion from the Spring forum. It is, indeed, related to Spring Integration, but it's on the same idea of message selection. On the other hand, you could consider adopting Spring Integration in your project: it's kind of an abstraction of integration patterns and fits well with everything message oriented.
Few interesting ideas from that forum post:
JmsTemplate from Spring contains a doReceive method that takes as a parameter a String as message selector
Message selectors are in the JMS spec (scroll down to "Message Properties" section)
Relevant section in the Spring Integration documentation is here

Can I tell camel jms endpoint to share jms connections between routes?

I have a app server that runs multiple camel routes that are reading messages from a JMS Queue, each route runs with different selectors.
We have an app server for each group of clients. So at the end there are multiple connections created to the queue. And that seems to be affecting the read and write performance on the queue.
I tried to use a connection pool, (by the way i am using WMQ), the closest I got is to use spring's CachingConnectionFactory (as described in this post how to configure (spring) JMS connection Pool for WMQ).
I was hoping that the number of connections will reduce from each app server, but that did not happen. Even though i set the size to 5 on the CCFactory, i see 10 connections created to the queue. According to the documentation on CCFactory, explicit closing of the connections is required. Is it possible or does it even make sense to close the connection that is used by a camel route that is reading from a queue? Or is there a way to tell camel routes to share the connections? I thought the use of connection pool and factory will do that, but i don't see that from happening.
Can I achieve what I want to achieve?
Thanks in advance.
what you can do is have only one route reading from the queue instead of many, and then use some camel conditional logic to redirect the message to the correct processing route via direct endpoints, see also this example.
This way there would only one consumer for the queue, instead of multiple consumers each running it's own selector.

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 single consumer multiple producers

Can anybody point out a reference on how to implement
a single consumer multiple producer in activemq? Or could give a very simple implementation.
This will be very helpful.
Thanks
Matt Raible's AppFuse project is a good skeleton project which is implemented using different libraries. You can pick the one which uses Spring and introduce ActiveMQ as Bharati Raja has explained in his blog post jms with appfuse1x.
There is no special implementation required for this. This is the core business of MessageBrokers. The only thing you need to make sure of:
If you decide to give an ID to your producers, make sure they are different from each other.. You cannot have multiple producers with the same ID. Same goes for consumers.
If you need to guarantee that a message can be consumed by only one consumer, then this is the point-to-point communication model which can be implemented using a JMS Queue in ActiveMQ.
Many producers can send messages to the same queue. Only one active consumer will receive a message from the queue.

Resources