From 12e1f9ddf6e79b9397c6d25f5d160893adfbdc20 Mon Sep 17 00:00:00 2001 From: Kabir Khan Date: Tue, 12 Dec 2023 20:59:45 +0000 Subject: [PATCH] [WFLY-15405] Test for the MP Reactive Messaging AMQP Connnector --- .../pom.xml | 49 ++++++++ images/pom.xml | 1 + test-bom/pom.xml | 6 + .../reactive-messaging/amqp/Dockerfile | 1 + .../reactive-messaging/amqp/pom.xml | 66 +++++++++++ .../amqp/ReactiveMessagingWithAmqpApp.java | 40 +++++++ .../amqp/ReactiveMessagingWithAmqpBean.java | 67 +++++++++++ .../ReactiveMessagingWithAmqpEndpoint.java | 58 +++++++++ .../META-INF/microprofile-config.properties | 30 +++++ .../amqp/src/test/container/artemis.yml | 57 +++++++++ .../amqp/ReactiveMessagingWithAmqpIT.java | 112 ++++++++++++++++++ .../amqp/src/webapp/WEB-INF/beans.xml | 25 ++++ tests/microprofile/reactive-messaging/pom.xml | 1 + 13 files changed, 513 insertions(+) create mode 100644 images/microprofile-reactive-messaging-amqp/pom.xml create mode 100644 tests/microprofile/reactive-messaging/amqp/Dockerfile create mode 100644 tests/microprofile/reactive-messaging/amqp/pom.xml create mode 100644 tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpApp.java create mode 100644 tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpBean.java create mode 100644 tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpEndpoint.java create mode 100644 tests/microprofile/reactive-messaging/amqp/src/main/resources/META-INF/microprofile-config.properties create mode 100644 tests/microprofile/reactive-messaging/amqp/src/test/container/artemis.yml create mode 100644 tests/microprofile/reactive-messaging/amqp/src/test/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpIT.java create mode 100644 tests/microprofile/reactive-messaging/amqp/src/webapp/WEB-INF/beans.xml diff --git a/images/microprofile-reactive-messaging-amqp/pom.xml b/images/microprofile-reactive-messaging-amqp/pom.xml new file mode 100644 index 00000000..d9ad4dc5 --- /dev/null +++ b/images/microprofile-reactive-messaging-amqp/pom.xml @@ -0,0 +1,49 @@ + + + + + 4.0.0 + + + org.wildfly.cloud-tests + wildfly-cloud-test-images + 1.0.0.Alpha3-SNAPSHOT + + image-microprofile-reactive-messaging-amqp + pom + + + + + org.wildfly.plugins + wildfly-maven-plugin + + + cloud-server + microprofile-reactive-messaging-amqp + + + + + + + \ No newline at end of file diff --git a/images/pom.xml b/images/pom.xml index 1d0f404c..26b1e298 100644 --- a/images/pom.xml +++ b/images/pom.xml @@ -54,6 +54,7 @@ images cloud-server + microprofile-reactive-messaging-amqp microprofile-reactive-messaging-kafka datasources/postgresql elytron-oidc-client diff --git a/test-bom/pom.xml b/test-bom/pom.xml index 82d4c3ec..303e44bb 100644 --- a/test-bom/pom.xml +++ b/test-bom/pom.xml @@ -93,6 +93,12 @@ ${project.version} pom + + ${project.groupId} + image-microprofile-reactive-messaging-amqp + ${project.version} + pom + ${project.groupId} image-microprofile-reactive-messaging-kafka diff --git a/tests/microprofile/reactive-messaging/amqp/Dockerfile b/tests/microprofile/reactive-messaging/amqp/Dockerfile new file mode 100644 index 00000000..cb06cd50 --- /dev/null +++ b/tests/microprofile/reactive-messaging/amqp/Dockerfile @@ -0,0 +1 @@ +# Needed until https://github.com/dekorateio/dekorate/issues/1000 is fixed \ No newline at end of file diff --git a/tests/microprofile/reactive-messaging/amqp/pom.xml b/tests/microprofile/reactive-messaging/amqp/pom.xml new file mode 100644 index 00000000..1bd570bf --- /dev/null +++ b/tests/microprofile/reactive-messaging/amqp/pom.xml @@ -0,0 +1,66 @@ + + + + + 4.0.0 + + + org.wildfly.cloud-tests + wildfly-cloud-tests-microprofile-reactive-messaging + 1.0.0.Alpha3-SNAPSHOT + + wildfly-cloud-tests-microprofile-reactive-messaging-amqp + war + + + wildfly-cloud-test-image/image-microprofile-reactive-messaging-amqp:latest + + + + + ${project.groupId} + image-microprofile-reactive-messaging-amqp + pom + test + + + jakarta.inject + jakarta.inject-api + provided + + + jakarta.enterprise + jakarta.enterprise.cdi-api + provided + + + jakarta.ws.rs + jakarta.ws.rs-api + provided + + + org.eclipse.microprofile.reactive.messaging + microprofile-reactive-messaging-api + provided + + + \ No newline at end of file diff --git a/tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpApp.java b/tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpApp.java new file mode 100644 index 00000000..fda6b4e8 --- /dev/null +++ b/tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpApp.java @@ -0,0 +1,40 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2023 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.wildfly.test.cloud.microprofile.reactive.messaging.amqp; + +import static io.dekorate.kubernetes.annotation.ImagePullPolicy.Always; + +import jakarta.ws.rs.ApplicationPath; +import jakarta.ws.rs.core.Application; + +import io.dekorate.kubernetes.annotation.Env; +import io.dekorate.kubernetes.annotation.KubernetesApplication; + +/** + * @author Kabir Khan + */ +@KubernetesApplication( + envVars = { + @Env(name = "AMQP_HOST", value= "artemis") + }, + imagePullPolicy = Always) +@ApplicationPath("") +public class ReactiveMessagingWithAmqpApp extends Application { +} diff --git a/tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpBean.java b/tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpBean.java new file mode 100644 index 00000000..7f9df984 --- /dev/null +++ b/tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpBean.java @@ -0,0 +1,67 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2023 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.wildfly.test.cloud.microprofile.reactive.messaging.amqp; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +import org.eclipse.microprofile.reactive.messaging.Channel; +import org.eclipse.microprofile.reactive.messaging.Emitter; +import org.eclipse.microprofile.reactive.messaging.Incoming; + +/** + * @author Kabir Khan + */ +@ApplicationScoped +public class ReactiveMessagingWithAmqpBean { + @Inject + @Channel("to-amqp") + private Emitter emitter; + + private List received = new ArrayList<>(); + + private boolean seenOne; + + @Incoming("from-amqp") + public void receive(String value) { + System.out.println("Received: " + value); + if (value.equals("one")) { + if (seenOne) { + // Avoid adding duplicate 'one' entries since the test might send more than one. See the comment there + System.out.println("'one' already in list. Skipping"); + return; + } + seenOne = true; + } + received.add(value); + } + + void send(String value) { + System.out.println("Sending: " + value); + emitter.send(value); + } + + public List getReceived() { + return received; + } +} diff --git a/tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpEndpoint.java b/tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpEndpoint.java new file mode 100644 index 00000000..54df1a16 --- /dev/null +++ b/tests/microprofile/reactive-messaging/amqp/src/main/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpEndpoint.java @@ -0,0 +1,58 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2023 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.wildfly.test.cloud.microprofile.reactive.messaging.amqp; + +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; + +import java.util.List; + +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +/** + * @author Kabir Khan + */ +@Path("") +public class ReactiveMessagingWithAmqpEndpoint { + @Inject + ReactiveMessagingWithAmqpBean bean; + + @POST + @Path("{value}") + @Consumes(MediaType.TEXT_PLAIN) + public Response send(@PathParam("value") String value) { + bean.send(value); + return Response.ok().build(); + } + + @GET + @Produces(APPLICATION_JSON) + public List getHelloWorldJSON() { + return bean.getReceived(); + } + +} diff --git a/tests/microprofile/reactive-messaging/amqp/src/main/resources/META-INF/microprofile-config.properties b/tests/microprofile/reactive-messaging/amqp/src/main/resources/META-INF/microprofile-config.properties new file mode 100644 index 00000000..719c2711 --- /dev/null +++ b/tests/microprofile/reactive-messaging/amqp/src/main/resources/META-INF/microprofile-config.properties @@ -0,0 +1,30 @@ +# +# JBoss, Home of Professional Open Source. +# Copyright 2022 Red Hat, Inc., and individual contributors +# as indicated by the @author tags. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +amqp-port=5672 +amqp-username=artemis +amqp-password=artemis +amqp-use-ssl=false + +mp.messaging.outgoing.to-amqp.connector=smallrye-amqp +mp.messaging.outgoing.to-amqp.address=test + +mp.messaging.incoming.from-amqp.connector=smallrye-amqp +mp.messaging.incoming.from-amqp.address=test + diff --git a/tests/microprofile/reactive-messaging/amqp/src/test/container/artemis.yml b/tests/microprofile/reactive-messaging/amqp/src/test/container/artemis.yml new file mode 100644 index 00000000..4f596f8e --- /dev/null +++ b/tests/microprofile/reactive-messaging/amqp/src/test/container/artemis.yml @@ -0,0 +1,57 @@ +apiVersion: v1 +kind: List +items: + - apiVersion: apps/v1 + kind: Deployment + metadata: + name: artemis + labels: + app: artemis + spec: + replicas: 1 + selector: + matchLabels: + app: artemis + template: + metadata: + labels: + app: artemis + spec: + containers: + - name: artemis + image: quay.io/artemiscloud/activemq-artemis-broker-kubernetes:1.0.23 + env: + - name: AMQ_USER + value: artemis + - name: AMQ_PASSWORD + value: artemis + - name: AMQ_DATA_DIR + value: /home/jboss/data +# - name: AMQ_EXTRA_ARGS +# value: "--http-host 0.0.0.0 " + - name: SCRIPT_DEBUG + value: "true" + ports: + - containerPort: 5672 + - containerPort: 8161 + - containerPort: 61613 + - apiVersion: v1 + kind: Service + metadata: + name: artemis + spec: + selector: + app: artemis + ports: + - protocol: TCP + port: 5672 + targetPort: 5672 + name: amqp + - protocol: TCP + port: 8161 + targetPort: 8161 + name: http + - protocol: TCP + port: 61616 + targetPort: 61613 + name: all diff --git a/tests/microprofile/reactive-messaging/amqp/src/test/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpIT.java b/tests/microprofile/reactive-messaging/amqp/src/test/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpIT.java new file mode 100644 index 00000000..5a485be5 --- /dev/null +++ b/tests/microprofile/reactive-messaging/amqp/src/test/java/org/wildfly/test/cloud/microprofile/reactive/messaging/amqp/ReactiveMessagingWithAmqpIT.java @@ -0,0 +1,112 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2023 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.wildfly.test.cloud.microprofile.reactive.messaging.amqp; + +import static org.wildfly.test.cloud.common.WildflyTags.KUBERNETES; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.ws.rs.core.MediaType; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.wildfly.test.cloud.common.ConfigPlaceholderReplacement; +import org.wildfly.test.cloud.common.KubernetesResource; +import org.wildfly.test.cloud.common.WildFlyCloudTestCase; +import org.wildfly.test.cloud.common.WildFlyKubernetesIntegrationTest; + +import io.restassured.RestAssured; +import io.restassured.response.Response; + +/** + * @author Kabir Khan + */ +@Tag(KUBERNETES) +@WildFlyKubernetesIntegrationTest( + kubernetesResources = { + @KubernetesResource(definitionLocation = "src/test/container/artemis.yml") + } +) +public class ReactiveMessagingWithAmqpIT extends WildFlyCloudTestCase { + + @Test + public void test() throws Exception { + postMessage("one"); + + List list = getReceived(); + if (list.size() == 0) { + // Occasionally we might start sending messages before the subscriber is connected property + // (the connection happens async as part of the application start) so retry until we get this first message + Thread.sleep(1000); + long end = System.currentTimeMillis() + 20000; + while (true) { + list = getReceived(); + if (getReceived().size() != 0) { + break; + } + + if (System.currentTimeMillis() > end) { + break; + } + postMessage("one"); + Thread.sleep(1000); + } + } + + + postMessage("two"); + + long end = System.currentTimeMillis() + 20000; + while (list.size() != 2 && System.currentTimeMillis() < end) { + list = getReceived(); + Thread.sleep(1000); + } + waitUntilListPopulated(20000, "one", "two"); + + } + + private void waitUntilListPopulated(long timoutMs, String... expected) throws Exception { + List list = new ArrayList<>(); + long end = System.currentTimeMillis() + timoutMs; + while (list.size() < expected.length && System.currentTimeMillis() < end) { + list = getReceived(); + Thread.sleep(1000); + } + Assertions.assertArrayEquals(expected, list.toArray(new String[list.size()])); + } + + private List getReceived() throws Exception { + return getHelper().doWithWebPortForward("", url -> { + Response r = RestAssured.get(url); + Assertions.assertEquals(200, r.getStatusCode()); + return r.as(List.class); + }); + } + + private void postMessage(String s) throws Exception { + int status = getHelper().doWithWebPortForward(s, + url -> RestAssured.given().header("Content-Type", MediaType.TEXT_PLAIN).post(url).getStatusCode()); + Assertions.assertEquals(200, status); + + } + +} diff --git a/tests/microprofile/reactive-messaging/amqp/src/webapp/WEB-INF/beans.xml b/tests/microprofile/reactive-messaging/amqp/src/webapp/WEB-INF/beans.xml new file mode 100644 index 00000000..28afe894 --- /dev/null +++ b/tests/microprofile/reactive-messaging/amqp/src/webapp/WEB-INF/beans.xml @@ -0,0 +1,25 @@ + + + + + + diff --git a/tests/microprofile/reactive-messaging/pom.xml b/tests/microprofile/reactive-messaging/pom.xml index 5131b4c5..50bfdebe 100644 --- a/tests/microprofile/reactive-messaging/pom.xml +++ b/tests/microprofile/reactive-messaging/pom.xml @@ -32,6 +32,7 @@ pom + amqp strimzi