diff --git a/deployment/pom.xml b/deployment/pom.xml
index 5e5ede5..f861349 100644
--- a/deployment/pom.xml
+++ b/deployment/pom.xml
@@ -52,6 +52,10 @@
io.quarkus
quarkus-arc-deployment
+
+ io.quarkus
+ quarkus-jms-spi-deployment
+
io.quarkus
quarkus-netty-deployment
diff --git a/deployment/src/main/java/org/amqphub/quarkus/qpid/jms/deployment/QpidJmsProcessor.java b/deployment/src/main/java/org/amqphub/quarkus/qpid/jms/deployment/QpidJmsProcessor.java
index 52ec56b..f3b9d6c 100644
--- a/deployment/src/main/java/org/amqphub/quarkus/qpid/jms/deployment/QpidJmsProcessor.java
+++ b/deployment/src/main/java/org/amqphub/quarkus/qpid/jms/deployment/QpidJmsProcessor.java
@@ -15,7 +15,13 @@
*/
package org.amqphub.quarkus.qpid.jms.deployment;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.jms.ConnectionFactory;
+
+import org.amqphub.quarkus.qpid.jms.runtime.ConnectionFactoryWrapper;
import org.amqphub.quarkus.qpid.jms.runtime.QpidJmsProducer;
+import org.amqphub.quarkus.qpid.jms.runtime.QpidJmsRecorder;
+
import org.apache.qpid.jms.JmsConnectionFactory;
import org.apache.qpid.jms.meta.JmsConnectionInfo;
import org.apache.qpid.jms.provider.amqp.AmqpProvider;
@@ -50,15 +56,22 @@
import org.apache.qpid.proton.engine.impl.TransportImpl;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
+import io.quarkus.jms.spi.deployment.ConnectionFactoryWrapperBuildItem;
+
+import java.util.Optional;
+import java.util.function.Function;
public class QpidJmsProcessor {
private static final String QPID_JMS = "qpid-jms";
@@ -81,6 +94,23 @@ AdditionalBeanBuildItem registerBean() {
return AdditionalBeanBuildItem.unremovableOf(QpidJmsProducer.class);
}
+ @BuildStep
+ @Record(ExecutionTime.RUNTIME_INIT)
+ void connectionFactoryWrapper(Optional connectionFactoryWrapper,
+ QpidJmsRecorder recorder,
+ BuildProducer syntheticBeanProducer) {
+ if (connectionFactoryWrapper.isPresent()) {
+ Function wrapper = connectionFactoryWrapper.get().getWrapper();
+ SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator = SyntheticBeanBuildItem.configure(ConnectionFactoryWrapper.class)
+ .setRuntimeInit()
+ .defaultBean()
+ .unremovable()
+ .scope(ApplicationScoped.class)
+ .runtimeValue(recorder.getConnectionFactoryWrapper(wrapper));
+ syntheticBeanProducer.produce(configurator.done());
+ }
+ }
+
@BuildStep
public void build(CombinedIndexBuildItem indexBuildItem, BuildProducer reflectiveClass,
BuildProducer delayedInitialisation,
diff --git a/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/ConnectionFactoryWrapper.java b/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/ConnectionFactoryWrapper.java
new file mode 100644
index 0000000..b9ef444
--- /dev/null
+++ b/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/ConnectionFactoryWrapper.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.amqphub.quarkus.qpid.jms.runtime;
+
+import jakarta.jms.ConnectionFactory;
+
+public interface ConnectionFactoryWrapper {
+ ConnectionFactory wrap(ConnectionFactory connectionFactory);
+}
diff --git a/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsProducer.java b/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsProducer.java
index 3231184..51ee694 100644
--- a/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsProducer.java
+++ b/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsProducer.java
@@ -15,6 +15,7 @@
*/
package org.amqphub.quarkus.qpid.jms.runtime;
+import io.quarkus.arc.Arc;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import jakarta.inject.Inject;
@@ -34,7 +35,14 @@ public class QpidJmsProducer {
@ApplicationScoped
@DefaultBean
public ConnectionFactory connectionFactory() {
- return new JmsConnectionFactory(config.username.orElse(null), config.password.orElse(null), config.url);
+ ConnectionFactory connectionFactory = new JmsConnectionFactory(config.username.orElse(null), config.password.orElse(null), config.url);
+ ConnectionFactoryWrapper wrapper = Arc.container().instance(ConnectionFactoryWrapper.class).get();
+
+ if (config.wrap && wrapper != null) {
+ return wrapper.wrap(connectionFactory);
+ } else {
+ return connectionFactory;
+ }
}
public QpidJmsRuntimeConfig getConfig() {
diff --git a/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsRecorder.java b/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsRecorder.java
new file mode 100644
index 0000000..6f187f3
--- /dev/null
+++ b/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsRecorder.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.amqphub.quarkus.qpid.jms.runtime;
+
+import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.annotations.Recorder;
+import jakarta.jms.ConnectionFactory;
+
+import java.util.function.Function;
+
+@Recorder
+public class QpidJmsRecorder {
+ public RuntimeValue getConnectionFactoryWrapper(Function wrapper) {
+ return new RuntimeValue<>(connectionFactory -> (ConnectionFactory) wrapper.apply(connectionFactory));
+ }
+}
diff --git a/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsRuntimeConfig.java b/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsRuntimeConfig.java
index f7e61c0..0dc5cc7 100644
--- a/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsRuntimeConfig.java
+++ b/runtime/src/main/java/org/amqphub/quarkus/qpid/jms/runtime/QpidJmsRuntimeConfig.java
@@ -43,4 +43,11 @@ public class QpidJmsRuntimeConfig {
*/
@ConfigItem
public Optional password;
+
+ /**
+ * Whether to wrap a ConnectionFactory by ConnectionFactoryWrapper which could be introduced by other extensions,
+ * such as quarkus-pooled-jms to provide pooling capability
+ */
+ @ConfigItem(defaultValue = "false")
+ public boolean wrap;
}