You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2025/08/18 07:31:30 UTC

(camel) branch main updated: CAMEL-22300: add IBM MQ mq test infra (#18918)

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

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


The following commit(s) were added to refs/heads/main by this push:
     new cde6abe34cf CAMEL-22300: add IBM MQ mq test infra (#18918)
cde6abe34cf is described below

commit cde6abe34cf46a35cf68c333cbbdd327f409ce0e
Author: Jono Morris <jo...@apache.org>
AuthorDate: Mon Aug 18 19:31:24 2025 +1200

    CAMEL-22300: add IBM MQ mq test infra (#18918)
    
    * CAMEL-22300 add IBM-MQ test-infra module
    
    * CAMEL-22300 basic tests using jms
    
    * CAMEL-22300 regenerate metadata
---
 .../apache/camel/catalog/test-infra/metadata.json  |   9 ++
 components/camel-jms/pom.xml                       |   8 ++
 .../camel/component/jms/JmsComponentIbmMQTest.java |  74 +++++++++++++
 .../component/jms/issues/JmsReplyToIbmMQTest.java  |  68 ++++++++++++
 parent/pom.xml                                     |   1 +
 test-infra/camel-test-infra-all/pom.xml            |  11 ++
 .../src/generated/resources/META-INF/metadata.json |   9 ++
 test-infra/camel-test-infra-ibmmq/pom.xml          |  64 +++++++++++
 .../ibmmq/common/ConnectionFactoryHelper.java      |  41 ++++++++
 .../test/infra/ibmmq/common/IbmMQProperties.java   |  31 ++++++
 .../infra/ibmmq/services/IbmMQInfraService.java    |  31 ++++++
 .../services/IbmMQLocalContainerInfraService.java  | 117 +++++++++++++++++++++
 .../src/main/resources/META-INF/MANIFEST.MF        |   0
 .../test/infra/ibmmq/services/container.properties |  17 +++
 .../test/infra/ibmmq/services/IbmMQService.java    |  23 ++++
 .../infra/ibmmq/services/IbmMQServiceFactory.java  |  40 +++++++
 test-infra/pom.xml                                 |   1 +
 17 files changed, 545 insertions(+)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
index c2654fce040..f05bee46515 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
@@ -313,6 +313,15 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-infinispan",
   "version" : "4.14.0-SNAPSHOT"
+}, {
+  "service" : "org.apache.camel.test.infra.ibmmq.services.IbmMQInfraService",
+  "description" : "IBM MQ messaging middleware",
+  "implementation" : "org.apache.camel.test.infra.ibmmq.services.IbmMQLocalContainerInfraService",
+  "alias" : [ "ibmmq" ],
+  "aliasImplementation" : [ ],
+  "groupId" : "org.apache.camel",
+  "artifactId" : "camel-test-infra-ibmmq",
+  "version" : "4.14.0-SNAPSHOT"
 }, {
   "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
diff --git a/components/camel-jms/pom.xml b/components/camel-jms/pom.xml
index 074d49983c7..b85217ce843 100644
--- a/components/camel-jms/pom.xml
+++ b/components/camel-jms/pom.xml
@@ -126,6 +126,14 @@
             <type>test-jar</type>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-ibmmq</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+
         <dependency>
             <groupId>org.messaginghub</groupId>
             <artifactId>pooled-jms</artifactId>
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsComponentIbmMQTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsComponentIbmMQTest.java
new file mode 100644
index 00000000000..2c87640cd6f
--- /dev/null
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsComponentIbmMQTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.component.jms;
+
+import jakarta.jms.ConnectionFactory;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.infra.ibmmq.common.ConnectionFactoryHelper;
+import org.apache.camel.test.infra.ibmmq.services.IbmMQService;
+import org.apache.camel.test.infra.ibmmq.services.IbmMQServiceFactory;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.apache.camel.component.jms.JmsComponent.jmsComponentAutoAcknowledge;
+
+public class JmsComponentIbmMQTest extends CamelTestSupport {
+
+    @RegisterExtension
+    public static IbmMQService service = IbmMQServiceFactory.createService();
+
+    @Test
+    public void testSend() throws Exception {
+        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
+        resultEndpoint.expectedMessageCount(1);
+        resultEndpoint.message(0).header("cheese").isEqualTo(123);
+        resultEndpoint.message(0).body().isEqualTo("Hello there!");
+
+        template.sendBodyAndHeader("direct:start", "Hello world", "cheese", 123);
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:start")
+                        .to("jms:queue:DEV.QUEUE.1");
+
+                from("jms:queue:DEV.QUEUE.1")
+                        .process(exchange -> exchange.getIn().setBody("Hello there!"))
+                        .to("mock:result");
+            }
+        };
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext camelContext = super.createCamelContext();
+        ConnectionFactory connectionFactory
+                = ConnectionFactoryHelper.createConnectionFactory(
+                        service.queueManager(), service.channel(), service.listenerPort());
+        camelContext.addComponent("jms", jmsComponentAutoAcknowledge(connectionFactory));
+        return camelContext;
+    }
+}
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsReplyToIbmMQTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsReplyToIbmMQTest.java
new file mode 100644
index 00000000000..6cb21648614
--- /dev/null
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsReplyToIbmMQTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.component.jms.issues;
+
+import jakarta.jms.ConnectionFactory;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.infra.ibmmq.common.ConnectionFactoryHelper;
+import org.apache.camel.test.infra.ibmmq.services.IbmMQService;
+import org.apache.camel.test.infra.ibmmq.services.IbmMQServiceFactory;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.apache.camel.component.jms.JmsComponent.jmsComponentAutoAcknowledge;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class JmsReplyToIbmMQTest extends CamelTestSupport {
+
+    @RegisterExtension
+    public static IbmMQService service = IbmMQServiceFactory.createService();
+
+    @Test
+    public void testCustomJMSReplyToInOut() {
+        template.sendBody("jms:queue:DEV.QUEUE.1", "What is your name?");
+
+        String reply
+                = consumer.receiveBody("jms:queue:DEV.QUEUE.2", 5000, String.class);
+        assertEquals("My name is Camel", reply);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("jms:queue:DEV.QUEUE.1?replyTo=queue:DEV.QUEUE.2")
+                        .to("log:hello")
+                        .transform(constant("My name is Camel"));
+            }
+        };
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext camelContext = super.createCamelContext();
+        ConnectionFactory connectionFactory
+                = ConnectionFactoryHelper.createConnectionFactory(
+                        service.queueManager(), service.channel(), service.listenerPort());
+        camelContext.addComponent("jms", jmsComponentAutoAcknowledge(connectionFactory));
+        return camelContext;
+    }
+}
diff --git a/parent/pom.xml b/parent/pom.xml
index 3acef4fb716..d9f26541904 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -100,6 +100,7 @@
         <chunk-templates-version>3.6.2</chunk-templates-version>
         <classgraph-version>4.8.181</classgraph-version>
         <cloudant-version>0.10.6</cloudant-version>
