This is an automated email from the ASF dual-hosted git repository. zhfeng 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 42e498b495 [IBM-MQ] Add tests for IBM MQ client (#4918) 42e498b495 is described below commit 42e498b4951ab59fd86e1a7b82115ac08b668f9f Author: Andrej Vaňo <av...@redhat.com> AuthorDate: Fri May 26 15:18:00 2023 +0200 [IBM-MQ] Add tests for IBM MQ client (#4918) --- .../jms/artemis/it/JmsArtemisResource.java | 10 ++ .../component/jms/artemis/it/JmsArtemisXATest.java | 10 ++ integration-tests/jms-ibmmq-client/README.adoc | 7 + integration-tests/jms-ibmmq-client/pom.xml | 168 +++++++++++++++++++++ .../component/jms/ibmmq/it/IBMMQProducers.java | 44 ++++++ .../component/jms/ibmmq/it/IBMMQResource.java} | 48 +----- .../quarkus/component/jms/ibmmq/it/IBMMQTest.java | 88 +++++++++++ .../jms/ibmmq/support/IBMMQDestinations.java | 109 +++++++++++++ .../jms/ibmmq/support/IBMMQTestResource.java | 98 ++++++++++++ .../messaging/it/MessagingCommonResource.java | 53 ++++--- .../messaging/it/MessagingCommonRoutes.java | 38 +++-- .../messaging/it/MessagingPojoConsumer.java | 4 +- .../messaging/it/AbstractMessagingTest.java | 49 ++++-- .../camel/quarkus/messaging/jms/JmsProducers.java | 2 +- .../camel/quarkus/messaging/jms/JmsResource.java | 32 ++-- .../camel/quarkus/messaging/jms/JmsRoutes.java | 4 +- .../messaging/jms/AbstractJmsMessagingTest.java | 18 +-- integration-tests/pom.xml | 4 +- pom.xml | 1 + poms/bom-test/pom.xml | 1 - poms/bom/pom.xml | 6 + poms/bom/src/main/generated/flattened-full-pom.xml | 5 + .../src/main/generated/flattened-reduced-pom.xml | 5 + .../generated/flattened-reduced-verbose-pom.xml | 5 + tooling/scripts/test-categories.yaml | 1 + 25 files changed, 686 insertions(+), 124 deletions(-) diff --git a/integration-tests/jms-artemis-client/src/main/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisResource.java b/integration-tests/jms-artemis-client/src/main/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisResource.java index 1febd96ecc..5e3cb0dcdb 100644 --- a/integration-tests/jms-artemis-client/src/main/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisResource.java +++ b/integration-tests/jms-artemis-client/src/main/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisResource.java @@ -88,4 +88,14 @@ public class JmsArtemisResource { private boolean isValid(String message) { return !message.startsWith("fail"); } + + @Path("/routes/start") + @GET + public void startRoutes() { + try { + context.getRouteController().startAllRoutes(); + } catch (Exception e) { + throw new RuntimeException("Unable to start camel routes", e); + } + } } diff --git a/integration-tests/jms-artemis-client/src/test/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisXATest.java b/integration-tests/jms-artemis-client/src/test/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisXATest.java index 03391d9f70..2c7cc28148 100644 --- a/integration-tests/jms-artemis-client/src/test/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisXATest.java +++ b/integration-tests/jms-artemis-client/src/test/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisXATest.java @@ -19,6 +19,8 @@ package org.apache.camel.quarkus.component.jms.artemis.it; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.TestProfile; import io.restassured.RestAssured; +import org.eclipse.microprofile.config.ConfigProvider; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import static org.hamcrest.core.Is.is; @@ -26,6 +28,14 @@ import static org.hamcrest.core.Is.is; @QuarkusTest @TestProfile(JmsArtemisXAEnabled.class) public class JmsArtemisXATest { + @BeforeAll + public static void startRoutes() { + RestAssured.given() + // see AbstractMessagingTest#beforeAll + .port(ConfigProvider.getConfig().getValue("quarkus.http.test-port", Integer.class)) + .get("/messaging/jms/artemis/routes/start"); + } + @Test public void testJmsXACommit() { RestAssured.given() diff --git a/integration-tests/jms-ibmmq-client/README.adoc b/integration-tests/jms-ibmmq-client/README.adoc new file mode 100644 index 0000000000..9d676583c6 --- /dev/null +++ b/integration-tests/jms-ibmmq-client/README.adoc @@ -0,0 +1,7 @@ +== Running the tests + +To run the tests, you need to accept the license from the official docker image for IBM MQ. + +You can run `docker run -e LICENSE=view icr.io/ibm-messaging/mq:9.3.2.1-r1` to view the license. + +If you accept the license and want to run the tests, use `-Dibm.mq.container.license=accept` property. diff --git a/integration-tests/jms-ibmmq-client/pom.xml b/integration-tests/jms-ibmmq-client/pom.xml new file mode 100644 index 0000000000..6b2861773e --- /dev/null +++ b/integration-tests/jms-ibmmq-client/pom.xml @@ -0,0 +1,168 @@ +<?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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-build-parent-it</artifactId> + <version>3.0.0-SNAPSHOT</version> + <relativePath>../../poms/build-parent-it/pom.xml</relativePath> + </parent> + + <artifactId>camel-quarkus-integration-test-jms-ibmmq-client</artifactId> + <name>Camel Quarkus :: Integration Tests :: JMS IBM MQ Client</name> + <description>Integration tests for Camel Quarkus JMS extension with the IBM MQ Client</description> + + <properties> + </properties> + + <dependencies> + <!-- Messaging extension to test --> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-jms</artifactId> + </dependency> + + <!-- Inherit base messaging routes --> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-integration-test-messaging-jms</artifactId> + </dependency> + + <!-- The JMS client library to test with --> + <dependency> + <groupId>com.ibm.mq</groupId> + <artifactId>com.ibm.mq.jakarta.client</artifactId> + <scope>provided</scope> + </dependency> + + <!-- test dependencies --> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-junit5</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>io.rest-assured</groupId> + <artifactId>rest-assured</artifactId> + <scope>test</scope> + </dependency> + + <!-- IBM MQ Test Resource --> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>testcontainers</artifactId> + <exclusions> + <exclusion> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </exclusion> + </exclusions> + <scope>test</scope> + </dependency> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-junit4-mock</artifactId> + <scope>test</scope> + </dependency> + <!-- Inherit base messaging tests --> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-integration-test-messaging-common</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-integration-test-messaging-jms</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + + </dependencies> + + <profiles> + <!-- IBM MQ client does not work in native: https://github.com/apache/camel-quarkus/issues/4924 + <profile> + <id>native</id> + <activation> + <property> + <name>native</name> + </property> + </activation> + <properties> + <quarkus.package.type>native</quarkus.package.type> + </properties> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>integration-test</goal> + <goal>verify</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + --> + <profile> + <id>virtualDependencies</id> + <activation> + <property> + <name>!noVirtualDependencies</name> + </property> + </activation> + <dependencies> + <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory --> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-jms-deployment</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + </profile> + <profile> + <id>skip-testcontainers-tests</id> + <activation> + <property> + <name>skip-testcontainers-tests</name> + </property> + </activation> + <properties> + <skipTests>true</skipTests> + </properties> + </profile> + </profiles> +</project> diff --git a/integration-tests/jms-ibmmq-client/src/main/java/org/apache/camel/quarkus/component/jms/ibmmq/it/IBMMQProducers.java b/integration-tests/jms-ibmmq-client/src/main/java/org/apache/camel/quarkus/component/jms/ibmmq/it/IBMMQProducers.java new file mode 100644 index 0000000000..45b246ea69 --- /dev/null +++ b/integration-tests/jms-ibmmq-client/src/main/java/org/apache/camel/quarkus/component/jms/ibmmq/it/IBMMQProducers.java @@ -0,0 +1,44 @@ +/* + * 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.quarkus.component.jms.ibmmq.it; + +import com.ibm.mq.jakarta.jms.MQConnectionFactory; +import com.ibm.msg.client.jakarta.wmq.WMQConstants; +import jakarta.enterprise.inject.Produces; +import jakarta.jms.ConnectionFactory; +import org.eclipse.microprofile.config.ConfigProvider; + +public class IBMMQProducers { + @Produces + ConnectionFactory createConnectionFactory() { + MQConnectionFactory connectionFactory = new MQConnectionFactory(); + connectionFactory.setHostName(ConfigProvider.getConfig().getValue("ibm.mq.host", String.class)); + try { + connectionFactory.setPort(ConfigProvider.getConfig().getValue("ibm.mq.port", Integer.class)); + connectionFactory.setChannel(ConfigProvider.getConfig().getValue("ibm.mq.channel", String.class)); + connectionFactory.setQueueManager(ConfigProvider.getConfig().getValue("ibm.mq.queueManagerName", String.class)); + connectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT); + connectionFactory.setStringProperty(WMQConstants.USERID, + ConfigProvider.getConfig().getValue("ibm.mq.user", String.class)); + connectionFactory.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 connectionFactory; + } +} diff --git a/integration-tests/jms-artemis-client/src/main/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisResource.java b/integration-tests/jms-ibmmq-client/src/main/java/org/apache/camel/quarkus/component/jms/ibmmq/it/IBMMQResource.java similarity index 55% copy from integration-tests/jms-artemis-client/src/main/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisResource.java copy to integration-tests/jms-ibmmq-client/src/main/java/org/apache/camel/quarkus/component/jms/ibmmq/it/IBMMQResource.java index 1febd96ecc..0fc99e0495 100644 --- a/integration-tests/jms-artemis-client/src/main/java/org/apache/camel/quarkus/component/jms/artemis/it/JmsArtemisResource.java +++ b/integration-tests/jms-ibmmq-client/src/main/java/org/apache/camel/quarkus/component/jms/ibmmq/it/IBMMQResource.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.quarkus.component.jms.artemis.it; +package org.apache.camel.quarkus.component.jms.ibmmq.it; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -24,28 +24,18 @@ import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; -import org.apache.camel.CamelContext; -import org.apache.camel.CamelExecutionException; import org.apache.camel.Produce; import org.apache.camel.ProducerTemplate; -import org.apache.camel.component.mock.MockEndpoint; @ApplicationScoped -@Path("/messaging/jms/artemis") -public class JmsArtemisResource { - +@Path("/messaging/jms/ibmmq") +public class IBMMQResource { @Inject ConnectionFactory connectionFactory; - @Produce("jms:queue:pojoProduce") + @Produce("jms:queue:testPojoProducer") ProducerTemplate pojoProducer; - @Inject - CamelContext context; - - @Inject - ProducerTemplate producerTemplate; - @GET @Path("/connection/factory") @Produces(MediaType.TEXT_PLAIN) @@ -58,34 +48,4 @@ public class JmsArtemisResource { public void pojoProducer(String message) { pojoProducer.sendBody(message); } - - @POST - @Path("/xa") - public String testXA(String message) throws Exception { - MockEndpoint mockEndpoint = context.getEndpoint("mock:xaResult", MockEndpoint.class); - - mockEndpoint.reset(); - if (isValid(message)) { - mockEndpoint.expectedMessageCount(1); - } else { - mockEndpoint.expectedMessageCount(0); - } - - try { - producerTemplate.sendBody("direct:xa", message); - } catch (CamelExecutionException e) { - // ignore the exception and we will check the mock:xaResult - } - mockEndpoint.assertIsSatisfied(5000); - - if (isValid(message)) { - return mockEndpoint.getExchanges().get(0).getIn().getBody(String.class); - } else { - return "rollback"; - } - } - - private boolean isValid(String message) { - return !message.startsWith("fail"); - } } diff --git a/integration-tests/jms-ibmmq-client/src/test/java/org/apache/camel/quarkus/component/jms/ibmmq/it/IBMMQTest.java b/integration-tests/jms-ibmmq-client/src/test/java/org/apache/camel/quarkus/component/jms/ibmmq/it/IBMMQTest.java new file mode 100644 index 0000000000..eb81e9e3d1 --- /dev/null +++ b/integration-tests/jms-ibmmq-client/src/test/java/org/apache/camel/quarkus/component/jms/ibmmq/it/IBMMQTest.java @@ -0,0 +1,88 @@ +/* + * 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.quarkus.component.jms.ibmmq.it; + +import java.lang.reflect.Method; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.RestAssured; +import org.apache.camel.quarkus.component.jms.ibmmq.support.IBMMQDestinations; +import org.apache.camel.quarkus.component.jms.ibmmq.support.IBMMQTestResource; +import org.apache.camel.quarkus.messaging.jms.AbstractJmsMessagingTest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.condition.EnabledIfSystemProperty; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.startsWith; + +@QuarkusTest +@QuarkusTestResource(IBMMQTestResource.class) +@EnabledIfSystemProperty(named = "ibm.mq.container.license", matches = "accept") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class IBMMQTest extends AbstractJmsMessagingTest { + private IBMMQDestinations destinations; + + /** + * IBM MQ needs to have the destinations created before you can use them. + * <p> + * This method is called after the routes start, so the routes will print a warning first that the destinations don't + * exist, only then they are + * created using this method + * + * @param test test + */ + @BeforeAll + @Override + public void startRoutes(TestInfo test) { + for (Method method : test.getTestClass().get().getMethods()) { + destinations.createQueue(method.getName()); + // Some tests use two queues + destinations.createQueue(method.getName() + "2"); + destinations.createTopic(method.getName()); + } + + super.startRoutes(test); + } + + @Test + public void connectionFactoryImplementation() { + RestAssured.get("/messaging/jms/ibmmq/connection/factory") + .then() + .statusCode(200) + .body(startsWith("com.ibm.mq")); + } + + @Test + public void testPojoProducer() { + String message = "Camel Quarkus IBM MQ Pojo Producer"; + + RestAssured.given() + .body(message) + .post("/messaging/jms/ibmmq/pojo/producer") + .then() + .statusCode(204); + + RestAssured.get("/messaging/{queueName}", queue) + .then() + .statusCode(200) + .body(is(message)); + } +} diff --git a/integration-tests/jms-ibmmq-client/src/test/java/org/apache/camel/quarkus/component/jms/ibmmq/support/IBMMQDestinations.java b/integration-tests/jms-ibmmq-client/src/test/java/org/apache/camel/quarkus/component/jms/ibmmq/support/IBMMQDestinations.java new file mode 100644 index 0000000000..3de1994259 --- /dev/null +++ b/integration-tests/jms-ibmmq-client/src/test/java/org/apache/camel/quarkus/component/jms/ibmmq/support/IBMMQDestinations.java @@ -0,0 +1,109 @@ +/* + * 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.quarkus.component.jms.ibmmq.support; + +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Set; + +import com.ibm.mq.MQException; +import com.ibm.mq.MQQueueManager; +import com.ibm.mq.constants.MQConstants; +import com.ibm.mq.headers.MQDataException; +import com.ibm.mq.headers.pcf.PCFMessage; +import com.ibm.mq.headers.pcf.PCFMessageAgent; + +/** + * Before using the destinations in IBM MQ, it is needed to create them. + */ +public class IBMMQDestinations { + private static final String ADMIN_USER = "admin"; + private static final String ADMIN_PASSWORD = "passw0rd"; + private static final String ADMIN_CHANNEL = "DEV.ADMIN.SVRCONN"; + + private final String host; + private final int port; + private final String queueManagerName; + + private final PCFMessageAgent agent; + // The destination can be created only once, otherwise the request will fail + private final Set<String> createdQueues = new HashSet<>(); + private final Set<String> createdTopics = new HashSet<>(); + + public IBMMQDestinations(String host, int port, String queueManagerName) { + this.host = host; + this.port = port; + this.queueManagerName = queueManagerName; + + // Disable creating log files for client + System.setProperty("com.ibm.msg.client.commonservices.log.status", "OFF"); + + agent = createPCFAgent(); + } + + private MQQueueManager createQueueManager() { + Hashtable<String, Object> properties = new Hashtable<>(); + properties.put(MQConstants.HOST_NAME_PROPERTY, host); + properties.put(MQConstants.PORT_PROPERTY, port); + properties.put(MQConstants.CHANNEL_PROPERTY, ADMIN_CHANNEL); + properties.put(MQConstants.USE_MQCSP_AUTHENTICATION_PROPERTY, true); + properties.put(MQConstants.USER_ID_PROPERTY, ADMIN_USER); + properties.put(MQConstants.PASSWORD_PROPERTY, ADMIN_PASSWORD); + try { + return new MQQueueManager(queueManagerName, properties); + } catch (MQException e) { + throw new RuntimeException("Unable to create MQQueueManager:", e); + } + } + + private PCFMessageAgent createPCFAgent() { + try { + return new PCFMessageAgent(createQueueManager()); + } catch (MQDataException e) { + throw new RuntimeException("Unable to create PCFMessageAgent:", e); + } + } + + private void sendRequest(PCFMessage request) { + try { + agent.send(request); + } catch (Exception e) { + throw new RuntimeException("Unable to send PCFMessage:", e); + } + } + + public void createQueue(String queueName) { + if (!createdQueues.contains(queueName)) { + PCFMessage request = new PCFMessage(MQConstants.MQCMD_CREATE_Q); + request.addParameter(MQConstants.MQCA_Q_NAME, queueName); + request.addParameter(MQConstants.MQIA_Q_TYPE, MQConstants.MQQT_LOCAL); + sendRequest(request); + createdQueues.add(queueName); + } + } + + public void createTopic(String topicName) { + if (!createdTopics.contains(topicName)) { + PCFMessage request = new PCFMessage(MQConstants.MQCMD_CREATE_TOPIC); + request.addParameter(MQConstants.MQCA_TOPIC_NAME, topicName); + request.addParameter(MQConstants.MQCA_TOPIC_STRING, topicName); + request.addParameter(MQConstants.MQIA_TOPIC_TYPE, MQConstants.MQTOPT_LOCAL); + sendRequest(request); + createdTopics.add(topicName); + } + } +} diff --git a/integration-tests/jms-ibmmq-client/src/test/java/org/apache/camel/quarkus/component/jms/ibmmq/support/IBMMQTestResource.java b/integration-tests/jms-ibmmq-client/src/test/java/org/apache/camel/quarkus/component/jms/ibmmq/support/IBMMQTestResource.java new file mode 100644 index 0000000000..37a580f9c0 --- /dev/null +++ b/integration-tests/jms-ibmmq-client/src/test/java/org/apache/camel/quarkus/component/jms/ibmmq/support/IBMMQTestResource.java @@ -0,0 +1,98 @@ +/* + * 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.quarkus.component.jms.ibmmq.support; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Map; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import org.apache.commons.io.FileUtils; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; + +public class IBMMQTestResource implements QuarkusTestResourceLifecycleManager { + private static final String IMAGE_NAME = System.getProperty("ibm.mq.container.image", "icr.io/ibm-messaging/mq:9.3.2.1-r1"); + private static final int PORT = 1414; + private static final String QUEUE_MANAGER_NAME = "QM1"; + private static final String USER = "app"; + private static final String PASSWORD = "passw0rd"; + private static final String MESSAGING_CHANNEL = "DEV.APP.SVRCONN"; + private static final String MQSC_COMMAND_FILE_NAME = "99-auth.mqsc"; + private static final String MQSC_FILE = "target/" + MQSC_COMMAND_FILE_NAME; + private static final String MQSC_FILE_CONTAINER_PATH = "/etc/mqm/" + MQSC_COMMAND_FILE_NAME; + + private GenericContainer<?> container; + private IBMMQDestinations destinations; + + @Override + public Map<String, String> start() { + container = new GenericContainer<>(DockerImageName.parse(IMAGE_NAME)) + .withExposedPorts(PORT) + .withEnv(Map.of( + "LICENSE", System.getProperty("ibm.mq.container.license"), + "MQ_QMGR_NAME", QUEUE_MANAGER_NAME, + "MQ_APP_PASSWORD", PASSWORD)) + .withFileSystemBind(mqscConfig(), MQSC_FILE_CONTAINER_PATH) + // AMQ5806I is a message code for queue manager start + .waitingFor(Wait.forLogMessage(".*AMQ5806I.*", 1)); + container.start(); + + destinations = new IBMMQDestinations(container.getHost(), container.getMappedPort(PORT), QUEUE_MANAGER_NAME); + + return Map.of( + "ibm.mq.host", container.getHost(), + "ibm.mq.port", container.getMappedPort(PORT).toString(), + "ibm.mq.user", USER, + "ibm.mq.password", PASSWORD, + "ibm.mq.queueManagerName", QUEUE_MANAGER_NAME, + "ibm.mq.channel", MESSAGING_CHANNEL); + } + + @Override + public void stop() { + if (container != null) { + container.stop(); + } + } + + @Override + public void inject(TestInjector testInjector) { + testInjector.injectIntoFields(destinations, new TestInjector.MatchesType(IBMMQDestinations.class)); + } + + /** + * By default the user does have access just to predefined queues, this will add permissions to access + * all standard queues + topics and a special system queue. + * + * @return mqsc config string + */ + private String mqscConfig() { + final String content = "SET AUTHREC PROFILE('*') PRINCIPAL('" + USER + "') OBJTYPE(TOPIC) AUTHADD(ALL)\n" + + "SET AUTHREC PROFILE('*') PRINCIPAL('" + USER + "') OBJTYPE(QUEUE) AUTHADD(ALL)\n" + + "SET AUTHREC PROFILE('SYSTEM.DEFAULT.MODEL.QUEUE') OBJTYPE(QUEUE) PRINCIPAL('" + USER + "') AUTHADD(ALL)"; + File targetFile = new File(MQSC_FILE); + try { + FileUtils.writeStringToFile(targetFile, content, Charset.defaultCharset()); + } catch (IOException e) { + throw new RuntimeException("Unable to write to file", e); + } + return targetFile.getAbsolutePath(); + } +} diff --git a/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingCommonResource.java b/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingCommonResource.java index 6960c1853c..3b559b6ed0 100644 --- a/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingCommonResource.java +++ b/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingCommonResource.java @@ -88,11 +88,12 @@ public class MessagingCommonResource { return Response.created(new URI("https://camel.apache.org/")).build(); } - @Path("/type/{type}") + @Path("{queueName}/type/{type}") @POST @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.TEXT_PLAIN) - public Response jmsMessageType(@PathParam("type") String type, String messageBody) throws Exception { + public Response jmsMessageType(@PathParam("queueName") String queueName, @PathParam("type") String type, String messageBody) + throws Exception { MockEndpoint mockEndpoint = context.getEndpoint("mock:jmsType", MockEndpoint.class); mockEndpoint.reset(); mockEndpoint.expectedMessageCount(1); @@ -121,7 +122,7 @@ public class MessagingCommonResource { throw new IllegalArgumentException("Unknown type: " + type); } - producerTemplate.sendBody(componentScheme + ":queue:typeTest", payload); + producerTemplate.sendBody(componentScheme + ":queue:" + queueName, payload); mockEndpoint.assertIsSatisfied(5000); @@ -129,7 +130,7 @@ public class MessagingCommonResource { jakarta.jms.Message message = messageResolver.resolve(exchange); Object result; - if (type.equals("string") || type.equals("node")) { + if ("string".equals(type) || "node".equals(type)) { assert message instanceof jakarta.jms.TextMessage; TextMessage textMessage = (TextMessage) message; result = textMessage.getText(); @@ -146,16 +147,16 @@ public class MessagingCommonResource { return Response.ok().entity(result).build(); } - @Path("/map") + @Path("/{queueName}/map") @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SuppressWarnings("unchecked") - public Response jmsMapMessage(Map<String, String> payload) throws Exception { + public Response jmsMapMessage(@PathParam("queueName") String queueName, Map<String, String> payload) throws Exception { MockEndpoint mockEndpoint = context.getEndpoint("mock:mapResult", MockEndpoint.class); mockEndpoint.expectedMessageCount(1); - producerTemplate.sendBody(componentScheme + ":queue:mapTest", payload); + producerTemplate.sendBody(componentScheme + ":queue:" + queueName, payload); mockEndpoint.assertIsSatisfied(5000); @@ -172,26 +173,26 @@ public class MessagingCommonResource { return Response.ok().entity(result).build(); } - @Path("/selector/{expression}") + @Path("{queueName}/selector/{expression}") @GET @Produces(MediaType.TEXT_PLAIN) - public String jmsSelector(@PathParam("expression") String expression) { - producerTemplate.sendBodyAndHeader(componentScheme + ":queue:selectorA", + public String jmsSelector(@PathParam("queueName") String queueName, @PathParam("expression") String expression) { + producerTemplate.sendBodyAndHeader(componentScheme + ":queue:" + queueName, "Camel JMS Selector Not Matched", "foo", "baz"); - producerTemplate.sendBodyAndHeader(componentScheme + ":queue:selectorA", + producerTemplate.sendBodyAndHeader(componentScheme + ":queue:" + queueName, "Camel JMS Selector Match", "foo", "bar"); return consumerTemplate.receiveBody( - componentScheme + ":selectorB?selector=" + expression, 5000, + componentScheme + ":" + queueName + "2?selector=" + expression, 5000, String.class); } - @Path("/transaction") + @Path("/{queueName}/transaction") @GET @Produces(MediaType.TEXT_PLAIN) - public Response jmsTransaction() throws Exception { + public Response jmsTransaction(@PathParam("queueName") String queueName) throws Exception { MockEndpoint mockEndpoint = context.getEndpoint("mock:txResult", MockEndpoint.class); mockEndpoint.expectedMessageCount(1); @@ -200,7 +201,7 @@ public class MessagingCommonResource { mockEndpoint.message(0).header(Exchange.REDELIVERY_COUNTER).isEqualTo(2); mockEndpoint.message(0).header("JMSRedelivered").isEqualTo(false); - producerTemplate.sendBody(componentScheme + ":queue:txTest?transacted=true", + producerTemplate.sendBody(componentScheme + ":queue:" + queueName + "?transacted=true", "Test JMS Transaction"); mockEndpoint.assertIsSatisfied(5000); @@ -211,15 +212,15 @@ public class MessagingCommonResource { return Response.ok().entity(message.getBody()).build(); } - @Path("/object") + @Path("/{queueName}/object") @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.TEXT_PLAIN) @POST - public Response testObjectMessage(String name) throws InterruptedException { + public Response testObjectMessage(@PathParam("queueName") String queueName, String name) throws InterruptedException { MockEndpoint mockEndpoint = context.getEndpoint("mock:objectTestResult", MockEndpoint.class); mockEndpoint.expectedMessageCount(1); - producerTemplate.sendBody(componentScheme + ":queue:objectTest", new Person(name)); + producerTemplate.sendBody(componentScheme + ":queue:" + queueName, new Person(name)); mockEndpoint.assertIsSatisfied(); @@ -230,17 +231,17 @@ public class MessagingCommonResource { return Response.ok().entity(body.getName()).build(); } - @Path("/topic") + @Path("/topic/{topicName}") @Consumes(MediaType.TEXT_PLAIN) @POST - public void topicPubSub(String message) throws Exception { + public void topicPubSub(@PathParam("topicName") String topicName, String message) throws Exception { MockEndpoint topicResultA = context.getEndpoint("mock:topicResultA", MockEndpoint.class); topicResultA.expectedBodiesReceived(message); MockEndpoint topicResultB = context.getEndpoint("mock:topicResultB", MockEndpoint.class); topicResultB.expectedBodiesReceived(message); - producerTemplate.sendBody(componentScheme + ":topic:test", message); + producerTemplate.sendBody(componentScheme + ":topic:" + topicName, message); topicResultA.assertIsSatisfied(5000); topicResultB.assertIsSatisfied(5000); @@ -285,4 +286,14 @@ public class MessagingCommonResource { public String pojoConsumer() { return pojoConsumer.getMessage(5000); } + + @Path("/routes/start") + @GET + public void startRoutes() { + try { + context.getRouteController().startAllRoutes(); + } catch (Exception e) { + throw new RuntimeException("Unable to start camel routes", e); + } + } } diff --git a/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingCommonRoutes.java b/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingCommonRoutes.java index c5567f8153..084aa8b12d 100644 --- a/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingCommonRoutes.java +++ b/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingCommonRoutes.java @@ -19,6 +19,7 @@ package org.apache.camel.quarkus.component.messaging.it; import io.quarkus.runtime.annotations.RegisterForReflection; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; +import org.apache.camel.CamelContext; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.builder.RouteBuilder; @@ -31,28 +32,36 @@ public class MessagingCommonRoutes extends RouteBuilder { @Inject ComponentScheme componentScheme; + @Inject + CamelContext camelContext; + @Override public void configure() throws Exception { - fromF("%s:queue:typeTest?concurrentConsumers=5", componentScheme) - .toF("%s:queue:typeTestResult", componentScheme); + // Don't start the routes by default, for IBM MQ it is needed to create the destinations beforehand + // The routes are later started in AbstractMessagingTest#beforeAll method + camelContext.setAutoStartup(false); + + fromF("%s:queue:testJmsMessageType?concurrentConsumers=5", componentScheme) + .toF("%s:queue:testJmsMessageType2", componentScheme); String disableStreaming = ""; if (isDisableStreaming()) { disableStreaming = "artemisStreamingEnabled=false"; } - fromF("%s:queue:typeTestResult?%s", componentScheme, disableStreaming) + fromF("%s:queue:testJmsMessageType2?%s", componentScheme, disableStreaming) .to("mock:jmsType"); // Map message type routes - fromF("%s:queue:mapTest", componentScheme) + fromF("%s:queue:testJmsMapMessage", componentScheme) + .id("hello") .to("mock:mapResult"); // JMS selector routes - fromF("%s:queue:selectorA", componentScheme) - .toF("%s:queue:selectorB", componentScheme); + fromF("%s:queue:testJmsSelector", componentScheme) + .toF("%s:queue:testJmsSelector2", componentScheme); // JMS transaction tests - fromF("%s:queue:txTest?transacted=true", componentScheme) + fromF("%s:queue:testJmsTransaction?transacted=true", componentScheme) .errorHandler(jtaTransactionErrorHandler().maximumRedeliveries(4)) .transacted() .process(new Processor() { @@ -69,17 +78,17 @@ public class MessagingCommonRoutes extends RouteBuilder { }) .to("mock:txResult"); - fromF("%s:queue:objectTest", componentScheme) + fromF("%s:queue:testJmsObject", componentScheme) .to("mock:objectTestResult"); // Topic routes - fromF("%s:topic:test?clientId=123&durableSubscriptionName=camel-quarkus", componentScheme) + fromF("%s:topic:testJmsTopic?clientId=123&durableSubscriptionName=camel-quarkus", componentScheme) .to("mock:topicResultA"); - fromF("%s:topic:test?clientId=456&durableSubscriptionName=camel-quarkus", componentScheme) + fromF("%s:topic:testJmsTopic?clientId=456&durableSubscriptionName=camel-quarkus", componentScheme) .to("mock:topicResultB"); - fromF("%s:queue:resequence", componentScheme) + fromF("%s:queue:testResequence", componentScheme) // sort by body by allowing duplicates (message can have same JMSPriority) // and use reverse ordering so 9 is first output (most important), and 0 is last // use batch mode and fire every 3rd second @@ -87,16 +96,15 @@ public class MessagingCommonRoutes extends RouteBuilder { .to("mock:resequence"); from("direct:replyTo") - .toF("%s:queue:replyQueueA?replyTo=replyQueueB&preserveMessageQos=true", componentScheme) + .toF("%s:queue:testJmsReplyTo?replyTo=testJmsReplyTo2&preserveMessageQos=true", componentScheme) .to("mock:replyToDone"); - fromF("%s:queue:replyQueueA", componentScheme) + fromF("%s:queue:testJmsReplyTo", componentScheme) .to("mock:replyToStart") .transform(body().prepend("Hello ")); - fromF("%s:queue:replyQueueB?disableReplyTo=true", componentScheme) + fromF("%s:queue:testJmsReplyTo2?disableReplyTo=true", componentScheme) .to("mock:replyToEnd"); - } private boolean isDisableStreaming() { diff --git a/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingPojoConsumer.java b/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingPojoConsumer.java index 5ee275a4d1..5ec84fed19 100644 --- a/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingPojoConsumer.java +++ b/integration-tests/messaging/common/src/main/java/org/apache/camel/quarkus/component/messaging/it/MessagingPojoConsumer.java @@ -28,13 +28,13 @@ import org.apache.camel.quarkus.component.messaging.it.util.scheme.ComponentSche @Singleton public class MessagingPojoConsumer { - private static BlockingQueue<String> messages = new LinkedBlockingQueue<>(); + private static final BlockingQueue<String> messages = new LinkedBlockingQueue<>(); @Inject ComponentScheme scheme; public String getMessagingUri() { - return scheme + ":queue:pojoConsume"; + return scheme + ":queue:testJmsPojoConsumer"; } @Consume(property = "messagingUri") diff --git a/integration-tests/messaging/common/src/test/java/org/apache/camel/quarkus/component/messaging/it/AbstractMessagingTest.java b/integration-tests/messaging/common/src/test/java/org/apache/camel/quarkus/component/messaging/it/AbstractMessagingTest.java index 592c952532..04165ae9cd 100644 --- a/integration-tests/messaging/common/src/test/java/org/apache/camel/quarkus/component/messaging/it/AbstractMessagingTest.java +++ b/integration-tests/messaging/common/src/test/java/org/apache/camel/quarkus/component/messaging/it/AbstractMessagingTest.java @@ -25,15 +25,42 @@ import java.util.Map; import io.restassured.RestAssured; import io.restassured.http.ContentType; import jakarta.json.bind.JsonbBuilder; +import org.eclipse.microprofile.config.ConfigProvider; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import static org.hamcrest.core.Is.is; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public abstract class AbstractMessagingTest { + protected String queue; + protected String queue2; + protected String topic; + + @BeforeAll + public void startRoutes(TestInfo info) { + // At this point RestAssured is not configured to use the test port + // see https://github.com/quarkusio/quarkus/issues/7690#issuecomment-596543310 + // The comment states it does not work in native, however it seems to work fine + RestAssured.given() + .port(ConfigProvider.getConfig().getValue("quarkus.http.test-port", Integer.class)) + .get("/messaging/routes/start"); + } + + @BeforeEach + public void setupDestinations(TestInfo test) { + final String testMethod = test.getTestMethod().get().getName(); + queue = testMethod; + queue2 = testMethod + "2"; + topic = testMethod; + } @Test public void testQueueProduceConsume() { @@ -42,13 +69,13 @@ public abstract class AbstractMessagingTest { RestAssured.given() .contentType(ContentType.TEXT) .body(message) - .post("/messaging/{queueName}", "test-queue") + .post("/messaging/{queueName}", queue) .then() .statusCode(201); RestAssured.given() .contentType(ContentType.TEXT) - .get("/messaging/{queueName}", "test-queue") + .get("/messaging/{queueName}", queue) .then() .statusCode(200) .body(is(message)); @@ -59,13 +86,13 @@ public abstract class AbstractMessagingTest { public void testJmsMessageType(String type) { String message = "Message type " + type; String expected = message; - if (type.equals("node")) { + if ("node".equals(type)) { expected = "<test>" + message + "</test>"; } RestAssured.given() .body(message) - .post("/messaging/type/" + type) + .post("/messaging/{queueName}/type/{type}", queue, type) .then() .statusCode(200) .body(is(expected)); @@ -80,7 +107,7 @@ public abstract class AbstractMessagingTest { RestAssured.given() .contentType(ContentType.JSON) .body(JsonbBuilder.create().toJson(message)) - .post("/messaging/map") + .post("/messaging/{queueName}/map", queue) .then() .statusCode(200) .body(is("{\"foo\":\"bar\",\"cheese\":\"wine\"}")); @@ -91,7 +118,7 @@ public abstract class AbstractMessagingTest { String message = "Camel JMS Topic Message"; RestAssured.given() .body(message) - .post("/messaging/topic") + .post("/messaging/topic/{topicName}", topic) .then() .statusCode(204); } @@ -99,7 +126,7 @@ public abstract class AbstractMessagingTest { @Test public void testJmsSelector() { RestAssured.given() - .get("/messaging/selector/foo='bar'") + .get("/messaging/{queueName}/selector/foo='bar'", queue) .then() .statusCode(200) .body(is("Camel JMS Selector Match")); @@ -110,7 +137,7 @@ public abstract class AbstractMessagingTest { String message = "Mr Test Person"; RestAssured.given() .body(message) - .post("/messaging/object") + .post("/messaging/{queueName}/object", queue) .then() .statusCode(200) .body(is(message)); @@ -119,7 +146,7 @@ public abstract class AbstractMessagingTest { @Test public void testJmsTransaction() { RestAssured.given() - .get("/messaging/transaction") + .get("/messaging/{queueName}/transaction", queue) .then() .statusCode(200) .body(is("JMS Transaction Success")); @@ -132,7 +159,7 @@ public abstract class AbstractMessagingTest { for (String msg : messages) { RestAssured.given() .body(msg) - .post("/messaging/resequence") + .post("/messaging/{queueName}", queue) .then() .statusCode(201); } @@ -162,7 +189,7 @@ public abstract class AbstractMessagingTest { RestAssured.given() .contentType(ContentType.TEXT) .body(message) - .post("/messaging/{queueName}", "pojoConsume") + .post("/messaging/{queueName}", queue) .then() .statusCode(201); diff --git a/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsProducers.java b/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsProducers.java index 33834269a5..92079b2f0b 100644 --- a/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsProducers.java +++ b/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsProducers.java @@ -52,7 +52,7 @@ public class JmsProducers { return (session, destinationName, pubSubDomain) -> { if (destinationName.equals("ignored")) { // Ignore and override the original queue name - return session.createQueue("destinationOverride"); + return session.createQueue("testJmsDestinationResolver"); } if (pubSubDomain) { diff --git a/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsResource.java b/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsResource.java index 2d59fa7bb0..fd96c74cfd 100644 --- a/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsResource.java +++ b/integration-tests/messaging/jms/src/main/java/org/apache/camel/quarkus/messaging/jms/JmsResource.java @@ -55,16 +55,16 @@ public class JmsResource { @Inject ComponentScheme componentScheme; - @Path("/custom/message/listener/factory") + @Path("/{queueName}/custom/message/listener/factory") @POST @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.TEXT_PLAIN) - public String customMessageListenerContainerFactory(String message) { + public String customMessageListenerContainerFactory(@PathParam("queueName") String queueName, String message) { producerTemplate.sendBody( componentScheme - + ":queue:listener?messageListenerContainerFactory=#customMessageListener", + + ":queue:" + queueName + "?messageListenerContainerFactory=#customMessageListener", message); - return consumerTemplate.receiveBody(componentScheme + ":queue:listener", 5000, + return consumerTemplate.receiveBody(componentScheme + ":queue:" + queueName, 5000, String.class); } @@ -78,37 +78,37 @@ public class JmsResource { + ":queue:ignored?destinationResolver=#customDestinationResolver", message); - // The custom DestinationResolver should have overridden the original queue name to 'destinationOverride' - return consumerTemplate.receiveBody(componentScheme + ":queue:destinationOverride", + // The custom DestinationResolver should have overridden the original queue name to 'testJmsDestinationResolver' + return consumerTemplate.receiveBody(componentScheme + ":queue:testJmsDestinationResolver", 5000, String.class); } - @Path("/custom/message/converter") + @Path("/{queueName}/custom/message/converter") @POST @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.TEXT_PLAIN) - public String customMessageConverter(String message) { + public String customMessageConverter(@PathParam("queueName") String queueName, String message) { producerTemplate.sendBody( componentScheme - + ":queue:converter?messageConverter=#customMessageConverter", + + ":queue:" + queueName + "?messageConverter=#customMessageConverter", message); return consumerTemplate.receiveBody( componentScheme - + ":queue:converter?messageConverter=#customMessageConverter", + + ":queue:" + queueName + "?messageConverter=#customMessageConverter", 5000, String.class); } - @Path("/transfer/exchange") + @Path("/{queueName}/transfer/exchange") @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.TEXT_PLAIN) @POST - public Response testTransferExchange(String message) throws InterruptedException { + public Response testTransferExchange(@PathParam("queueName") String queueName, String message) throws InterruptedException { MockEndpoint mockEndpoint = context.getEndpoint("mock:transferExchangeResult", MockEndpoint.class); mockEndpoint.expectedMessageCount(1); producerTemplate.sendBody( - componentScheme + ":queue:transferExchange?transferExchange=true", message); + componentScheme + ":queue:" + queueName + "?transferExchange=true", message); mockEndpoint.assertIsSatisfied(); @@ -119,13 +119,13 @@ public class JmsResource { return Response.ok().entity(result).build(); } - @Path("/transfer/exception") + @Path("/{queueName}/transfer/exception") @Produces(MediaType.TEXT_PLAIN) @GET - public Response testTransferException() { + public Response testTransferException(@PathParam("queueName") String queueName) { try { producerTemplate.requestBody( - componentScheme + ":queue:transferException?transferException=true", + componentScheme + ":queue:" + queueName + "?transferException=true", "bad payload"); } catch (RuntimeCamelException e) { Class<? extends Throwable> exception = e.getCause().getClass(); 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 c0077926f7..8c46757cd2 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 @@ -34,10 +34,10 @@ public class JmsRoutes extends RouteBuilder { @Override public void configure() throws Exception { - fromF("%s:queue:transferExchange?transferExchange=true", componentScheme) + fromF("%s:queue:testJmsTransferExchange?transferExchange=true", componentScheme) .to("mock:transferExchangeResult"); - fromF("%s:queue:transferException?transferException=true", componentScheme) + fromF("%s:queue:testJmsTransferException?transferException=true", componentScheme) .throwException(new IllegalStateException("Forced exception")); from("direct:computedDestination") diff --git a/integration-tests/messaging/jms/src/test/java/org/apache/camel/quarkus/messaging/jms/AbstractJmsMessagingTest.java b/integration-tests/messaging/jms/src/test/java/org/apache/camel/quarkus/messaging/jms/AbstractJmsMessagingTest.java index 5c5fba54f0..93451fac0e 100644 --- a/integration-tests/messaging/jms/src/test/java/org/apache/camel/quarkus/messaging/jms/AbstractJmsMessagingTest.java +++ b/integration-tests/messaging/jms/src/test/java/org/apache/camel/quarkus/messaging/jms/AbstractJmsMessagingTest.java @@ -33,7 +33,7 @@ public class AbstractJmsMessagingTest extends AbstractMessagingTest { String message = "Test transfer message"; RestAssured.given() .body(message) - .post("/messaging/jms/transfer/exchange") + .post("/messaging/jms/{queueName}/transfer/exchange", queue) .then() .statusCode(200) .body(is(message)); @@ -42,7 +42,7 @@ public class AbstractJmsMessagingTest extends AbstractMessagingTest { @Test public void testJmsTransferException() { RestAssured.given() - .get("/messaging/jms/transfer/exception") + .get("/messaging/jms/{queueName}/transfer/exception", queue) .then() .statusCode(200) .body(is("java.lang.IllegalStateException")); @@ -53,7 +53,7 @@ public class AbstractJmsMessagingTest extends AbstractMessagingTest { String message = "Camel JMS With Custom MessageListenerContainerFactory"; RestAssured.given() .body(message) - .post("/messaging/jms/custom/message/listener/factory") + .post("/messaging/jms/{queueName}/custom/message/listener/factory", queue) .then() .statusCode(200) .body(is(message)); @@ -74,7 +74,7 @@ public class AbstractJmsMessagingTest extends AbstractMessagingTest { public void testJmsMessageConverter() { String result = RestAssured.given() .body("a test message") - .post("/messaging/jms/custom/message/converter") + .post("/messaging/jms/{queueName}/custom/message/converter", queue) .then() .statusCode(200) .extract() @@ -90,34 +90,32 @@ public class AbstractJmsMessagingTest extends AbstractMessagingTest { String message = UUID.randomUUID().toString(); // Send a message with java.lang.String destination header - String destinationA = "queue-" + UUID.randomUUID().toString().split("-")[0]; RestAssured.given() .queryParam("isStringDestination", "true") .body(message) - .post("/messaging/jms/custom/destination/{destinationName}", destinationA) + .post("/messaging/jms/custom/destination/{destinationName}", queue) .then() .statusCode(201); // Send a message with jakarta.jms.Destination destination header - String destinationB = "queue-" + UUID.randomUUID().toString().split("-")[0]; RestAssured.given() .queryParam("isStringDestination", "false") .body(message) - .post("/messaging/jms/custom/destination/{destinationName}", destinationB) + .post("/messaging/jms/custom/destination/{destinationName}", queue2) .then() .statusCode(201); // Verify messages sent to destinations RestAssured.given() .contentType(ContentType.TEXT) - .get("/messaging/{destinationName}", destinationA) + .get("/messaging/{destinationName}", queue) .then() .statusCode(200) .body(is(message)); RestAssured.given() .contentType(ContentType.TEXT) - .get("/messaging/{destinationName}", destinationB) + .get("/messaging/{destinationName}", queue2) .then() .statusCode(200) .body(is(message)); diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index e1fe31de83..285767dce0 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -17,7 +17,8 @@ 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"> +<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"> <modelVersion>4.0.0</modelVersion> <parent> @@ -121,6 +122,7 @@ <module>jfr</module> <!--<module>jira</module> https://github.com/apache/camel-quarkus/issues/4524 --> <module>jms-artemis-client</module> + <module>jms-ibmmq-client</module> <module>jms-qpid-amqp-client</module> <module>jolt</module> <module>joor</module> diff --git a/pom.xml b/pom.xml index 6a6d87b035..d0fa474bfd 100644 --- a/pom.xml +++ b/pom.xml @@ -104,6 +104,7 @@ <hapi-fhir.version>${hapi-fhir-version}</hapi-fhir.version> <hapi-fhir-core.version>5.6.971</hapi-fhir-core.version><!-- @sync ca.uhn.hapi.fhir:hapi-fhir:${hapi-fhir.version} prop:fhir_core_version --> <httpclient5.version>5.2.1</httpclient5.version><!-- Saxon and Wiremock --> + <ibm.mq.client.version>9.3.2.1</ibm.mq.client.version> <influxdb.version>${influx-java-driver-version}</influxdb.version> <io-netty-iouring.version>0.0.16.Final</io-netty-iouring.version><!-- @sync org.asynchttpclient:async-http-client-project:${ahc.version} prop:netty.iouring --> <jackson.version>2.15.0</jackson.version><!-- @sync io.quarkus:quarkus-bom:${quarkus.version} dep:com.fasterxml.jackson.core:jackson-core --> diff --git a/poms/bom-test/pom.xml b/poms/bom-test/pom.xml index 7d9a0792ee..ace0ec0356 100644 --- a/poms/bom-test/pom.xml +++ b/poms/bom-test/pom.xml @@ -154,7 +154,6 @@ <artifactId>camel-quarkus-integration-tests-process-executor-support</artifactId> <version>${camel-quarkus.version}</version> </dependency> - <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-integration-tests-support-google</artifactId> diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml index 8e6d466b0c..4c528d5052 100644 --- a/poms/bom/pom.xml +++ b/poms/bom/pom.xml @@ -6055,6 +6055,11 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>com.ibm.mq</groupId> + <artifactId>com.ibm.mq.jakarta.client</artifactId> + <version>${ibm.mq.client.version}</version> + </dependency> <dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> @@ -6717,6 +6722,7 @@ <resolutionEntryPointInclude>io.quarkiverse.messaginghub:*</resolutionEntryPointInclude> <resolutionEntryPointInclude>net.openhft:affinity</resolutionEntryPointInclude> <!-- https://github.com/apache/camel-quarkus/issues/3788 --> <resolutionEntryPointInclude>xerces:xercesImpl</resolutionEntryPointInclude> + <resolutionEntryPointInclude>com.ibm.mq:com.ibm.mq.jakarta.client</resolutionEntryPointInclude> </resolutionEntryPointIncludes> <bannedDependencyResources> <bannedDependencyResource> diff --git a/poms/bom/src/main/generated/flattened-full-pom.xml b/poms/bom/src/main/generated/flattened-full-pom.xml index 3808a0c9f8..79f45cd26f 100644 --- a/poms/bom/src/main/generated/flattened-full-pom.xml +++ b/poms/bom/src/main/generated/flattened-full-pom.xml @@ -5978,6 +5978,11 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>com.ibm.mq</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} --> + <artifactId>com.ibm.mq.jakarta.client</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} --> + <version>9.3.2.1</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} --> + </dependency> <dependency> <groupId>com.jayway.jsonpath</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} --> <artifactId>json-path</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} --> diff --git a/poms/bom/src/main/generated/flattened-reduced-pom.xml b/poms/bom/src/main/generated/flattened-reduced-pom.xml index 4e1ecdde7c..90007fc0f1 100644 --- a/poms/bom/src/main/generated/flattened-reduced-pom.xml +++ b/poms/bom/src/main/generated/flattened-reduced-pom.xml @@ -5978,6 +5978,11 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>com.ibm.mq</groupId> + <artifactId>com.ibm.mq.jakarta.client</artifactId> + <version>9.3.2.1</version> + </dependency> <dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> diff --git a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml index 896ef7ef7a..977f43ee1f 100644 --- a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml +++ b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml @@ -5978,6 +5978,11 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>com.ibm.mq</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} --> + <artifactId>com.ibm.mq.jakarta.client</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} --> + <version>9.3.2.1</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} --> + </dependency> <dependency> <groupId>com.jayway.jsonpath</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} --> <artifactId>json-path</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} --> diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml index 52982109f5..28f41a234d 100644 --- a/tooling/scripts/test-categories.yaml +++ b/tooling/scripts/test-categories.yaml @@ -25,6 +25,7 @@ group-01: - infinispan-quarkus-client - jcache - jms-artemis-client + - jms-ibmmq-client - jsch - kafka - kafka-sasl