sharedDeadLetterStrategy is not discarding the DLQ messages - activemq

Am using AMQ 5.5. I would like to disable the option of sending dead letters to ActiveMQ.DLQ destination and completely discard (automatically) the messages that would be sent there otherwise. To do this I had configured the broker as below:
<amq:destinationPolicy>
<amq:policyMap>
<amq:policyEntries>
<amq:policyEntry topic=">" producerFlowControl="false" >
<amq:deadLetterStrategy>
<amq:sharedDeadLetterStrategy processExpired="false" />
</amq:deadLetterStrategy>
</amq:policyEntry>
<amq:policyEntry queue=">" producerFlowControl="false">
<amq:deadLetterStrategy>
<amq:sharedDeadLetterStrategy processExpired="false" />
</amq:deadLetterStrategy>
</amq:policyEntry>
</amq:policyEntries>
</amq:policyMap>
</amq:destinationPolicy>
However, I still see that the messages are getting stored in DLQ. Can you please let me know what could be causing this?
Do I need to fix anything in the config?
Thanks
Hari

The problem faced here was that, the above given configuration would discard only non-persistent expired messages. To discard all expired messages, persistent and non-persistent, use discardingDLQBrokerPlugin.
<amq:plugins>
<amq:discardingDLQBrokerPlugin dropAll="true"/>
</amq:plugins>

Related

Remove message from rabbit MQ after limited attempts of requeing

I put records from a file into rabbit mq,read records from queue and call a service.For rejected records,I am sending a negative acknowledgemnt and requeuing with channel.basicNack method.But requirement is that we need to make only some 3 attempts of service call.After that we have to remove the message from the queue rather keep on calling the service again and again.
On the last attempt, set the requeue argument in basicNack to false.

Spring integration Error handling - How do I access original faulty message's history?

We have a spring-integration application where we would like to deal with the messages on the error channel.At a minimum we would like to extract the history and log it so we can visualise where exactly it failed etc
Here is a brief markup of just this bit
<int:poller id="defaultPoller" default="true" fixed-delay="5000" />
<int:channel id="MyCustomErrorChannel">
<int:queue capacity="10"/>
</int:channel>
<int:header-enricher id="errorMsg.HeaderEnricher"
input-channel="errorChannel"
output-channel="MyCustomErrorChannel">
<int:header name="history" expression="payload.failedMessage.headers" />
</int:header-enricher>
<int:service-activator input-channel="MyCustomErrorChannel" ref="errorLogger" method="logError"/>
<bean id="errorLogger" class="com.dataprep.util.ErrorLogger" />
The idea is to define our custom error channel MyCustomErrorChannel. Any error that ends up in the default errorChannel gets its header's enriched before being put out on MyCustomErrorChannel
Lastly we have a logger that reads the messages from MyCustomErrorChannel and logs the payload which is the underlying exception and also the history.
I notice that the history in my logger is always 3 steps
errorChannel,errorMsg.HeaderEnricher,pbSwiftRouterErrorChannel i.e nothing prior to this message landing on the errorChannel is obtainable in the history.
How do I get hold of the original message's history (i.e the history of the faulty message which somehow landed on the default error channel as a new Error Message)
Could you please take a look at my header enricher and let me know how to access the headers on the failed message and stuff it to the error message?
Is it doable at all ?
To replace existing headers you should use overwrite="true", because the history is built for the ErrorChannel, too.
You should override exactly with history header, not the whole headers. Therefore your expression must be like this:
<int:header name="history"
expression="payload.failedMessage.headers.history"
overwrite="true"/>

Hawtio ActiveMQ queue Browse shows maximum 500 messages

I'm trying to see all the messages in my queue in ActiveMQ(5.11.1). I am using Hawtio(1.4.51) for this purpose. My queue in ActiveMQ contains 790 message.
My Steps till now:
By default hawtio shows up to 400 Messages in ActiveMQ queue. So i went to my broker.xml settings and added:
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue="incoming.status" maxBrowsePageSize="401"/>
</policyEntries>
</policyMap>
</destinationPolicy>
This gave me 401 messages.
So i tried to change the maxBrowsePageSize="401" to "-1". To my surprise i got only 200 messages...
Next try was to set maxBrowsePageSize="1000" and again dissapointement. I could see only 500 messages...
Next i went to my java code and inserted:
PrintWriter writer = new PrintWriter("c:\\Messages.log", "UTF-8");
writer.write(jmsQueueEndpoint.browseAllMessagesAsXml(true));
writer.close();
The results were: for maxBrowsePageSize="401" i got 401/790 messages, for "2" i got 2/790 for "1000" and for "-1" i got 790/790.
So my conclusion was that there is some setting in Hawtio that limits my results to 500.
I need to see ALL my messages in Hawtio.
So after more investigation, and with a help of this blog: HawtIO + Camel plugin - Multiple context not showing up - Limits to max3
I was able to find the setting which will allow ActiveMQ in Hawtion to show more than 500 entries. The setting located here:
In the right side of hawtio application there is your user picture with a small arrow. Press on it and select "Preferences".
In "Preferences" select "Jolokia.
In "Jolokia" edit: "Max collection size" to maximum that you want and press "apply", restart browser.
The only problem left is the unlimited option. When i set "-1" in the broker part, hawtio limits me to 200 entries...

