How to use same message header id in queue? - activemq

I want to use the Message Header ID generated in Queue 1 to Queue 2.
Can you please tell me how to achieve this in ActiveMQ?
Scenario:
Queue 1 message was not processed by ESB bus due to some failure
We will be using Queue 2 to post the message again after fixing it with
the same Message Header ID created in Queue 1
Queue 1 (Process):
Message Header ID : ID:XYZ-1234-1555664319032-4:2:1:1:1
Queue 2 (Re-process):
Message Header ID : ID:XYZ-1234-1555664319032-4:2:1:1:1
Many Thanks,
Samuel

ActiveMQ itself assigns the message IDs. It's not something which can be done from a client application. You'll need to use a different message header or property for your application-specific ID.

Related

How to set routing key for producer and consumer successfully

I'm building a SpringCloud Stream based application and exchange type is topic and message is sent to 2 queue consumer groups from the topic exchange. The scenario is something like this:
Service A in my application wants to send message of type appointments to service B and service C via an exchange named as: appointments-request based on different use case scenarios such as book, cancel, update etc.
So messages with a key appointments.book.B or appointments.cancel.B should go to consumer queue group appointments.B
messages with a key appointments.book.C or appointments.cancel.C should go to consumer queue group appointments.C
How to achieve this successfully?
Configuration of Producer Service:
spring.cloud.stream.bindings.output.destination=appointments-request
spring.cloud.stream.bindings.input.destination=appointments-reply
spring.cloud.stream.rabbit.bindings.output.producer.exchangeType=topic
spring.cloud.stream.rabbit.bindings.output.producer.routingKeyExpression=
appointments.#.#
Configuration of Consumer Service B:
spring.cloud.stream.rabbit.bindings.input.consumer.exchangeType=direct
spring.cloud.stream.rabbit.bindings.input.consumer.group=
appointments.docmgmt
spring.cloud.stream.rabbit.bindings.input.consumer.bindingRoutingKey=
appointments.docmgmt
spring.cloud.stream.rabbit.bindings.input.consumer.routingKeyExpression=
appointments.#.docmgmt
Producer Service A has the below method to set routing key
public boolean send(AppointmentEvent appointmentEvent)
{
logger.info("Sending event {} ",appointmentEvent);
return this.source.output().
send(MessageBuilder.withPayload(appointmentEvent).
setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER,
"appointments.book.docmgmt").build());
}
My communication between services is not working.
appointments.#.#
You can't use wildcards on the producer side.
You need something like
spring.cloud.stream.rabbit.bindings.output.producer.routingKeyExpression=headers['routingKey']
And then the producer sets the routingKey header to the desired value for each message.
You shouldn't really use the Simp headers; that is for STOMP; use your own header.

How to set message priority for embedded activeMQ using spring JmsTemplate?

I am following this guide- https://spring.io/guides/gs/messaging-jms/
I have few messages with higher priority that needs to be sent before any other message.
I have already tried following -
jmsTemplate.execute(new ProducerCallBack(){
public Object doInJms(Session session,MessageProducer producer){
Message hello1 =session.createTextMessage("Hello1");
producer.send(hello1, DeliveryMode.PERSISTENT,0,0); // <- low priority
Message hello2 =session.createTextMessage("Hello2");
producer.send(hello1, DeliveryMode.PERSISTENT,9,0);// <- high priority
}
})
But the messages are sent in order as they are in the code.What I am missing here?
Thank you.
There are a number of factors that can influence the arrival order of messages when using priority. The first question would be did you enable priority support and the second would be is there a consumer online at the time you sent the message.
There are many good resources for information on using prioritized messages with ActiveMQ, here is one. Keep in mind that if there is an active consumer online when you sent those messages then the broker is just going to dispatch them as they arrive since and the consumer will of course process them in that order.

ActiveMQ Durable Subscriber with jmsMessageId

