Ce contenu n'est pas disponible dans la langue sélectionnée.
2.4. Integration with JMS
The
camel-jms
component provides messaging support. It integrates with the EAP Messaging (HornetQ) subsystem. Integration with other JMS implementations is possible by using the JBoss generic JMS Resource Adapter.
2.4.1. Configuring EAP JMS
With the help of standard EAP XML configuration files, you can configure the EAP messaging subsystem. The following example displays the configuration of a new JMS queue on the messaging subsystem, by adding the XML configuration to the
jms-destinations
section.
<jms-queue name="WildFlyCamelQueue"> <entry name="java:/jms/queue/WildFlyCamelQueue"/> </jms-queue>
However, you can also use a CLI script to add the queue.
jms-queue add --queue-address=WildFlyCamelQueue --entries=queue/WildFlyCamelQueue,java:/jms/queue/WildFlyCamelQueue
2.4.2. Configuring Camel Route
The following examples of JMS producer and consumer illustrates the use of EAP embedded HornetQ server to publish and consume messages, to and from destinations.
However, it also displays the use of CDI in conjunction with the
camel-cdi
component. You can inject the JMS ConnectionFactory instances into the Camel RouteBuilder via JNDI lookups.
2.4.2.1. JMS Producer
You can start the
RouteBuilder
by injecting the DefaultJMSConnectionFactory
connection factory from JNDI. However, the connection factory is defined within the messaging subsystem. Also, a timer endpoint runs after every 10 seconds to share an XML payload to the EAPCamelQueue
destination.
@Startup @ApplicationScoped @ContextName("jms-camel-context") public class JmsRouteBuilder extends RouteBuilder { @Resource(mappedName = "java:jboss/DefaultJMSConnectionFactory") private ConnectionFactory connectionFactory; @Override public void configure() throws Exception { JmsComponent component = new JmsComponent(); component.setConnectionFactory(connectionFactory); getContext().addComponent("jms", component); from("timer://sendJMSMessage?fixedRate=true&period=10000") .transform(constant("<?xml version='1.0><message><greeting>hello world</greeting></message>")) .to("jms:queue:WildFlyCamelQueue") .log("JMS Message sent"); } }
When you add a JMS message to the
EAPCamelQueue
destination, a log message appears. Use the EAP Administration console to verify that the messages are placed onto the queue.
2.4.2.2. JMS Consumer
To consume JMS messages, inject and set the connection factory from JNDI on the JMSComponent instance. When the JMS endpoint consumes messages from the EAPCamelQueue destination, the content is logged to the console.
@Override public void configure() throws Exception { JmsComponent component = new JmsComponent(); component.setConnectionFactory(connectionFactory); getContext().addComponent("jms", component); from("jms:queue:WildFlyCamelQueue") .to("log:jms?showAll=true"); }
2.4.2.3. JMS Transactions
To enable the Apache Camel JMS routes to participate in JMS transactions, you need to configure some spring classes to enable them to work with the EAP transaction manager and connection factory. The following example illustrates how to use CDI to configure a transactional JMS Camel route.
The
camel-jms
component requires a transaction manager of type org.springframework.transaction.PlatformTransactionManager
. Therefore, you can create a bean extending JtaTransactionManager.
Note
Use the annotation
@Named
to make the bean available to Camel. It enables you to register the bean within the camel bean registry. Also, inject the EAP transaction manager and user transaction instances by using CDI.
@Named("transactionManager") public class CdiTransactionManager extends JtaTransactionManager { @Resource(mappedName = "java:/TransactionManager") private TransactionManager transactionManager; @Resource private UserTransaction userTransaction; @PostConstruct public void initTransactionManager() { setTransactionManager(transactionManager); setUserTransaction(userTransaction); } }
Declare the transaction policy that you want to implement. Use the annotation to make the bean available to Camel. Inject the transaction manager, so that you can create a
TransactionalTemplate
using the desired transaction policy. For example, PROPAGATION_REQUIRED
in this instance.
@Named("PROPAGATION_REQUIRED") public class CdiRequiredPolicy extends SpringTransactionPolicy { @Inject public CdiRequiredPolicy(CdiTransactionManager cdiTransactionManager) { super(new TransactionTemplate(cdiTransactionManager, new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED))); } }
Also, you can configure the Camel RouteBuilder class and inject the dependencies you need for the Camel JMS component as shown in the given example:
@Startup @ApplicationScoped @ContextName("jms-camel-context") public class JMSRouteBuilder extends RouteBuilder { @Resource(mappedName = "java:/JmsXA") private ConnectionFactory connectionFactory; @Inject CdiTransactionManager transactionManager; @Override public void configure() throws Exception { // Creates a JMS component which supports transactions JmsComponent jmsComponent = JmsComponent.jmsComponentTransacted(connectionFactory, transactionManager); getContext().addComponent("jms", jmsComponent); from("jms:queue:queue1") .transacted("PROPAGATION_REQUIRED") .to("jms:queue:queue2"); from("jms:queue:queue2") .to("log:end") .rollback(); }
2.4.2.4. Remote JMS destinations
You can send messages from one EAP instance to HornetQ destinations configured on an other EAP instance, through remote JNDI. To send messages, you need to configure an exported JMS queue. Only JNDI names bound in the
java:jboss/export
namespace are appropriate for remote clients.
<jms-queue name="RemoteQueue"> <entry name="java:jboss/exported/jms/queues/RemoteQueue"/> </jms-queue>
Note
Configure the queue on the EAP client application server and EAP remote server.