diff --git a/integration-tests/jt400/README.adoc b/integration-tests/jt400/README.adoc index 636c965e0542..90a83efa4390 100644 --- a/integration-tests/jt400/README.adoc +++ b/integration-tests/jt400/README.adoc @@ -69,6 +69,13 @@ Message queue can be created by following the command CRTMSGQ LIBRARY/TESTMSGQ ``` + +Seconf queue is required for testing of inquiry messages: + +``` +CRTMSGQ LIBRARY/REPLYMSGQ +``` + ==== Data queue testing Two data-queues are required for the testing. One created as `keyed=true` and one as `LIFO`. @@ -90,6 +97,7 @@ export JT400_LIBRARY=#library_if_not_LIBRARY export JT400_LIFO_QUEUE=#lifoqueue_if_not_TESTLIFO.DTAQ export JT400_KEYED_QUEUE=#lkeyedqueue_if_not_TESTKEYED.DTAQ export JT400_MESSAGE_QUEUE=#messagequeue_if_not_TESTMSGQ.MSGQ +export JT400_MESSAGE_REPLYTO_QUEUE=#messagequeueinquiry_if_not_REPLYMSGQ.MSGQ export JT400_USER_SPACE=#userspace_if_not_PROGCALL ``` @@ -99,6 +107,7 @@ or for Windows: $Env:JT400_LIBRARY = "#library_if_not_LIBRARY" $Env:JT400_LIFO_QUEUE="#lifoqueue_if_not_TESTLIFO.DTAQe" $Env:JT400_KEYED_QUEUE="#lkeyedqueue_if_not_TESTKEYED.DTAQ" -$Env:JT400_MESSAGE_QUEUE="#messagequeue_if_not_TESTMSGQ.MSGQe" +$Env:JT400_MESSAGE_QUEUE="#messagequeue_if_not_TESTMSGQ.MSGQ" +$Env:JT400_MESSAGE_REPLYTO_QUEUE="#messagequeueinquiry_if_not_REPLYMSGQ.MSGQ" $Env:JT400_USER_SPACE="#userspace_if_not_PROGCALL" ``` \ No newline at end of file diff --git a/integration-tests/jt400/src/main/java/org/apache/camel/quarkus/component/jt400/it/Jt400Resource.java b/integration-tests/jt400/src/main/java/org/apache/camel/quarkus/component/jt400/it/Jt400Resource.java index b861f8a78ffc..c65f2689785c 100644 --- a/integration-tests/jt400/src/main/java/org/apache/camel/quarkus/component/jt400/it/Jt400Resource.java +++ b/integration-tests/jt400/src/main/java/org/apache/camel/quarkus/component/jt400/it/Jt400Resource.java @@ -21,6 +21,8 @@ import java.util.Map; import java.util.Optional; +import com.ibm.as400.access.AS400; +import com.ibm.as400.access.MessageQueue; import com.ibm.as400.access.QueuedMessage; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -31,6 +33,7 @@ import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import org.apache.camel.CamelContext; import org.apache.camel.ConsumerTemplate; import org.apache.camel.Exchange; import org.apache.camel.ProducerTemplate; @@ -45,7 +48,7 @@ public class Jt400Resource { String jt400Url; @ConfigProperty(name = "cq.jt400.username") - String jt400USername; + String jt400Username; @ConfigProperty(name = "cq.jt400.password") String jt400Password; @@ -62,6 +65,9 @@ public class Jt400Resource { @ConfigProperty(name = "cq.jt400.message-queue") String jt400MessageQueue; + @ConfigProperty(name = "cq.jt400.message-replyto-queue") + String jt400MessageReplyToQueue; + @ConfigProperty(name = "cq.jt400.user-space") String jt400UserSpace; @@ -71,6 +77,9 @@ public class Jt400Resource { @Inject ConsumerTemplate consumerTemplate; + @Inject + CamelContext context; + @Path("/dataQueue/read/") @POST @Produces(MediaType.APPLICATION_JSON) @@ -123,6 +132,36 @@ public Response keyedDataQueueWrite(@QueryParam("key") String key, return Response.ok().entity(ex).build(); } + @Path("/client/inquiryMessage/write/") + @POST + @Produces(MediaType.TEXT_PLAIN) + public Response clientInquiryMessageWrite(String data) throws Exception { + Jt400Endpoint jt400Endpoint = context.getEndpoint(getUrlForLibrary(jt400MessageReplyToQueue), Jt400Endpoint.class); + AS400 as400 = jt400Endpoint.getConfiguration().getConnection(); + //send inquiry message (with the same client as is used in the component, to avoid `CPF2451 Message queue TESTMSGQ is allocated to another job`. + MessageQueue queue = new MessageQueue(as400, jt400Endpoint.getConfiguration().getObjectPath()); + try { + queue.sendInquiry(data, "/QSYS.LIB/" + jt400Library + ".LIB/" + jt400MessageReplyToQueue); + } catch (Exception e) { + return Response.status(500).entity(e.getMessage()).build(); + } + return Response.ok().build(); + } + + @Path("/client/queuedMessage/read") + @POST + @Produces(MediaType.TEXT_PLAIN) + public Response clientQueuedMessageRead(String queueName) throws Exception { + + Jt400Endpoint jt400Endpoint = context.getEndpoint(getUrlForLibrary(queueName), Jt400Endpoint.class); + AS400 as400 = jt400Endpoint.getConfiguration().getConnection(); + //send inquiry message (with the same client as is used in the component, to avoid `CPF2451 Message queue TESTMSGQ is allocated to another job`. + MessageQueue queue = new MessageQueue(as400, jt400Endpoint.getConfiguration().getObjectPath()); + QueuedMessage message = queue.receive(null); + + return Response.ok().entity(message != null ? message.getText() : "").build(); + } + @Path("/messageQueue/write/") @POST @Produces(MediaType.TEXT_PLAIN) @@ -135,8 +174,9 @@ public Response messageQueueWrite(String data) { @Path("/messageQueue/read/") @POST @Produces(MediaType.APPLICATION_JSON) - public Response messageQueueRead() { - Exchange ex = consumerTemplate.receive(getUrlForLibrary(jt400MessageQueue)); + public Response messageQueueRead(@QueryParam("queue") String queue) { + Exchange ex = consumerTemplate + .receive(getUrlForLibrary(queue == null ? jt400MessageQueue : queue)); return generateResponse(ex.getIn().getBody(String.class), ex); } @@ -164,12 +204,12 @@ public Response programCall() throws Exception { } private String getUrlForLibrary(String suffix) { - return String.format("jt400://%s:%s@%s%s", jt400USername, jt400Password, jt400Url, + return String.format("jt400://%s:%s@%s%s", jt400Username, jt400Password, jt400Url, "/QSYS.LIB/" + jt400Library + ".LIB/" + suffix); } private String getUrl(String suffix) { - return String.format("jt400://%s:%s@%s%s", jt400USername, jt400Password, jt400Url, suffix); + return String.format("jt400://%s:%s@%s%s", jt400Username, jt400Password, jt400Url, suffix); } Response generateResponse(String result, Exchange ex) { diff --git a/integration-tests/jt400/src/main/java/org/apache/camel/quarkus/component/jt400/it/Jt400Routes.java b/integration-tests/jt400/src/main/java/org/apache/camel/quarkus/component/jt400/it/Jt400Routes.java new file mode 100644 index 000000000000..5615454c8610 --- /dev/null +++ b/integration-tests/jt400/src/main/java/org/apache/camel/quarkus/component/jt400/it/Jt400Routes.java @@ -0,0 +1,59 @@ +/* + * 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.jt400.it; + +import com.ibm.as400.access.AS400Message; +import jakarta.enterprise.context.ApplicationScoped; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.jt400.Jt400Constants; +import org.eclipse.microprofile.config.inject.ConfigProperty; + +@ApplicationScoped +public class Jt400Routes extends RouteBuilder { + + @ConfigProperty(name = "cq.jt400.library") + String jt400Library; + + @ConfigProperty(name = "cq.jt400.url") + String jt400Url; + + @ConfigProperty(name = "cq.jt400.username") + String jt400Username; + + @ConfigProperty(name = "cq.jt400.password") + String jt400Password; + + @ConfigProperty(name = "cq.jt400.message-replyto-queue") + String jt400MessageReplyToQueue; + + @Override + public void configure() throws Exception { + from(getUrlForLibrary(jt400MessageReplyToQueue + "?sendingReply=true")) + .choice() + .when(header(Jt400Constants.MESSAGE_TYPE).isEqualTo(AS400Message.INQUIRY)) + .process((exchange) -> { + String reply = "reply to: " + exchange.getIn().getBody(String.class); + exchange.getIn().setBody(reply); + }) + .to(getUrlForLibrary(jt400MessageReplyToQueue)); + } + + private String getUrlForLibrary(String suffix) { + return String.format("jt400://%s:%s@%s%s", jt400Username, jt400Password, jt400Url, + "/QSYS.LIB/" + jt400Library + ".LIB/" + suffix); + } +} diff --git a/integration-tests/jt400/src/main/resources/application.properties b/integration-tests/jt400/src/main/resources/application.properties index f4d6410bd109..db47b32aab66 100644 --- a/integration-tests/jt400/src/main/resources/application.properties +++ b/integration-tests/jt400/src/main/resources/application.properties @@ -29,5 +29,6 @@ cq.jt400.password=${JT400_PASSWORD:password} cq.jt400.library=${JT400_LIBRARY:LIBRARY} cq.jt400.user-space=${JT400_USER_SPACE:PROGCALL} cq.jt400.message-queue=${JT400_MESSAGE_QUEUE:TESTMSGQ.MSGQ} +cq.jt400.message-replyto-queue=${JT400_MESSAGE_REPLYTO_QUEUE:REPLYMSGQ.MSGQ} cq.jt400.keyed-queue=${JT400_KEYED_QUEUE:TESTKEYED.DTAQ} cq.jt400.lifo-queue=${JT400_LIFO_QUEUE:TESTLIFO.DTAQ} diff --git a/integration-tests/jt400/src/test/java/org/apache/camel/quarkus/component/jt400/it/Jt400Test.java b/integration-tests/jt400/src/test/java/org/apache/camel/quarkus/component/jt400/it/Jt400Test.java index d1d73187d0f2..c1168b7644b5 100644 --- a/integration-tests/jt400/src/test/java/org/apache/camel/quarkus/component/jt400/it/Jt400Test.java +++ b/integration-tests/jt400/src/test/java/org/apache/camel/quarkus/component/jt400/it/Jt400Test.java @@ -16,10 +16,23 @@ */ package org.apache.camel.quarkus.component.jt400.it; +import java.io.IOException; +import java.util.Locale; +import java.util.function.BiFunction; + +import com.ibm.as400.access.AS400; +import com.ibm.as400.access.AS400SecurityException; +import com.ibm.as400.access.ErrorCompletingRequestException; +import com.ibm.as400.access.KeyedDataQueue; +import com.ibm.as400.access.MessageQueue; +import com.ibm.as400.access.ObjectDoesNotExistException; import io.quarkus.test.junit.QuarkusTest; import io.restassured.RestAssured; import org.apache.camel.component.jt400.Jt400Constants; +import org.apache.commons.lang3.RandomStringUtils; +import org.eclipse.microprofile.config.ConfigProvider; import org.hamcrest.Matchers; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; @@ -27,50 +40,101 @@ @EnabledIfEnvironmentVariable(named = "JT400_URL", matches = ".+") public class Jt400Test { + @BeforeAll + public static void beforeAll() throws Exception { + //read all messages from the queues to be sure that they are empty + + //clear reply-to message queue + clearQueue("cq.jt400.message-replyto-queue", + (as400, path) -> { + try { + return new MessageQueue(as400, path).receive(null); + } catch (Exception e) { + return null; + } + }); + + //clear message queue + clearQueue("cq.jt400.message-queue", + (as400, path) -> { + try { + return new MessageQueue(as400, path).receive(null); + } catch (Exception e) { + return null; + } + }); + + //clear keyed queue for key1 + clearQueue("cq.jt400.message-queue", + (as400, path) -> { + try { + return new KeyedDataQueue(as400, path).read("key1"); + } catch (Exception e) { + return null; + } + }); + + //clear keyed queue for key2 + clearQueue("cq.jt400.message-queue", + (as400, path) -> { + try { + return new KeyedDataQueue(as400, path).read("key1"); + } catch (Exception e) { + return null; + } + }); + } + @Test public void testDataQueue() { + String msg = RandomStringUtils.randomAlphanumeric(10).toLowerCase(Locale.ROOT); + RestAssured.given() - .body("Leonard") + .body(msg) .post("/jt400/dataQueue/write") .then() .statusCode(200) - .body(Matchers.equalTo("Hello Leonard")); + .body(Matchers.equalTo("Hello " + msg)); RestAssured.post("/jt400/dataQueue/read") .then() .statusCode(200) - .body("result", Matchers.equalTo("Hello Leonard")); + .body("result", Matchers.equalTo("Hello " + msg)); } @Test public void testDataQueueBinary() { + String msg = RandomStringUtils.randomAlphanumeric(10).toLowerCase(Locale.ROOT); + RestAssured.given() - .body("Fred") + .body(msg) .post("/jt400/dataQueue/write") .then() .statusCode(200) - .body(Matchers.equalTo("Hello Fred")); + .body(Matchers.equalTo("Hello " + msg)); RestAssured.given() .queryParam("format", "binary") .post("/jt400/dataQueue/read") .then() .statusCode(200) - .body("result", Matchers.equalTo("Hello Fred")); + .body("result", Matchers.equalTo("Hello " + msg)); } @Test public void testKeyedDataQueue() { - String key = "key1"; + String msg1 = RandomStringUtils.randomAlphanumeric(10).toLowerCase(Locale.ROOT); + String msg2 = RandomStringUtils.randomAlphanumeric(10).toLowerCase(Locale.ROOT); + String key1 = "key1"; String key2 = "key2"; RestAssured.given() - .body("Sheldon") - .queryParam("key", key) + .body(msg1) + .queryParam("key", key1) .post("/jt400/dataQueue/write/") .then() .statusCode(200) - .body(Matchers.equalTo("Hello Sheldon")); + .body(Matchers.equalTo("Hello " + msg1)); RestAssured.given() .body("Sheldon2") @@ -81,45 +145,68 @@ public void testKeyedDataQueue() { .body(Matchers.equalTo("Hello Sheldon2")); RestAssured.given() - .body(key) + .body(key1) .post("/jt400/dataQueue/read/") .then() .statusCode(200) - .body("result", Matchers.equalTo("Hello Sheldon")) - .body(Jt400Constants.KEY, Matchers.equalTo(key)); + .body("result", Matchers.equalTo("Hello " + msg1)) + .body(Jt400Constants.KEY, Matchers.equalTo(key1)); RestAssured.given() - .body(key) - .queryParam("searchType", "GT") + .body(key1) + .queryParam("searchType", "NE") .post("/jt400/dataQueue/read/") .then() .statusCode(200) - .body("result", Matchers.equalTo("Hello Sheldon2")) + .body("result", Matchers.not(Matchers.equalTo("Hello " + msg2))) .body(Jt400Constants.KEY, Matchers.equalTo(key2)); } @Test - public void testMessageQueue() { + public void testMessageQueue() throws AS400SecurityException, ObjectDoesNotExistException, IOException, + InterruptedException, ErrorCompletingRequestException { + String msg = RandomStringUtils.randomAlphanumeric(10).toLowerCase(Locale.ROOT); + RestAssured.given() - .body("Irma") + .body(msg) .post("/jt400/messageQueue/write") .then() .statusCode(200) - .body(Matchers.equalTo("Hello Irma")); + .body(Matchers.equalTo("Hello " + msg)); RestAssured.post("/jt400/messageQueue/read") .then() .statusCode(200) - .body("result", Matchers.is("Hello Irma")) + .body("result", Matchers.is("Hello " + msg)) //check of headers .body(Jt400Constants.SENDER_INFORMATION, Matchers.not(Matchers.empty())) .body(Jt400Constants.MESSAGE_FILE, Matchers.is("")) .body(Jt400Constants.MESSAGE_SEVERITY, Matchers.is(0)) .body(Jt400Constants.MESSAGE_ID, Matchers.is("")) .body(Jt400Constants.MESSAGE_TYPE, Matchers.is(4)) - .body(Jt400Constants.MESSAGE, Matchers.is("QueuedMessage: Hello Irma")); + .body(Jt400Constants.MESSAGE, Matchers.is("QueuedMessage: Hello " + msg)); //Jt400Constants.MESSAGE_DFT_RPY && Jt400Constants.MESSAGE_REPLYTO_KEY are used only for a special - // type of message which can not be created by the camel compinent (*INQUIRY) + // type of message which can not be created by the camel component (*INQUIRY) + } + + @Test + public void testInquiryMessageQueue() throws AS400SecurityException, ObjectDoesNotExistException, IOException, + InterruptedException, ErrorCompletingRequestException { + String msg = RandomStringUtils.randomAlphanumeric(10).toLowerCase(Locale.ROOT); + + //sending a message using the same client as component + RestAssured.given() + .body(msg) + .post("/jt400/client/inquiryMessage/write") + .then() + .statusCode(200); + + RestAssured.given() + .body(ConfigProvider.getConfig().getValue("cq.jt400.message-replyto-queue", String.class)) + .post("/jt400/client/queuedMessage/read") + .then() + .statusCode(200) + .body(Matchers.equalTo("reply to: " + msg)); } @Test @@ -132,4 +219,27 @@ public void testProgramCall() { .body(Matchers.containsString("hello camel")); } + private static void clearQueue(String queue, BiFunction readFromQueue) { + String jt400Url = ConfigProvider.getConfig().getValue("cq.jt400.url", String.class); + String jt400Username = ConfigProvider.getConfig().getValue("cq.jt400.username", String.class); + String jt400Password = ConfigProvider.getConfig().getValue("cq.jt400.password", String.class); + String jt400Library = ConfigProvider.getConfig().getValue("cq.jt400.library", String.class); + String jt400MessageQueue = ConfigProvider.getConfig().getValue(queue, String.class); + + String objectPath = String.format("/QSYS.LIB/%s.LIB/%s", jt400Library, jt400MessageQueue); + + AS400 as400 = new AS400(jt400Url, jt400Username, jt400Password); + + int i = 0; + Object msg = null; + //read messages until null is received + do { + msg = readFromQueue.apply(as400, objectPath); + } while (i++ < 10 && msg != null); + + if (i == 10 && msg != null) { + throw new IllegalStateException("There is a message present in a queue!"); + } + } + }