A JCA resource adapter for using AMQP 1.0 messaging with Java app servers such as WildFly.
This component combines the Generic JMS JCA resource adapter with the Apache Qpid JMS client.
Note that this resource adapter does not support distributed transactions (XA transactions). It supports only local transactions and non-transactional messaging.
To use the resource adapter in your project, add the following
dependency to your pom.xml
file:
<dependency>
<groupId>org.amqphub.jca</groupId>
<artifactId>resource-adapter</artifactId>
<version>${current-version}</version>
<type>rar</type>
</dependency>
The project requires Maven 3. To build the code, use the mvn install
command.
$ mvn install
-
Copy the
resource-adapter/target/resource-adapter-<version>.rar
andwildfly-example/target/wildfly-example-<version>.war
files to the WildFlystandalone/deployments
directory. -
Copy the
wildfly-example/standalone-custom.xml
file to the WildFlystandalone/configuration
directory. -
In a separate terminal window, start an AMQP 1.0 server with user
example
and passwordexample
on localhost and port 5672. If your server does not create queues on demand, use the tools for your server to create queues calledexample/requests
andexample/responses
. Seescripts/run-artemis.sh
. -
In a separate terminal window, start WildFly. Tell it to use the
standalone-custom.xml
configuration file. Seescripts/run-wildfly.sh
. -
Use
curl
to send text to thesend-request
endpoint.$ curl -fX POST http://localhost:8080/wildfly-example/api/send-request -H "content-type: text/plain" -d "hellooo" ID:4a63adc0-547c-4881-bc3e-3c8eb7007648:2:1:1-1
-
Use
curl
again to get the response from thereceive-response
endpoint.$ curl -fX POST http://localhost:8080/wildfly-example/api/receive-response ID:4a63adc0-547c-4881-bc3e-3c8eb7007648:2:1:1-1: HELLOOO
The example test performs the steps above. You can run it with the following commands:
$ mvn clean package
$ scripts/test-example.sh
Add or modify the resource-adapters
subsystem. Change the JNDI and
connection properties according to your needs.
<subsystem xmlns="urn:jboss:domain:resource-adapters:5.0">
<resource-adapters>
<resource-adapter>
<archive>resource-adapter.rar</archive>
<transaction-support>NoTransaction</transaction-support>
<connection-definitions>
<connection-definition class-name="org.jboss.resource.adapter.jms.JmsManagedConnectionFactory"
jndi-name="java:global/jms/default">
<config-property name="UserName">example</config-property>
<config-property name="Password">example</config-property>
<config-property name="ConnectionFactory">factory1</config-property>
<config-property name="JndiParameters">java.naming.factory.initial=org.apache.qpid.jms.jndi.JmsInitialContextFactory;connectionFactory.factory1=amqp://localhost:5672</config-property>
</connection-definition>
</connection-definitions>
</resource-adapter>
</resource-adapters>
</subsystem>
Add or modify the ejb3
subsystem.
<subsystem xmlns="urn:jboss:domain:ejb3:6.0">
<mdb>
<resource-adapter-ref resource-adapter-name="resource-adapter.rar"/>
<bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
</mdb>
...
</subsystem>
For a complete example, see standalone-custom.xml.
Additional notes:
-
Your WildFly configuration must have the
messaging-activemq
subsystem installed, even though you are not using the internal broker in this case. -
Your application code must have a
src/main/resources/META-INF/beans.xml
file that enables bean discovery mode. -
You application code must have a
src/main/resources/META-INF/MANIFEST.MF
with an entry that corresponds to the name of your.rar
file.
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "connectionFactory", propertyValue = "factory1"),
@ActivationConfigProperty(propertyName = "user", propertyValue = "example"),
@ActivationConfigProperty(propertyName = "password", propertyValue = "example"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue1"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "jndiParameters", propertyValue = "java.naming.factory.initial=org.apache.qpid.jms.jndi.JmsInitialContextFactory;connectionFactory.factory1=amqp://localhost:5672;queue.queue1=example"),
})
@ResourceAdapter("resource-adapter.rar")
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class ExampleListener implements MessageListener {
@Override
public void onMessage(Message message) {
System.out.println("Received message " + message);
}
}
For complete examples, see RequestListener.java and ResponseListener.java.
@Singleton
public class ExampleApplication {
@Inject
@JMSConnectionFactory("java:global/jms/default")
private JMSContext jmsContext;
public synchronized void sendMessage(String text) throws JMSException {
Queue queue = jmsContext.createQueue("example");
JMSProducer producer = jmsContext.createProducer();
TextMessage message = jmsContext.createTextMessage();
message.setText(text);
producer.send(queue, message);
System.out.println("Sent message " + message);
}
}
For a complete example, see ExampleApplication.java.