Hi all,

Please forgive me if this is a basic question.

Working with Camel and JMS Topics has seemed very finicky for me so far. If I 
make slight configuration changes, I see the same message repeated endlessly. 
Using jconsole, I now know these messages are "external redeliveries", i.e. the 
same message is being sent from JMS to Camel repeatedly without ever getting 
through. It happens in the case of messages that I am intentionally not 
processing due to some criteria. What I don't understand is why these external 
redeliveries keep occurring, when I simply want this message to be dropped.

For example, if I use CACHE_SESSION or lower cache level, the following route 
works just fine for me:


        <route id="topics-out">
            <from uri="topic-jms:topic:projectx.>"/>
            <log message="Picked up message with id: ${id}, destinationType: 
${header.DestinationEntityType}" loggingLevel="INFO"/>
            <choice>
                <when>
                    <simple>${header.DestinationEntityType} not in 
'FOO,BAR'</simple>
                    <log message="Detected new ${header.Name} topic message on 
${header.JMSDestination} with id: ${id}, destinationType: 
${header.DestinationEntityType}" loggingLevel="INFO"/>
                    <recipientList ignoreInvalidEndpoints="false">
                        <simple>lc-jms:${header.JMSDestination}</simple>
                    </recipientList>
                </when>
            </choice>
        </route>


However, if I switch to CACHE_CONSUMER and I have even one message addressed to 
'FOO' or 'BAR', I will see the endless external redeliveries. Note that I am 
using a SingleConnectionFactory specifically for this route.

        <route id="topics-out">
            <from uri="topic-jms:topic:projectx.>"/>
            <log message="Picked up message with id: ${id}, destinationType: 
${header.DestinationEntityType}" loggingLevel="INFO"/>
            <choice>
                <when>
                    <simple>${header.DestinationEntityType} not in 
'FOO,BAR'</simple>
                    <log message="Detected new ${header.Name} topic message on 
${header.JMSDestination} with id: ${id}, destinationType: 
${header.DestinationEntityType}" loggingLevel="INFO"/>
                    <recipientList ignoreInvalidEndpoints="false">
                        <simple>lc-jms:${header.JMSDestination}</simple>
                    </recipientList>
                </when>
            </choice>
        </route>

Now, if I add an Otherwise clause with a Rollback, everything works fine again 
(albeit with a handful of log messages due to the rollbacks):

        <route id="topics-out">
            <from uri="topic-jms:topic:projectx.>"/>
            <log message="Picked up message with id: ${id}, destinationType: 
${header.DestinationEntityType}" loggingLevel="INFO"/>
            <choice>
                <when>
                    <simple>${header.DestinationEntityType} not in 
'FOO,BAR'</simple>
                    <log message="Detected new ${header.Name} topic message on 
${header.JMSDestination} with id: ${id}, destinationType: 
${header.DestinationEntityType}" loggingLevel="INFO"/>
                    <recipientList ignoreInvalidEndpoints="false">
                        <simple>lc-jms:${header.JMSDestination}</simple>
                    </recipientList>
                </when>
                <otherwise>
                <rollback markRollbackOnly="true" />
                </otherwise>
            </choice>
        </route>

But if I change that Rollback to a Stop instead, I get the endless external 
redeliveries again:

        <route id="topics-out">
            <from uri="topic-jms:topic:projectx.>"/>
            <log message="Picked up message with id: ${id}, destinationType: 
${header.DestinationEntityType}" loggingLevel="INFO"/>
            <choice>
                <when>
                    <simple>${header.DestinationEntityType} not in 
'FOO,BAR'</simple>
                    <log message="Detected new ${header.Name} topic message on 
${header.JMSDestination} with id: ${id}, destinationType: 
${header.DestinationEntityType}" loggingLevel="INFO"/>
                    <recipientList ignoreInvalidEndpoints="false">
                        <simple>lc-jms:${header.JMSDestination}</simple>
                    </recipientList>
                </when>
                <otherwise>
                 <stop/>
                </otherwise>
            </choice>
        </route>

Why does rolling back prevent the unwanted message from being redelivered, 
while using "stop" causes the redelivery to occur? Intuitively, I would have 
thought it would work the opposite way. Rolling back should put the item back 
on the "from" endpoint, allowing it to be processed again. "Stop" should just 
drop the message, preventing further redelivery. What I'm actually seeing is 
the opposite of this. Am I misunderstanding?

I also get the same exact symptoms if I leave the cache level at CACHE_SESSION, 
but I make the subscription durable. In that case the rollbacks prevent the 
problem, but otherwise I get the eternal external redeliveries.

Using a Filter element also produces the same results as using the Choice 
element above:

        <route id="topics-out">
            <from 
uri="topic-jms:topic:projectx.>?durableSubscriptionName=testdurasub"/>
            <log message="Picked up message with id: ${id}, destinationType: 
${header.DestinationEntityType}" loggingLevel="INFO"/>
            <filter>
                <simple>${header.DestinationEntityType} not in 
'FOO,BAR'</simple>
                <recipientList ignoreInvalidEndpoints="false">
                    <simple>lc-jms:${header.JMSDestination}</simple>
                </recipientList>
            </filter>
        </route>

When I look at the topic in JMS, I see the topic "projectx.>" appearing and 
disappearing in the list rapidly. I assume that's caused by the Camel polling 
frequency. It seems a little disturbing to me; is that normal?

Thanks so much for taking the time to help!

Jeff Bischoff
WDTS

Reply via email to