This is an automated email from the ASF dual-hosted git repository.

jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git


The following commit(s) were added to refs/heads/main by this push:
     new 4a014cabfc Update jms doc to add some usages about IBM MQ Client
4a014cabfc is described below

commit 4a014cabfc6be78c1b49be3e20202b400163c818
Author: Zheng Feng <zh.f...@gmail.com>
AuthorDate: Fri Sep 22 14:38:02 2023 +0800

    Update jms doc to add some usages about IBM MQ Client
    
    * Update jms doc to add some usages about IBM MQ Client
    
    * Update extensions/jms/runtime/src/main/doc/usage.adoc
    
    Co-authored-by: James Netherton <jamesnether...@users.noreply.github.com>
    
    * Replace to use Named
    
    * update docs
    
    ---------
    
    Co-authored-by: James Netherton <jamesnether...@users.noreply.github.com>
---
 .../ROOT/pages/reference/extensions/jms.adoc       | 81 +++++++++++++++++++---
 extensions/jms/runtime/src/main/doc/usage.adoc     | 81 +++++++++++++++++++---
 .../camel/quarkus/messaging/jms/JmsRoutes.java     |  4 +-
 3 files changed, 148 insertions(+), 18 deletions(-)

diff --git a/docs/modules/ROOT/pages/reference/extensions/jms.adoc 
b/docs/modules/ROOT/pages/reference/extensions/jms.adoc
index 678d7edfb2..07be4a5d4e 100644
--- a/docs/modules/ROOT/pages/reference/extensions/jms.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/jms.adoc
@@ -76,31 +76,96 @@ quarkus.pooled-jms.max-connections = 8
 endif::[]
 
 You can use the `quarkus-pooled-jms` extension to get pooling and XA support 
for JMS connections. Refer to the 
https://quarkiverse.github.io/quarkiverse-docs/quarkus-pooled-jms/dev/index.html[quarkus-pooled-jms]
 extension documentation for more information.
-Currently, it only works with `quarkus-artemis-jms` extension. Just add these 
two dependencies to your `pom.xml`:
+Currently, it can work with `quarkus-artemis-jms`, `quarkus-qpid-jms` and 
`ibmmq-client`. Just add the dependency to your `pom.xml`:
 [source,xml]
 ----
 <dependency>
     <groupId>io.quarkiverse.messaginghub</groupId>
     <artifactId>quarkus-pooled-jms</artifactId>
 </dependency>
+----
+
+Pooling is enabled by default.
+[NOTE]
+====
+`clientID` and `durableSubscriptionName` are not supported in pooling 
connections. If `setClientID` is called on a `reused` connection from the pool, 
an `IllegalStateException` will be thrown. You will get some error messages 
such like `Cause: setClientID can only be called directly after the connection 
is created`
+====
+
+To enable XA, you need to add `quarkus-narayana-jta` extension:
+[source,xml]
+----
 <dependency>
-    <groupId>io.quarkiverse.artemis</groupId>
-    <artifactId>quarkus-artemis-jms</artifactId>
+    <groupId>io.quarkus</groupId>
+    <artifactId>quarkus-narayana-jta</artifactId>
 </dependency>
 ----
+and add the following configuration to your `application.properties`:
+[source,properties]
+----
+quarkus.pooled-jms.transaction=xa
+quarkus.transaction-manager.enable-recovery=true
+----
 
-Note that pooling is enabled by default.
+XA support is only available with `quarkus-artemis-jms` and `ibmmq-client`. 
Also We highly recommend to enable transaction recovery.
 
-To enable XA, you need to add the following configuration to your 
`application.properties`:
-[source,properties]
+Since there is no quarkus extension for `ibmmq-client` currently, you need to 
create a custom `ConnectionFactory` and wrap it by yourself. Here is an example:
+[source,java]
 ----