+        <com-ibm-mq-jakarta-client-version>9.4.3.0</com-ibm-mq-jakarta-client-version>
         <cometd-java-client-version>8.0.9</cometd-java-client-version>
         <cometd-java-server-version>8.0.9</cometd-java-server-version>
         <commons-beanutils-version>1.11.0</commons-beanutils-version>
diff --git a/test-infra/camel-test-infra-all/pom.xml b/test-infra/camel-test-infra-all/pom.xml
index 70826527683..7dfea4c0a87 100644
--- a/test-infra/camel-test-infra-all/pom.xml
+++ b/test-infra/camel-test-infra-all/pom.xml
@@ -236,6 +236,11 @@
             <artifactId>camel-test-infra-hivemq</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-ibmmq</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-test-infra-torchserve</artifactId>
@@ -514,6 +519,12 @@
                                         <artifactId>camel-test-infra-hivemq</artifactId>
                                     </dependency>
                                 </fileSet>
+                                <fileSet>
+                                    <dependency>
+                                        <groupId>org.apache.camel</groupId>
+                                        <artifactId>camel-test-infra-ibmmq</artifactId>
+                                    </dependency>
+                                </fileSet>
                             </fileSets>
                         </configuration>
                     </execution>
diff --git a/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json b/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
index c2654fce040..f05bee46515 100644
--- a/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
+++ b/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
@@ -313,6 +313,15 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-infinispan",
   "version" : "4.14.0-SNAPSHOT"
