Following up my own question with an answer:  

I found a solution by following the clues at 
https://issues.apache.org/jira/browse/QPID-4991.  I gather that ActiveMQ 
doesn't internally map AMQP topics to JMS topics unless the destinationName 
begins with the prefix "topic://".  If this prefix is absent then ActiveMQ maps 
your AMQP topic to a JMS queue of the same name.  Since the Qpid JMS connection 
factory doesn't add this prefix by default, Camel ends up connecting to queues 
when it thinks it is connecting to topics.  The solution is to explicitly tell 
the Qpid connection factory to add the prefix that ActiveMQ wants to every 
topic name.  The following worked for me:

    <bean id="amqpConnection" 
class="org.apache.camel.component.jms.JmsComponent" >
        <property name="connectionFactory">
          <bean class="org.apache.qpid.amqp_1_0.jms.impl.ConnectionFactoryImpl" 
factory-method="createFromURL">
                        <constructor-arg index="0" type="java.lang.String" 
value="amqp://localhost:5672" />
            <property name="topicPrefix" value="topic://" />  <!-- only 
necessary when connecting to ActiveMQ over AMQP 1.0 -->
           </bean>
        </property>
    </bean>

I hope this is of assistance to others.


-----Original Message-----
From: Mark Kusec 
Sent: Thursday, April 30, 2015 10:31 AM
To: [email protected]
Subject: Camel connects to queue instead of topic when using AMQP 1.0

Hi all, I have run into an interesting issue, and I'm not sure whether it is 
due to user error or a bug.  I'm using Spring XML DSL to setup a subscription 
to a topic.  But instead of getting a subscription to a topic, I'm actually 
getting a consumer on a queue of the same name.  

This only happens if I use AMQP 1.0 (camel-amqp).  If I change to OpenWire, I 
get a subscription to a topic as I expect.  The following illustrates how I 
tested this:

In servlet.xml, I have created two connections to the same instance of 
ActiveMQ, one of which uses AMQP and one not:

    <bean id="amqpConnection" 
class="org.apache.camel.component.jms.JmsComponent" >
        <property name="connectionFactory">
          <bean class="org.apache.qpid.amqp_1_0.jms.impl.ConnectionFactoryImpl" 
factory-method="createFromURL">
                        <constructor-arg index="0" type="java.lang.String" 
value="amqp://localhost:5672" />
           </bean>
        </property>
    </bean>
    
    <bean id="tcpConnection" 
class="org.apache.camel.component.jms.JmsComponent" >
        <property name="connectionFactory">
          <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                        <property name="brokerURL" 
value="tcp://localhost:61616" /> 
          </bean>
        </property>
    </bean>

My routes look like this.  I think they should both connect to the same topic.  
But in the ActiveMQ hawtio, I can see that " AMQP-ROUTE" is a consumer of a 
Queue named "TEST", while "TCP-ROUTE" is a subscriber to a Topic named "TEST".

          <route id="AMQP-ROUTE">
            <from 
uri="amqpConnection:topic://TEST?clientId=TestWithAMQP&amp;durableSubscriptionName=TestDurSysAMQP"
 />
            <to uri="file:///foo"/>
         </route>
         
         <route id="TCP-ROUTE">
           <from 
uri="tcpConnection:topic://TEST?clientId=TestWithTCP&amp;durableSubscriptionName=TestDurSysTCP"
 />
           <to uri="file:///bar"/>
         </route>

Did I do something wrong in specifying the Connection Factory or anything else? 
 Is there a deficiency in Qpid or camel-amqp?  Help! 

P.S. Is there any other/better way to specify an AMQP 1.0 JMS connection 
factory in Spring?  I searched all over the web, but did not find any other 
examples.

Thanks,
Mark

Reply via email to