I am trying to understand Spring RabbitMQ codes when RabbitMQ is configured in XML files.
In the receiver xml file, I have
<rabbit:queue id="springQueue" name="spring.queue" auto-delete="true" durable="false"/>
<rabbit:queue name="springQueue" auto-delete="true" durable="false"/>
<rabbit:listener-container connection-factory="connectionFactory">
<rabbit:listener queues="springQueue" ref="messageListener"/>
</rabbit:listener-container>
<bean id="messageListener" class="com.ndpar.spring.rabbitmq.MessageHandler"/>
<!-- Bindings -->
<rabbit:fanout-exchange name="amq.fanout">
<rabbit:bindings>
<rabbit:binding queue="springQueue"/>
</rabbit:bindings>
</rabbit:fanout-exchange>
My question is - To which queue is the exchange bound to?? springQueue or spring.queue ?? I mean to ask, in the tag - , is it referring to queue id or queue name ?? also in the tag , the attribute 'queues' refers to queue id or queue name?? Please help. I looked at the schemas (xsd) but couldn't get clarity. Please help.
queues (in the listener) and queue (in the binding) should refer to the queue id attribute.
In the listener, you can use the queue name in the queue-names attribute but the binding always needs the id.
Related
I need to implement 2 filters that fit in the amq:discardingDLQBrokerPlugin category, and I need one to be executed before the other.
I can implement the two filter's logic in one class, but since the business logic is very different, I would prefer two.
I add the filters using two different plugins: com.filter.FilterAPlugin and com.filter.FilterBPlugin. The filter execution order follows a "last defined first executed" logic.
Example: In this broker configuration
<amq:broker useJmx="false" persistent="false" schedulerSupport="true">
<amq:transportConnectors>
<amq:transportConnector uri="tcp://localhost:0" />
</amq:transportConnectors>
<amq:plugins>
<amq:discardingDLQBrokerPlugin dropAll="true" dropTemporaryTopics="true" dropTemporaryQueues="true" />
<bean xmlns="http://www.springframework.org/schema/beans" class="com.filter.FilterAPlugin" />
<bean xmlns="http://www.springframework.org/schema/beans" class="com.filter.FilterBPlugin" />
</amq:plugins>
</amq:broker>
Filter added in com.filter.FilterBPlugin is executed first.
Does the order in which the beans are declared defines the order of execution of the filters? I can't find documentation about this in the apache MQ web
BrokerService uses Chain of Responsibility pattern, so execution order is defined by the object initialization order.
A message sent to a virtual topic will be dispatched to every queue named as "Consumer.*.VirtualTopic.", is it possible that such messages will only be dispatched to a certain queues that match a condition , instead of all the queues that map to the virtual topic ?
If you know up front that there are only going to be a set number of consumers/queues, you can use composite destinations instead of virtual ones and use filteredDestination blocks to make routing decisions based on message headers.
<destinationInterceptors>
<virtualDestinationInterceptor>
<virtualDestinations>
<compositeQueue name="orders">
<forwardTo>
<filteredDestination selector="odd = 'yes'" queue="orders.odd"/>
<queue physicalName="orders.accounting" />
<queue physicalName="orders.warehouse" />
<queue physicalName="orders.crm" />
</forwardTo>
</compositeQueue>
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>
For more complex routing decisions you should consider using an external routing engine such as Apache Camel.
In Mule 3.3.1, during async processing, when any of my external services are down, I would like to place the message on a queue (retryQueue) with a particular "next retry" timestamp. The flow that processes messages from this retryQueue selects messages based on "next retry" time as in if "next retry" time is past current time, select the message for processing. Similar to what has been mentioned in following link.
Retry JMS queue implementation to deliver failed messages after certain interval of time
Could you please provide sample code to achieve this?
I tried:
<on-redelivery-attempts-exceeded>
<message-properties-transformer scope="outbound">
<add-message-property key="putOnQueueTime" value="#[function:datestamp:yyyy-MM-dd hh:mm:ssZ]" />
</message-properties-transformer>
<jms:outbound-endpoint ref="retryQueue"/>
</on-redelivery-attempts-exceeded>
and on the receiving flow
<jms:inbound-endpoint ref="retryQueue">
<!-- I have no idea how to do the selector....
I tried....<jms:selector expression="#[header:INBOUND:putOnQueueTime > ((function:now) - 30)]"/>, but obviously it doesn't work. Gives me an invalid message selector. -->
</jms:inbound-endpoint>.
Another note: If I set the outbound property using
<add-message-property key="putOnQueueTime" value="#[function:now]"/>,
it doesn't get carried over as part of header. That's why I changed it to:
<add-message-property key="putOnQueueTime" value="#[function:datestamp:yyyy-MM-dd hh:mm:ssZ]" />
The expression in:
<jms:selector expression="#[header:INBOUND:putOnQueueTime > ((function:now) - 30)]"/>
should evaluate to a valid JMS selector, which is not the case here. Try with:
<jms:selector expression="putOnQueueTime > #[XXX]"/>
replacing XXX with an expression that creates the time you want.
We were trying to achieve this in one of the projects I'm working on, and tried what was being suggested in the other answer here, and it did not work, with various variantions. The problem is that the jms:selector doesn't support MEL, since it's relies on ActiveMQ classes.
We registered a support-ticket to Mulesoft, and their reply was that this is not supported.
What we ended up doing was this:
Create a simple Component, which does a Thread.sleep(numberOfMillis), where the number of millis is defined in a property.
In the flow that was supposed to delay processing, we added this component as the first step after reading the message from the inbound endpoint.
Not the best solution ever made, but it works..
I'm using Jboss 7.1.1.final and I would like to define 2 different DLQ's, one for a certain queue and the other for all the rest of the queues.
I found this configuration :
<address-settings>
<address-setting match="jms.queue.exampleQueue">
<dead-letter-address>jms.queue.deadLetterQueue</dead-letter-address>
<max-delivery-attempts>3</max-delivery-attempts>
<redelivery-delay>5000</redelivery-delay>
<expiry-address>jms.queue.expiryQueue</expiry-address>
<last-value-queue>true</last-value-queue>
<max-size-bytes>100000</max-size-bytes>
<page-size-bytes>20000</page-size-bytes>
<redistribution-delay>0</redistribution-delay>
<send-to-dla-on-no-route>true</send-to-dla-on-no-route>
<address-full-policy>PAGE</address-full-policy>
</address-setting>
</address-settings>
The match attribute can be used to match a certain queue, I have a couple of questions regarding this configuration:
If I define 2 address-setting, one with a wild card to match all and one that matches only one queue, does the one queue definition take precedence? Do i need to put it before the match all definition or it does not matter?
In the example they match a queue jms.queue.exampleQueue, i have a queue defined as:
<jms-queue name="MissionResult">
<entry name="queue/MissionResult"/>
</jms-queue>
what should i put in the match attribute in order to match it?
Found the answer:
The 2 definitions can co-exist. Jboss will find the best match.
You need to define a queue like:
<jms-queue name="exampleQueue">
<entry name="queue/exampleQueue" />
</jms-queue>
and then to match this queue, use jms.queue.exampleQueue.
I've been having trouble with Camel transactions and after some great help from the camel list I eventually tracked it down to using org.apache.activemq.camel.component.ActiveMQComponent in a bean with id 'activemq'. If I use an id of 'activemqTx' it works. But I can't seem to find any documentation on the significance of 'activemqTx' as a bean id.
only one message gets through the route with this:
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
everything works with this:
<bean id="activemqTx" class="org.apache.activemq.camel.component.ActiveMQComponent">
Must have been a bean name clash