-quarkus.pooled-jms.xa.enabled=true
+@Produces
+public ConnectionFactory createXAConnectionFactory(PooledJmsWrapper wrapper) {
+    MQXAConnectionFactory mq = new MQXAConnectionFactory();
+    try {
+        mq.setHostName(ConfigProvider.getConfig().getValue("ibm.mq.host", 
String.class));
+        mq.setPort(ConfigProvider.getConfig().getValue("ibm.mq.port", 
Integer.class));
+        mq.setChannel(ConfigProvider.getConfig().getValue("ibm.mq.channel", 
String.class));
+        
mq.setQueueManager(ConfigProvider.getConfig().getValue("ibm.mq.queueManagerName",
 String.class));
+        mq.setTransportType(WMQConstants.WMQ_CM_CLIENT);
+        mq.setStringProperty(WMQConstants.USERID,
+            ConfigProvider.getConfig().getValue("ibm.mq.user", String.class));
+        mq.setStringProperty(WMQConstants.PASSWORD,
+            ConfigProvider.getConfig().getValue("ibm.mq.password", 
String.class));
+    } catch (Exception e) {
+        throw new RuntimeException("Unable to create new IBM MQ connection 
factory", e);
+    }
+    return wrapper.wrapConnectionFactory(mq);
+}
 ----
 
 [NOTE]
 ====
-`clientID` and `durableSubscriptionName` are not supported in pooling 
connections. If `setClientID` is called on a `reused` connection from the pool, 
an `IllegalStateException` will be thrown. You will get some error messages 
such like `Cause: setClientID can only be called directly after the connection 
is created`
+If you use `ibmmq-client` to consume messages and enable XA, you need to 
configure `TransactionManager` in the camel route like this:
+[source,java]
+----
+@Inject
+TransactionManager transactionManager;
+
+@Override
+public void configure() throws Exception {
+    from("jms:queue:DEV.QUEUE.XA?transactionManager=#jtaTransactionManager");
+}
+
+@Named("jtaTransactionManager")
+public PlatformTransactionManager getTransactionManager() {
+    return new JtaTransactionManager(transactionManager);
+}
+----
+
+Otherwise, you will get an exception like `MQRC_SYNCPOINT_NOT_AVAILABLE`.
+====
+
+ifeval::[{doc-show-extra-content} == true]
+
+[NOTE]
 ====
+When you are using `ibmmq-client` and rollback a transaction, there will be a 
WARN message like:
+[source]
+----
+WARN  [com.arj.ats.jta] (executor-thread-1) ARJUNA016045: attempted rollback 
of < formatId=131077, gtrid_length=35, bqual_length=36, 
tx_uid=0:ffffc0a86510:aed3:650915d7:16, node_name=quarkus, 
branch_uid=0:ffffc0a86510:aed3:650915d7:1f, subordinatenodename=null, 
eis_name=0 > (com.ibm.mq.jmqi.JmqiXAResource@79786dde) failed with exception 
code XAException.XAER_NOTA: javax.transaction.xa.XAException: The method 
'xa_rollback' has failed with errorCode '-4'.
+----
+====
+ it may be ignored and can be assumed that MQ has discarded the transaction's 
work. Please refer to https://access.redhat.com/solutions/1250743[Red Hat 
Knowledgebase] for more information.
+
+endif::[]
 
 
 [id="extensions-jms-transferexception-option-in-native-mode"]
diff --git a/extensions/jms/runtime/src/main/doc/usage.adoc 
b/extensions/jms/runtime/src/main/doc/usage.adoc
index 582028bcc5..5e4592c15e 100644
--- a/extensions/jms/runtime/src/main/doc/usage.adoc
+++ b/extensions/jms/runtime/src/main/doc/usage.adoc
@@ -24,28 +24,93 @@ quarkus.pooled-jms.max-connections = 8
 endif::[]
 
 You can use the `quarkus-pooled-jms` extension to get pooling and XA support 
for JMS connections. Refer to the 
https://quarkiverse.github.io/quarkiverse-docs/quarkus-pooled-jms/dev/index.html[quarkus-pooled-jms]
 extension documentation for more information.
-Currently, it only works with `quarkus-artemis-jms` extension. Just add these 
two dependencies to your `pom.xml`:
+Currently, it can work with `quarkus-artemis-jms`, `quarkus-qpid-jms` and 
`ibmmq-client`. Just add the dependency to your `pom.xml`:
 [source,xml]
 ----
 <dependency>
     <groupId>io.quarkiverse.messaginghub</groupId>
     <artifactId>quarkus-pooled-jms</artifactId>
 </dependency>
+----
+
+Pooling is enabled by default.
+[NOTE]
+====
+`clientID` and `durableSubscriptionName` are not supported in pooling 
connections. If `setClientID` is called on a `reused` connection from the pool, 
an `IllegalStateException` will be thrown. You will get some error messages 
such like `Cause: setClientID can only be called directly after the connection 
is created`
+====
+
+To enable XA, you need to add `quarkus-narayana-jta` extension:
+[source,xml]
+----
 <dependency>
-    <groupId>io.quarkiverse.artemis</groupId>
-    <artifactId>quarkus-artemis-jms</artifactId>
+    <groupId>io.quarkus</groupId>
+    <artifactId>quarkus-narayana-jta</artifactId>
 </dependency>
 ----
+and add the following configuration to your `application.properties`:
+[source,properties]
+----
+quarkus.pooled-jms.transaction=xa
+quarkus.transaction-manager.enable-recovery=true
+----
 