Read messages from DLQ in Jboss 7

I have below two jms queues configured in JBOSS 7.1.
<jms-queue name="APP.QUEUE1">
<entry name="queue/APP.QUEUE1"/>
<entry name="java:jboss/exported/jms/queue/APP.QUEUE1"/>
</jms-queue>
<jms-queue name="APP.QUEUE2">
<entry name="queue/APP.QUEUE2"/>
<entry name="java:jboss/exported/jms/queue/APP.QUEUE2"/>
</jms-queue>
while consuming the message, if some thing goes wrong then the message will go to Dead letter Queue that is configured as follows.
<address-setting match="jms.queue.APP#">
<dead-letter-address>jms.queue.DLQ</dead-letter-address>
<expiry-address>jms.queue.ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<max-delivery-attempts>5</max-delivery-attempts>
<max-size-bytes>10485760</max-size-bytes>
<address-full-policy>BLOCK</address-full-policy>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
</address-setting>
so I have successfully delivered the message to DLQ.
Now I have written consumer for Dead letter queue, so that I can transfer back the message after fixing the issue.
the piece of code to consume the message is as follows.
QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
QueueBrowser browser = session.createBrowser(queue);
Queue queue1=browser.getQueue();
Enumeration messageEnum = browser.getEnumeration();
while (messageEnum.hasMoreElements()) {
TextMessage message = (TextMessage) messageEnum.nextElement();
}
from the text message,is there any chance of getting source queue (APP.QUEUE1 or APP.QUEUE2), so that I have transfer back the same text message with out worrying much on message properties.
please let me know my approach is correct or not,appricite for better solution.
Found the answer for this.
we have property as follows.
message.getStringProperty("_HQ_ORIG_ADDRESS");
This property give originating address.

Maximum number of messages sent to a Queue in OpenMQ?

I am currently using Glassfish v2.1 and I have set up a queue to send and receive messages from with Sesion beans and MDBs respectively. However, I have noticed that I can send only a maximum of 1000 messages to the queue. Is there any reason why I cannot send more than 1000 messages to the queue? I do have a "developer" profile setup for the glassfish domain. Could that be the reason? Or is there some resource configuration setting that I need to modify?
I have setup the sun-resources.xml configuration properties as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Resource Definitions //EN" "http://www.sun.com/software/appserver/dtds/sun-resources_1_3.dtd">
<resources>
<admin-object-resource
enabled="true"
jndi-name="jms/UpdateQueue"
object-type="user"
res-adapter="jmsra"
res-type="javax.jms.Queue">
<description/>
<property name="Name" value="UpdatePhysicalQueue"/>
</admin-object-resource>
<connector-resource
enabled="true" jndi-name="jms/UpdateQueueFactory"
object-type="user"
pool-name="jms/UpdateQueueFactoryPool">
<description/>
</connector-resource>
<connector-connection-pool
associate-with-thread="false"
connection-creation-retry-attempts="0"
connection-creation-retry-interval-in-seconds="10"
connection-definition-name="javax.jms.QueueConnectionFactory"
connection-leak-reclaim="false"
connection-leak-timeout-in-seconds="0"
fail-all-connections="false"
idle-timeout-in-seconds="300"
is-connection-validation-required="false"
lazy-connection-association="false"
lazy-connection-enlistment="false"
match-connections="true"
max-connection-usage-count="0"
max-pool-size="32"
max-wait-time-in-millis="60000"
name="jms/UpdateFactoryPool"
pool-resize-quantity="2"
resource-adapter-name="jmsra"
steady-pool-size="8"
validate-atmost-once-period-in-seconds="0"/>
</resources>
Hmm .. further investigation revealed the following in the imq logs:
[17/Nov/2009:10:27:57 CST] ERROR sendMessage: Sending message failed. Connection ID: 427038234214377984:
com.sun.messaging.jmq.jmsserver.util.BrokerException: transaction failed: [B4303]: The maximum number of messages [1,000] that the producer can process in a single transaction (TID=427038234364096768) has been exceeded. Please either limit the # of messages per transaction or increase the imq.transaction.producer.maxNumMsgs property.
So what would I do if I needed to send more than 5000 messages at a time?
What I am trying to do is to read all the records in a table and update a particular field of each record based on the corresponding value of that record in a legacy table to which I have only read only access. This table has more than 10k records in it. As of now, I am sequentially going through each record in a for loop, getting the corresponding record from the legacy table, comparing the field values, updating the record if necessary and adding corresponding new records in other tables.
However, I was hoping to improve performance by processing all the records asynchronously. To do that I was thinking of sending each record info as a separate message and hence requiring so many messages.
To configure OpenMQ and set artitrary broker properties, have a look at this blog post.
But actually, I wouldn't advice to increase the imq.transaction.producer.maxNumMsgs property, at least not above the value recommended in the documentation:
The maximum number of messages that a producer can process in a single transaction. It is recommended that the value be less than 5000 to prevent the exhausting of resources.
If you need to send more messages, consider doing it in several transactions.