HornetQ message splitter - jms

I'm new to JMS and HornetQ.
I'm wondering if there is a way to implement Message Translator Pattern using HornetQ to split data from a message in a set of smaller data and send them. I explored Bridge and Divert solutions but I can't get how to do it using org.hornetq.core.server.cluster.Transformer and org.hornetq.core.server.ServerMessage. Where can I find some docs about it? Am I looking in the right direction?

In short no(I've no Idea on camel). You cannot modify the jms body once sent until its consumed by a client(body is immutable). However you can change message headers and message properties. The org.hornetq.core.server.cluster.Transformer interface is used for modifying the headers/properties. Hence you are left with two options.
Consume the message, chunk the message based on your algorithem and send to other queues or put back to the queue(but be careful to avoid loop, by having suitable selector).
Other approach is chunk the message then send with message property to differentiate the message. And use the diverter with filter based on the message property(you can use exclusive/non exclusive strategy to send only/send copy of message to the other queue.)

Related

bind destinations dynamically for producers and consumers (Spring)

I'm trying to send and receive messages to channels/topics whose destination names are in a database, so they can be added/modified/deleted at runtime, but I'm surprised I have found little on the web. I'm using Spring Cloud Streams to allow to change the underlying broker.
To send messages to dynamically bound destinations I'm going with BinderAwareChannelResolver.resolveDestination(target).send(message), but I haven't found something that works like it to receive messages.
My questions are:
1. Is there something similar?
2. how can the message be processed periodically as #StreamListener does?
3. And not as important, but can you create a subscriber automatically in case there is none?
Thanks for any help!
This is a bit out of scope of the original design of the framework. But I would further question your architecture. . . If you truly desire to subscribe to unlimited amount of destinations I wonder why? What is the underlying business requirement?
Keep in mind that even if we were to do it somehow that would require creation of a message listener container dynamically for each new destination which would raise more questions, such as, how long would such container have to live since eventually you would run out of resources.
If, however, you simply asking about possibility of mapping multiple destinations to a single channel so all messages go to the same message handler (e.g., StreamListener), then you can simply use input destination property and define multiple destination delimited by comas.

Different message types (XMLs) on one TIBCO queue?

I am trying to implement an application(Java) which will subscribe to different message types (XMLs) from other different applications via TIBCO EMS. Each of these message types will have a specific purpose. I am of the opinion that I should have multiple queues with multiple subscribers in my application, however, the TIBCO guy is adamant that there should be only one queue where all of these messages will be published and I will have one subscriber and the subscriber then should have logic to different tasks based on the XML received.
Which approach is better? One with multiple queues and subscribers OR the one queue and one subscriber? Please let me know reasons for the choice.
Thanks!
-Naveen
In general, if the same application is reading all the messages, it is much cleaner for that application to have a single input queue instead of multiple input queues. With multiple then the application will need to have logic to know which order to process the queues and so on. With one input queue, the messaging system can deal with the order of the messages - whether FIFO or by priority etc, and the application can just read the next message and process it.
Use unique message header for each type of xml while sending the message. And use message selectors / filters while receiving the same, so that it can be routed / delegated to the respective handler based on the header value. This way, you will be able to handle different type of xml messages by single queue as well.

How can I modify messages on a queue, once sent

I need to modify some of the messages that are already present in the queues.
Can it be possible to modify the message and send new modified message on the same queue for processing.
If yes, what would be the best approach for this.
Thanks.
The short answer is no. In JMS messages are immutable once they have been sent. If you find you need to modify messages its recommended that you create a consumer with some selector which matches the messages you wish to update, consume them and send new modified messages, either to another queue or if you are careful, back to the original queue.
ref link Can I modify messages on a queue?
my opinion is if you are consume the message using selector like correlationId,then consume the particular message from queue and again post the new message with same correlationId of previous message.but this will depends up on your requirements.

IBM WebSphere MQ Client - unlimited wait GET vs. correlation GET

I am trying to build with amqmdnet a IBM MQ receiver with 2 functionalities:
ReceiveReply(byte correlationId) – reads REPLY messages for supplied correlation identifiers. Is implemented by a GET with a correlation MATCH.
event EventHandler NewMessage – notifies the subscriber of new REQUEST messages. Is implemented by a GET with unlimited wait in infinite while loop.
The problem is that I cannot limit the second GET to read only REQUEST messages and so the correlation GET is never successful. If I only do one GET I will have to implement correlation on my own.
Anyone tried to implement something similar?
Thanks,
Radu
The simplest option is to use two queues. There are ugly ways of achieving what you are after (imagine all request messages putting something in the correlid so you could get by correlid there too, for example) but in principle you have a request queue and a reply queue - dont share!

ActiveMQ LIFO ordering?

Is there any option to change queue order without using out of box "Resequencer"? Maybe it can be done using JMS client to get last message in queue instead of first?
I think that you should give more info about what you're trying to achieve...
Anyway if you read the specs of some JMS implementation like MQ you'll see that the FIFO order is not guaranteed at 100%.
That means that if you relay on the order of the messages received, you can get easily in trouble.
It's good practice to add a progressive number to the message header and use it to handle the messages as you please. If you adopt this solution you have 2 options to achieve your goal:
1) modify the receiver business logic to check the the header of the message;
2) (probably the cleaner approach if you're using MQ) use something called MESSAGE SELECTOR.
Message Selectors allow content based retrieval of specific messages using SQL92-query functions. MQ spec states:
The JMS message provides a facility to provide user-defined metadata
to the JMS message header (outside the actual body of the message).
JMS programs can take advantage of this facility to select a subset
of messages based on a selection criteria or, in other words, a JMS
client can choose only those messages that it is interested in.
Here some more info about the implementation of the two solutions...
The property that you're probably interested in and that you should set before sending the message is JMSCorrelationID that will be set to 1 for the first message, 2 for the second one and so on.
1) Since you're more interested in the message selector, you can skip to the next bullet. Anyway just for reference, if you decide to adopt the solution 1 you can find some good reference in:
http://activemq.apache.org/maven/apidocs/org/apache/activemq/ActiveMQQueueBrowser.html
2) Message Selector.
Your message selector will be an sql string like: JMSCorrelationID = max(JMSCorrelationID)
If you wanna implement a message selector in java the syntax is:
MessageConsumer consumer = session.createConsumer(destination, messageSelectorString, true);
ActiveMQObjectMessage objMsg = (ActiveMQObjectMessage) consumer.receiveNoWait();

Resources