-Note that pooling is enabled by default.
+XA support is only available with `quarkus-artemis-jms` and `ibmmq-client`. 
Also We highly recommend to enable transaction recovery.
 
-To enable XA, you need to add the following configuration to your 
`application.properties`:
-[source,properties]
+Since there is no quarkus extension for `ibmmq-client` currently, you need to 
create a custom `ConnectionFactory` and wrap it by yourself. Here is an example:
+[source,java]
 ----
-quarkus.pooled-jms.xa.enabled=true
+@Produces
+public ConnectionFactory createXAConnectionFactory(PooledJmsWrapper wrapper) {
+    MQXAConnectionFactory mq = new MQXAConnectionFactory();
+    try {
+        mq.setHostName(ConfigProvider.getConfig().getValue("ibm.mq.host", 
String.class));
+        mq.setPort(ConfigProvider.getConfig().getValue("ibm.mq.port", 
Integer.class));
+        mq.setChannel(ConfigProvider.getConfig().getValue("ibm.mq.channel", 
String.class));
+        
mq.setQueueManager(ConfigProvider.getConfig().getValue("ibm.mq.queueManagerName",
 String.class));
+        mq.setTransportType(WMQConstants.WMQ_CM_CLIENT);
+        mq.setStringProperty(WMQConstants.USERID,
+            ConfigProvider.getConfig().getValue("ibm.mq.user", String.class));
+        mq.setStringProperty(WMQConstants.PASSWORD,
+            ConfigProvider.getConfig().getValue("ibm.mq.password", 
String.class));
+    } catch (Exception e) {
+        throw new RuntimeException("Unable to create new IBM MQ connection 
factory", e);
+    }
+    return wrapper.wrapConnectionFactory(mq);
+}
 ----
 
 [NOTE]
 ====
-`clientID` and `durableSubscriptionName` are not supported in pooling 
connections. If `setClientID` is called on a `reused` connection from the pool, 
an `IllegalStateException` will be thrown. You will get some error messages 
such like `Cause: setClientID can only be called directly after the connection 
is created`
+If you use `ibmmq-client` to consume messages and enable XA, you need to 
configure `TransactionManager` in the camel route like this:
+[source,java]
+----
+@Inject
+TransactionManager transactionManager;
+
+@Override
+public void configure() throws Exception {
+    from("jms:queue:DEV.QUEUE.XA?transactionManager=#jtaTransactionManager");
+}
+
+@Named("jtaTransactionManager")
+public PlatformTransactionManager getTransactionManager() {
+    return new JtaTransactionManager(transactionManager);
+}
+----
+
+Otherwise, you will get an exception like `MQRC_SYNCPOINT_NOT_AVAILABLE`.
+====
+
+ifeval::[{doc-show-extra-content} == true]
+
+[NOTE]
 ====
+When you are using `ibmmq-client` and rollback a transaction, there will be a 
WARN message like:
+[source]
+----
+WARN  [com.arj.ats.jta] (executor-thread-1) ARJUNA016045: attempted rollback 
of < formatId=131077, gtrid_length=35, bqual_length=36, 
tx_uid=0:ffffc0a86510:aed3:650915d7:16, node_name=quarkus, 
branch_uid=0:ffffc0a86510:aed3:650915d7:1f, subordinatenodename=null, 
eis_name=0 > (com.ibm.mq.jmqi.JmqiXAResource@79786dde) failed with exception 
code XAException.XAER_NOTA: javax.transaction.xa.XAException: The method 
'xa_rollback' has failed with errorCode '-4'.
+----
+====
+ it may be ignored and can be assumed that MQ has discarded the transaction's 
work. Please refer to https://access.redhat.com/solutions/1250743[Red Hat 
Knowledgebase] for more information.
+
+endif::[]
diff --git 
a/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsRoutes.java
 
b/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsRoutes.java
index 0a1647fe1c..221f664005 100644
--- 
a/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsRoutes.java
+++ 
b/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsRoutes.java
@@ -18,8 +18,8 @@ package org.apache.camel.quarkus.messaging.jms;
 
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
+import jakarta.inject.Named;
 import jakarta.transaction.TransactionManager;
-import org.apache.camel.BindToRegistry;
 import org.apache.camel.builder.RouteBuilder;
 import 
org.apache.camel.quarkus.component.messaging.it.util.scheme.ComponentScheme;
 import org.springframework.transaction.PlatformTransactionManager;
@@ -70,7 +70,7 @@ public class JmsRoutes extends RouteBuilder {
                 .endChoice();
     }
 
-    @BindToRegistry("jtaTransactionManager")
+    @Named("jtaTransactionManager")
     public PlatformTransactionManager getTransactionManager() {
         return new JtaTransactionManager(transactionManager);
     }

Reply via email to