0
votes

I was able to successful read from a Remote ActiveMQ Queue using a resource adapter as defined in https://developer.jboss.org/wiki/HowToUseOutOfProcessActiveMQWithWildFly using Wildfly 10. It references the following configuration in standalone

<subsystem xmlns="urn:jboss:domain:resource-adapters:2.0">  
  <resource-adapters>  
    <resource-adapter id="activemq-rar.rar">  
      <module slot="main" id="org.apache.activemq.ra" />  
      <transaction-support>XATransaction</transaction-support>  
        <config-property name="UseInboundSession">  
          false  
        </config-property>  
        <config-property name="Password">  
          mypassword
        </config-property>  
        <config-property name="UserName">  
          myuser  
        </config-property>  
        <config-property name="ServerUrl">  
          ssl://hostname:61617
        </config-property>  
        <connection-definitions>  
          <connection-definition class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory" jndi-name="java:/ConnectionFactory" enabled="true" pool-name="ConnectionFactory">  
            <xa-pool>  
            <min-pool-size>1</min-pool-size>  
            <max-pool-size>20</max-pool-size>  
            <prefill>false</prefill>  
            <is-same-rm-override>false</is-same-rm-override>  
          </xa-pool>  
        </connection-definition>  
      </connection-definitions>  
      <admin-objects>  
        <admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="java:/activemq/projectName.queue.projectQueue" use-java-context="true" pool-name="PoolName">  
          <config-property name="PhysicalName">  
            ProjectQueue  
          </config-property>  
        </admin-object>  
      </admin-objects>  
    </resource-adapter>  
  </resource-adapters>  
</subsystem>

To get the code to work I used the follow MessageDriven annotation on my Listener

@MessageDriven(activationConfig = {
  @ActivationConfigProperty(propertyName = "destination", propertyValue = "projectName.queue.projectQueue"),
  @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
  @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")})
public class MyMDB implements MessageListener {
   ...
}

This works because you are essentially hard coding the remote jndi name into the @MessageDriven annotation. I would prefer to use the physical name so that the remote queue name could change without having to update the annotations in the code. When I use the Physical name as the destiation value I get the following error

Failed to connect to broker [ssl://hostname:61617]: User myuser is not authorized to read from: queue://ProjectQueue: javax.jms.JMSSecurityException: User myuser is not authorized to read from: queue://ProjectQueue
  at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:52)
  at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1399)
  at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1428)
  at org.apache.activemq.ActiveMQConnectionConsumer.<init>(ActiveMQConnectionConsumer.java:82)
  at org.apache.activemq.ActiveMQConnection.createConnectionConsumer(ActiveMQConnection.java:1244)
  at org.apache.activemq.ra.ActiveMQEndpointWorker$1.run(ActiveMQEndpointWorker.java:140)
  at org.jboss.jca.core.workmanager.WorkWrapper.run(WorkWrapper.java:223)
  at org.jboss.threads.SimpleDirectExecutor.execute(SimpleDirectExecutor.java:33)
  at org.jboss.threads.QueueExecutor.runTask(QueueExecutor.java:808)
  at org.jboss.threads.QueueExecutor.access$100(QueueExecutor.java:45)
  at org.jboss.threads.QueueExecutor$Worker.run(QueueExecutor.java:828)
  at java.lang.Thread.run(Thread.java:745)
  at org.jboss.threads.JBossThread.run(JBossThread.java:320)

Is it possible to create some internal JNDI binding so that my @MessageDriven annotation can bind to that name or some config-property on the admin-object?

1

1 Answers

0
votes

I found the solution. The trick is the "useJndi" ActivationConfigProperty

@MessageDriven(activationConfig = {
  @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/activemq/projectName.queue.projectQueue"),
  @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
  @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
  @ActivationConfigProperty(propertyName = "useJndi", propertyValue = "true")})
public class MyMDB implements MessageListener {
   ...
}

This allows means that JNDI looks will find the admin object defined in the resource adapter configuration in standalone.xml

<resource-adapters> 
  ...
  <admin-objects>  
    <admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="java:/activemq/projectName.queue.projectQueue" use-java-context="true" pool-name="PoolName">  
      <config-property name="PhysicalName">  
        ProjectQueue  
      </config-property>  
    </admin-object>  
  </admin-objects>
</resource-adapters>