+}, {
+  "service" : "org.apache.camel.test.infra.ibmmq.services.IbmMQInfraService",
+  "description" : "IBM MQ messaging middleware",
+  "implementation" : "org.apache.camel.test.infra.ibmmq.services.IbmMQLocalContainerInfraService",
+  "alias" : [ "ibmmq" ],
+  "aliasImplementation" : [ ],
+  "groupId" : "org.apache.camel",
+  "artifactId" : "camel-test-infra-ibmmq",
+  "version" : "4.14.0-SNAPSHOT"
 }, {
   "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
diff --git a/test-infra/camel-test-infra-ibmmq/pom.xml b/test-infra/camel-test-infra-ibmmq/pom.xml
new file mode 100644
index 00000000000..3b7bc9ca67a
--- /dev/null
+++ b/test-infra/camel-test-infra-ibmmq/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>camel-test-infra-parent</artifactId>
+        <groupId>org.apache.camel</groupId>
+        <relativePath>../camel-test-infra-parent/pom.xml</relativePath>
+        <version>4.14.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>camel-test-infra-ibmmq</artifactId>
+    <name>Camel :: Test Infra :: IBM MQ</name>
+
+    <properties>
+        <assembly.skipAssembly>false</assembly.skipAssembly>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-common</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-messaging-common</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+        </dependency>
+
+        <dependency>
+            <groupId>com.ibm.mq</groupId>
+            <artifactId>com.ibm.mq.jakarta.client</artifactId>
+            <version>${com-ibm-mq-jakarta-client-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+            <version>${testcontainers-version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/common/ConnectionFactoryHelper.java b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/common/ConnectionFactoryHelper.java
new file mode 100644
index 00000000000..7b60bede616
--- /dev/null
+++ b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/common/ConnectionFactoryHelper.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.test.infra.ibmmq.common;
+
+import jakarta.jms.ConnectionFactory;
+import jakarta.jms.JMSException;
+
+import com.ibm.mq.jakarta.jms.MQConnectionFactory;
+import com.ibm.msg.client.jakarta.wmq.WMQConstants;
+
+public class ConnectionFactoryHelper {
+
+    private ConnectionFactoryHelper() {
+
+    }
+
+    public static ConnectionFactory createConnectionFactory(String queueManager, String channel, int port) throws JMSException {
+        MQConnectionFactory factory = new MQConnectionFactory();
+        factory.setHostName("localhost");
+        factory.setQueueManager(queueManager);
+        factory.setChannel(channel);
+        factory.setPort(port);
+        factory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
+
+        return factory;
+    }
+}
diff --git a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/common/IbmMQProperties.java b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/common/IbmMQProperties.java
new file mode 100644
index 00000000000..662c205784d
--- /dev/null
+++ b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/common/IbmMQProperties.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.test.infra.ibmmq.common;
+
+public class IbmMQProperties {
+    public static final String IBM_MQ_CONTAINER = "ibm.mq.container";
+    public static final String IBM_MQ_CHANNEL = "ibm.mq.channel";
+    public static final String IBM_MQ_QMGR_NAME = "ibm.mq.qmgr.name";
+    public static final String IBM_MQ_PORT = "ibm.mq.port";
+
+    public static final String DEFAULT_QMGR_NAME = "QM1";
+    public static final String DEFAULT_CHANNEL = "DEV.APP.SVRCONN";
+
+    private IbmMQProperties() {
+
+    }
+}
diff --git a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java
new file mode 100644
index 00000000000..82472f2f83a
--- /dev/null
+++ b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.test.infra.ibmmq.services;
+
+import org.apache.camel.test.infra.common.services.InfrastructureService;
+
+/**
+ * Test infra service for IBM MQ.
+ */
+public interface IbmMQInfraService extends InfrastructureService {
+
+    String channel();
+
+    String queueManager();
+
+    int listenerPort();
+}
diff --git a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java
new file mode 100644
index 00000000000..c7cd13c60f4
--- /dev/null
+++ b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.test.infra.ibmmq.services;
+
+import org.apache.camel.spi.annotations.InfraService;
+import org.apache.camel.test.infra.common.LocalPropertyResolver;
+import org.apache.camel.test.infra.common.services.ContainerService;
+import org.apache.camel.test.infra.ibmmq.common.IbmMQProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+import org.testcontainers.containers.wait.strategy.Wait;
+import org.testcontainers.utility.DockerImageName;
+
+@InfraService(service = IbmMQInfraService.class,
+              description = "IBM MQ messaging middleware",
+              serviceAlias = "ibmmq")
+public class IbmMQLocalContainerInfraService implements IbmMQInfraService, ContainerService<GenericContainer<?>> {
+
+    public static final String CONTAINER_NAME = "ibmmq";
+    public static final int MQ_LISTENER_PORT = 1414;
+    public static final int WEB_CONSOLE_PORT = 9443;
+
+    private static final Logger LOG = LoggerFactory.getLogger(IbmMQLocalContainerInfraService.class);
+
+    private final GenericContainer<?> container;
+
+    public IbmMQLocalContainerInfraService() {
+        this(LocalPropertyResolver.getProperty(
+                IbmMQLocalContainerInfraService.class, IbmMQProperties.IBM_MQ_CONTAINER));
+    }
+
+    public IbmMQLocalContainerInfraService(String containerImage) {
+        container = initContainer(containerImage);
+    }
+
+    protected GenericContainer<?> initContainer(String imageName) {
+
+        class IbmMQContainer extends GenericContainer<IbmMQContainer> {
+            public IbmMQContainer() {
+                super(DockerImageName.parse(imageName));
+
+                withNetworkAliases(CONTAINER_NAME)
+                        .withEnv("LICENSE", "accept")
+                        .withEnv("MQ_QMGR_NAME", IbmMQProperties.DEFAULT_QMGR_NAME)
+                        .withLogConsumer(new Slf4jLogConsumer(LOG))
+                        .waitingFor(Wait.forLogMessage(
+                                ".*Queued Publish/Subscribe Daemon started for queue manager.*", 1));
+
+                addFixedExposedPort(MQ_LISTENER_PORT, MQ_LISTENER_PORT);
+                addFixedExposedPort(WEB_CONSOLE_PORT, WEB_CONSOLE_PORT);
+            }
+        }
+        return new IbmMQContainer();
+    }
+
+    @Override
+    public void registerProperties() {
+        System.setProperty(IbmMQProperties.IBM_MQ_CHANNEL, channel());
+        System.setProperty(IbmMQProperties.IBM_MQ_QMGR_NAME, queueManager());
+        System.setProperty(IbmMQProperties.IBM_MQ_PORT, String.valueOf(listenerPort()));
+    }
+
+    @Override
+    public void initialize() {
+        LOG.info("Trying to start the IBM MQ container");
+        container.withStartupAttempts(5);
+
+        // also starts admin console on https://localhost:9443/ibmmq/console, user: admin, password: passw0rd
+        container.start();
+        registerProperties();
+    }
+
+    @Override
+    public void shutdown() {
+        LOG.info("Stopping the IBM MQ container");
+        container.stop();
+        System.clearProperty(IbmMQProperties.IBM_MQ_CHANNEL);
+        System.clearProperty(IbmMQProperties.IBM_MQ_QMGR_NAME);
+        System.clearProperty(IbmMQProperties.IBM_MQ_PORT);
+    }
+
+    @Override
+    public GenericContainer<?> getContainer() {
+        return container;
+    }
+
+    @Override
+    public String channel() {
+        return IbmMQProperties.DEFAULT_CHANNEL;
+    }
+
+    @Override
+    public String queueManager() {
+        return IbmMQProperties.DEFAULT_QMGR_NAME;
+    }
+
+    @Override
+    public int listenerPort() {
+        return MQ_LISTENER_PORT;
+    }
+}
diff --git a/test-infra/camel-test-infra-ibmmq/src/main/resources/META-INF/MANIFEST.MF b/test-infra/camel-test-infra-ibmmq/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/test-infra/camel-test-infra-ibmmq/src/main/resources/org/apache/camel/test/infra/ibmmq/services/container.properties b/test-infra/camel-test-infra-ibmmq/src/main/resources/org/apache/camel/test/infra/ibmmq/services/container.properties
new file mode 100644
index 00000000000..b6112d35d62
--- /dev/null
+++ b/test-infra/camel-test-infra-ibmmq/src/main/resources/org/apache/camel/test/infra/ibmmq/services/container.properties
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You 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.
+## ---------------------------------------------------------------------------
+ibm.mq.container=icr.io/ibm-messaging/mq:9.3.2.0-r2
\ No newline at end of file
diff --git a/test-infra/camel-test-infra-ibmmq/src/test/java/org/apache/camel/test/infra/ibmmq/services/IbmMQService.java b/test-infra/camel-test-infra-ibmmq/src/test/java/org/apache/camel/test/infra/ibmmq/services/IbmMQService.java
new file mode 100644
index 00000000000..590e8dd0d17
--- /dev/null
+++ b/test-infra/camel-test-infra-ibmmq/src/test/java/org/apache/camel/test/infra/ibmmq/services/IbmMQService.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.test.infra.ibmmq.services;
+
+import org.apache.camel.test.infra.common.services.ContainerTestService;
+import org.apache.camel.test.infra.common.services.TestService;
+
+public interface IbmMQService extends TestService, IbmMQInfraService, ContainerTestService {
+}
diff --git a/test-infra/camel-test-infra-ibmmq/src/test/java/org/apache/camel/test/infra/ibmmq/services/IbmMQServiceFactory.java b/test-infra/camel-test-infra-ibmmq/src/test/java/org/apache/camel/test/infra/ibmmq/services/IbmMQServiceFactory.java
new file mode 100644
index 00000000000..f3043328dfd
--- /dev/null
+++ b/test-infra/camel-test-infra-ibmmq/src/test/java/org/apache/camel/test/infra/ibmmq/services/IbmMQServiceFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.test.infra.ibmmq.services;
+
+import org.apache.camel.test.infra.common.services.SimpleTestServiceBuilder;
+
+public class IbmMQServiceFactory {
+
+    private IbmMQServiceFactory() {
+
+    }
+
+    public static SimpleTestServiceBuilder<IbmMQService> builder() {
+        return new SimpleTestServiceBuilder<>("ibm-mq");
+    }
+
+    public static IbmMQService createService() {
+        return builder()
+                .addLocalMapping(IbmMQLocalContainerService::new)
+                .build();
+    }
+
+    public static class IbmMQLocalContainerService extends IbmMQLocalContainerInfraService
+            implements IbmMQService {
+    }
+}
diff --git a/test-infra/pom.xml b/test-infra/pom.xml
index 22adcb199a5..b6b885ed7b9 100644
--- a/test-infra/pom.xml
+++ b/test-infra/pom.xml
@@ -93,6 +93,7 @@
         <module>camel-test-infra-triton</module>
         <module>camel-test-infra-neo4j</module>
         <module>camel-test-infra-weaviate</module>
+        <module>camel-test-infra-ibmmq</module>
         <module>camel-test-infra-all</module>
     </modules>