I'm new to ActiveMQ and trying to find anything that explicitly outlines how JMSMessageID behaves with durable subscribers and selectors, however, I am struggling to find much.
As an example: JMSType = 'car' AND color = 'blue' AND weight > 2500 as a selector. Each subscriber will only receive messages from the topic where the criteria match. When each receives said messages are the JSMMessageID unique for each subscriber or are they unique for the entire topic before it was filtered by the selector for the subscriber.
If not is there a way that I can get the JSMessageID to be unique for each subscriber so that it can be used as a form of sequence number using custom messageID layout: 1, 2, 3... ad infinitum.
The Message ID is set by the producer at the time of send, the broker passes along a copy of the message to each Topic subscription (durable or not) with the message ID that it was sent with. You cannot alter the ID the broker uses that value to track the message and ensure that it is preserved until each subscription that it was dispatched to or stored for has acknowledged it.

How to make rabbitmq to refuses messages when a queue is full?

I have a http server which receives some messages and must reply 200 when a message is successfully stored in a queue and 500 is the message is not added to the queue.
I would like rabbitmq to refuse my messages when the queue reach a size limit.
How can I do it?
actually you can't configure RabbitMq is such a way. but you may programatically check queue size like:
`DeclareOk queueOkStatus = channel.queueDeclare(queueOutputName, true, false, false, null);
if(queueOkStatus.getMessageCount()==0){//your logic here}`
but be careful, because this method returns number of non-acked messages in queue.
If you want to be aware of this , you can check Q count before inserting. It sends request on the same channel. Asserting Q returns messageCount which is Number of 'Ready' Messages. Note : This does not include the messages in unAcknowledged state.
If you do not wish to be aware of the Q length, then as specified in 1st comment of the question:
x-max-length :
How many (ready) messages a queue can contain before it starts to drop them from its head.
(Sets the "x-max-length" argument.)

JMS message priority not working on Message

I need to set message priority so that High priority messages are consumed before Low priority messages by Receivers.
First I tried with message.setJMSPriority() method to set the priority but it was not working in HornetQ and ActiveMQ so finally I set the priority of the Message Producer using setPriority() method and it works fine now.
Why isn't Messsge.setJMSPriority() working in any of the JMS vendor implementations and why do we need to set the priority of the Producer not the message itself to set the priority of the message? What is the use of Messsge.setJMSPriority() method then?
Any suggestion or comment is appreciated.
To answer this question all you need to do is read the API docs for the setJMSPriority method and it tells you why. Here's the relevant text.
Sets the priority level for this message.
JMS providers set this field when a message is sent. This method can be used to change the value for a message that has been received.
The JMS Provider (ActiveMQ, HornetMQ, etc) set the priority in the producer on send to either the default value of 4, or to whatever value you've set the producer to use, so setting the value before send on the message itself won't have any effect.
The following will not work:
msg.setJMSPriority(9); // Not working!
In this code, the message priority is set to 9, indicating this is a high-priority message.
However, when the message is sent, the message will have a priority of 4 (normal
priority). The reason? Like the message expiration, the JMS provider will look at the
message priority property on the sender, or on the send(..) invocation, and then invoke the setJMSPriority on the message method prior
to placing the message on the queue. Since the default message priority is 4 (normal
priority), the message priority will not be set to a high priority message, as the developer had originally intended.
Like the message expiration, there are two ways of setting the message priority: you
can invoke the setPriority() method on the MessageProducer (QueueSender or Topic
Publisher) or set the message priority when sending the message:
//set the default message priority for all messages to 9 (high)
QueueSender qSender = qSession.createSender(requestQ);
qSender.setPriority(9);
qSender.send(msg1);
//this message is low priority
qSender.send(msg2, DeliveryMode.PERSISTENT, 1, 30000);
In this example, msg1 will be sent with a priority of 9 (high priority), whereas msg2 will
be sent with a priority of 1 (low priority).
This is a JMS Specification requirement.
You should change the priority on the Message Producer.
You can read JmsTemplate http://static.springsource.org/spring/docs/3.0.6.RELEASE/spring-framework-reference/html/jms.html
Some JMS providers allow the setting of default QOS values administratively through the configuration of the ConnectionFactory.
Check isExplicitQosEnabled property.