This is an automated email from the ASF dual-hosted git repository. jamesnetherton pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/master by this push: new de9ab94 LRA native support de9ab94 is described below commit de9ab94584a864f911e8ff4caa9cab996ce4716a Author: James Netherton <jamesnether...@gmail.com> AuthorDate: Wed Feb 24 07:24:15 2021 +0000 LRA native support Fixes #793 --- .../ROOT/pages/reference/extensions/lra.adoc | 8 +- .../ROOT/partials/reference/others/lra.adoc | 6 +- extensions-jvm/lra/integration-test/pom.xml | 83 --------- .../quarkus/component/lra/it/LraResource.java | 48 ------ extensions-jvm/pom.xml | 1 - .../lra/deployment/pom.xml | 12 ++ .../component/lra/deployment/LraProcessor.java | 16 -- {extensions-jvm => extensions}/lra/pom.xml | 1 - {extensions-jvm => extensions}/lra/runtime/pom.xml | 23 +-- .../main/resources/META-INF/quarkus-extension.yaml | 3 +- extensions/pom.xml | 1 + integration-tests/lra/pom.xml | 190 +++++++++++++++++++++ .../quarkus/component/lra/it/LraResource.java | 77 +++++++++ .../camel/quarkus/component/lra/it/LraRoutes.java | 87 ++++++++++ .../component/lra/it/service/CreditService.java | 51 ++++++ .../lra/it/service/OrderManagerService.java | 31 ++-- .../component/lra/it/service/ServiceProducers.java | 24 +-- .../camel/quarkus/component/lra/it/LraIT.java | 16 +- .../camel/quarkus/component/lra/it/LraTest.java | 84 +++++++++ .../quarkus/component/lra/it/LraTestResource.java | 71 ++++++++ integration-tests/pom.xml | 1 + poms/bom/pom.xml | 6 + tooling/scripts/test-categories.yaml | 1 + 23 files changed, 636 insertions(+), 205 deletions(-) diff --git a/docs/modules/ROOT/pages/reference/extensions/lra.adoc b/docs/modules/ROOT/pages/reference/extensions/lra.adoc index f78da9a..e1be3da 100644 --- a/docs/modules/ROOT/pages/reference/extensions/lra.adoc +++ b/docs/modules/ROOT/pages/reference/extensions/lra.adoc @@ -2,15 +2,15 @@ // This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page = LRA :cq-artifact-id: camel-quarkus-lra -:cq-native-supported: false -:cq-status: Preview +:cq-native-supported: true +:cq-status: Stable :cq-description: Camel saga binding for Long-Running-Action framework :cq-deprecated: false :cq-jvm-since: 1.2.0 -:cq-native-since: n/a +:cq-native-since: 1.8.0 [.badges] -[.badge-key]##JVM since##[.badge-supported]##1.2.0## [.badge-key]##Native##[.badge-unsupported]##unsupported## +[.badge-key]##JVM since##[.badge-supported]##1.2.0## [.badge-key]##Native since##[.badge-supported]##1.8.0## Camel saga binding for Long-Running-Action framework diff --git a/docs/modules/ROOT/partials/reference/others/lra.adoc b/docs/modules/ROOT/partials/reference/others/lra.adoc index 6236799..e6ab2ed 100644 --- a/docs/modules/ROOT/partials/reference/others/lra.adoc +++ b/docs/modules/ROOT/partials/reference/others/lra.adoc @@ -2,11 +2,11 @@ // This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page :cq-artifact-id: camel-quarkus-lra :cq-artifact-id-base: lra -:cq-native-supported: false -:cq-status: Preview +:cq-native-supported: true +:cq-status: Stable :cq-deprecated: false :cq-jvm-since: 1.2.0 -:cq-native-since: n/a +:cq-native-since: 1.8.0 :cq-camel-part-name: lra :cq-camel-part-title: LRA :cq-camel-part-description: Camel saga binding for Long-Running-Action framework diff --git a/extensions-jvm/lra/integration-test/pom.xml b/extensions-jvm/lra/integration-test/pom.xml deleted file mode 100644 index 646b854..0000000 --- a/extensions-jvm/lra/integration-test/pom.xml +++ /dev/null @@ -1,83 +0,0 @@ -<?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>1.8.0-SNAPSHOT</version> - <relativePath>../../../poms/build-parent-it/pom.xml</relativePath> - </parent> - - <artifactId>camel-quarkus-lra-integration-test</artifactId> - <name>Camel Quarkus :: LRA :: Integration Test</name> - <description>Integration tests for Camel Quarkus LRA extension</description> - - <dependencyManagement> - <dependencies> - <dependency> - <groupId>org.apache.camel.quarkus</groupId> - <artifactId>camel-quarkus-bom-test</artifactId> - <version>${project.version}</version> - <type>pom</type> - <scope>import</scope> - </dependency> - </dependencies> - </dependencyManagement> - - <dependencies> - <dependency> - <groupId>org.apache.camel.quarkus</groupId> - <artifactId>camel-quarkus-lra</artifactId> - </dependency> - <dependency> - <groupId>io.quarkus</groupId> - <artifactId>quarkus-resteasy</artifactId> - </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> - - <!-- 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-lra-deployment</artifactId> - <version>${project.version}</version> - <type>pom</type> - <scope>test</scope> - <exclusions> - <exclusion> - <groupId>*</groupId> - <artifactId>*</artifactId> - </exclusion> - </exclusions> - </dependency> - </dependencies> - -</project> diff --git a/extensions-jvm/lra/integration-test/src/main/java/org/apache/camel/quarkus/component/lra/it/LraResource.java b/extensions-jvm/lra/integration-test/src/main/java/org/apache/camel/quarkus/component/lra/it/LraResource.java deleted file mode 100644 index fdc7518..0000000 --- a/extensions-jvm/lra/integration-test/src/main/java/org/apache/camel/quarkus/component/lra/it/LraResource.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.lra.it; - -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.camel.CamelContext; -import org.jboss.logging.Logger; - -@Path("/lra") -@ApplicationScoped -public class LraResource { - - private static final Logger LOG = Logger.getLogger(LraResource.class); - - private static final String OTHER_LRA = "lra"; - @Inject - CamelContext context; - - @Path("/load/other/lra") - @GET - @Produces(MediaType.TEXT_PLAIN) - public Response loadOtherLra() throws Exception { - /* This is an autogenerated test */ - /* No way to test a Camel artifact of kind "other" */ - return Response.ok().build(); - } -} diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml index 994f12c..9c49414 100644 --- a/extensions-jvm/pom.xml +++ b/extensions-jvm/pom.xml @@ -86,7 +86,6 @@ <module>language</module> <module>ldap</module> <module>ldif</module> - <module>lra</module> <module>lucene</module> <module>management</module> <module>milo</module> diff --git a/extensions-jvm/lra/deployment/pom.xml b/extensions/lra/deployment/pom.xml similarity index 83% rename from extensions-jvm/lra/deployment/pom.xml rename to extensions/lra/deployment/pom.xml index 32dce4e..dd85366 100644 --- a/extensions-jvm/lra/deployment/pom.xml +++ b/extensions/lra/deployment/pom.xml @@ -31,11 +31,23 @@ <dependencies> <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-rest-client-deployment</artifactId> + </dependency> + <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-core-deployment</artifactId> </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-rest-deployment</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-saga-deployment</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-lra</artifactId> </dependency> </dependencies> diff --git a/extensions-jvm/lra/deployment/src/main/java/org/apache/camel/quarkus/component/lra/deployment/LraProcessor.java b/extensions/lra/deployment/src/main/java/org/apache/camel/quarkus/component/lra/deployment/LraProcessor.java similarity index 69% rename from extensions-jvm/lra/deployment/src/main/java/org/apache/camel/quarkus/component/lra/deployment/LraProcessor.java rename to extensions/lra/deployment/src/main/java/org/apache/camel/quarkus/component/lra/deployment/LraProcessor.java index f463bd4..d851791 100644 --- a/extensions-jvm/lra/deployment/src/main/java/org/apache/camel/quarkus/component/lra/deployment/LraProcessor.java +++ b/extensions/lra/deployment/src/main/java/org/apache/camel/quarkus/component/lra/deployment/LraProcessor.java @@ -18,18 +18,12 @@ package org.apache.camel.quarkus.component.lra.deployment; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.deployment.annotations.ExecutionTime; -import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.FeatureBuildItem; -import io.quarkus.deployment.pkg.steps.NativeBuild; -import org.apache.camel.quarkus.core.JvmOnlyRecorder; import org.apache.camel.quarkus.core.deployment.spi.RoutesBuilderClassExcludeBuildItem; import org.apache.camel.service.lra.LRASagaRoutes; -import org.jboss.logging.Logger; class LraProcessor { - private static final Logger LOG = Logger.getLogger(LraProcessor.class); private static final String FEATURE = "camel-lra"; @BuildStep @@ -37,16 +31,6 @@ class LraProcessor { return new FeatureBuildItem(FEATURE); } - /** - * Remove this once this extension starts supporting the native mode. - */ - @BuildStep(onlyIf = NativeBuild.class) - @Record(value = ExecutionTime.RUNTIME_INIT) - void warnJvmInNative(JvmOnlyRecorder recorder) { - JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time - recorder.warnJvmInNative(FEATURE); // warn at runtime - } - @BuildStep void excludeLraRoutes(BuildProducer<RoutesBuilderClassExcludeBuildItem> routesBuilderClassExcludes) { routesBuilderClassExcludes.produce(RoutesBuilderClassExcludeBuildItem.ofClass(LRASagaRoutes.class)); diff --git a/extensions-jvm/lra/pom.xml b/extensions/lra/pom.xml similarity index 97% rename from extensions-jvm/lra/pom.xml rename to extensions/lra/pom.xml index 414bf67..c7d2837 100644 --- a/extensions-jvm/lra/pom.xml +++ b/extensions/lra/pom.xml @@ -33,6 +33,5 @@ <modules> <module>deployment</module> <module>runtime</module> - <module>integration-test</module> </modules> </project> diff --git a/extensions-jvm/lra/runtime/pom.xml b/extensions/lra/runtime/pom.xml similarity index 89% rename from extensions-jvm/lra/runtime/pom.xml rename to extensions/lra/runtime/pom.xml index 5f51bca..70d64e4 100644 --- a/extensions-jvm/lra/runtime/pom.xml +++ b/extensions/lra/runtime/pom.xml @@ -32,6 +32,7 @@ <properties> <camel.quarkus.jvmSince>1.2.0</camel.quarkus.jvmSince> + <camel.quarkus.nativeSince>1.8.0</camel.quarkus.nativeSince> </properties> <dependencyManagement> @@ -48,22 +49,24 @@ <dependencies> <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-rest-client</artifactId> + </dependency> + <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-core</artifactId> </dependency> <dependency> - <groupId>org.apache.camel</groupId> - <artifactId>camel-lra</artifactId> - <exclusions> - <exclusion> - <groupId>jakarta.xml.bind</groupId> - <artifactId>jakarta.xml.bind-api</artifactId> - </exclusion> - </exclusions> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-rest</artifactId> </dependency> <dependency> - <groupId>org.jboss.spec.javax.xml.bind</groupId> - <artifactId>jboss-jaxb-api_2.3_spec</artifactId> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-saga</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-lra</artifactId> </dependency> </dependencies> diff --git a/extensions-jvm/lra/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/lra/runtime/src/main/resources/META-INF/quarkus-extension.yaml similarity index 97% rename from extensions-jvm/lra/runtime/src/main/resources/META-INF/quarkus-extension.yaml rename to extensions/lra/runtime/src/main/resources/META-INF/quarkus-extension.yaml index 1c2e713..42ce14b 100644 --- a/extensions-jvm/lra/runtime/src/main/resources/META-INF/quarkus-extension.yaml +++ b/extensions/lra/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -24,9 +24,8 @@ name: "Camel LRA" description: "Camel saga binding for Long-Running-Action framework" metadata: - unlisted: true guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/lra.html" categories: - "integration" status: - - "preview" + - "stable" diff --git a/extensions/pom.xml b/extensions/pom.xml index 467ea84..1694dee 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -162,6 +162,7 @@ <module>kudu</module> <module>leveldb</module> <module>log</module> + <module>lra</module> <module>lumberjack</module> <module>lzf</module> <module>mail</module> diff --git a/integration-tests/lra/pom.xml b/integration-tests/lra/pom.xml new file mode 100644 index 0000000..677d365 --- /dev/null +++ b/integration-tests/lra/pom.xml @@ -0,0 +1,190 @@ +<?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-integration-tests</artifactId> + <version>1.8.0-SNAPSHOT</version> + </parent> + + <artifactId>camel-quarkus-integration-test-lra</artifactId> + <name>Camel Quarkus :: Integration Tests :: LRA</name> + <description>Integration tests for Camel Quarkus LRA extension</description> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-bom-test</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-bean</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-direct</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-log</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-lra</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-main</artifactId> + </dependency> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-resteasy</artifactId> + </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> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-integration-testcontainers-support</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.awaitility</groupId> + <artifactId>awaitility</artifactId> + <scope>test</scope> + </dependency> + + <!-- 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-bean-deployment</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-direct-deployment</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-log-deployment</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-lra-deployment</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-main-deployment</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + + <profiles> + <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> + </profiles> + +</project> diff --git a/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/LraResource.java b/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/LraResource.java new file mode 100644 index 0000000..6d9a83c --- /dev/null +++ b/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/LraResource.java @@ -0,0 +1,77 @@ +/* + * 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.lra.it; + +import java.net.URI; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.camel.FluentProducerTemplate; +import org.apache.camel.quarkus.component.lra.it.service.CreditService; +import org.apache.camel.quarkus.component.lra.it.service.OrderManagerService; + +@Path("/lra") +@ApplicationScoped +public class LraResource { + + @Inject + FluentProducerTemplate producerTemplate; + + @Inject + CreditService creditService; + + @Inject + OrderManagerService orderManagerService; + + @Path("/order") + @POST + @Produces(MediaType.TEXT_PLAIN) + public Response createOrder(@QueryParam("amount") int amount, @QueryParam("fail") boolean fail) throws Exception { + try { + producerTemplate.to("direct:saga") + .withHeader("amount", amount) + .withHeader("fail", fail) + .request(); + } catch (Exception e) { + return Response.serverError().build(); + } + + return Response.created(new URI("https://camel.apache.org")).build(); + } + + @Path("/order/count") + @GET + @Produces(MediaType.TEXT_PLAIN) + public int getOrderCount() { + return orderManagerService.getOrders().size(); + } + + @Path("/credit/available") + @GET + @Produces(MediaType.TEXT_PLAIN) + public int getAvailableCredit() { + return creditService.getCredit(); + } +} diff --git a/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/LraRoutes.java b/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/LraRoutes.java new file mode 100644 index 0000000..92c4c2f --- /dev/null +++ b/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/LraRoutes.java @@ -0,0 +1,87 @@ +/* + * 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.lra.it; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.SagaPropagation; +import org.apache.camel.quarkus.component.lra.it.service.CreditService; +import org.apache.camel.quarkus.component.lra.it.service.OrderManagerService; + +@ApplicationScoped +public class LraRoutes extends RouteBuilder { + + @Inject + CreditService creditService; + + @Inject + OrderManagerService orderManagerService; + + @Override + public void configure() throws Exception { + from("direct:saga") + .saga().propagation(SagaPropagation.REQUIRES_NEW) + .log("Creating a new order") + .to("direct:newOrder") + .log("Taking the credit") + .to("direct:reserveCredit") + .log("Finalizing") + .to("direct:finalize") + .log("Done!"); + + // Order service + from("direct:newOrder") + .saga() + .propagation(SagaPropagation.MANDATORY) + .compensation("direct:cancelOrder") + .transform().header(Exchange.SAGA_LONG_RUNNING_ACTION) + .bean(orderManagerService, "newOrder") + .log("Order ${body} created"); + + from("direct:cancelOrder") + .transform().header(Exchange.SAGA_LONG_RUNNING_ACTION) + .bean(orderManagerService, "cancelOrder") + .log("Order ${body} cancelled"); + + // Credit service + from("direct:reserveCredit") + .saga() + .propagation(SagaPropagation.MANDATORY) + .compensation("direct:refundCredit") + .transform().header(Exchange.SAGA_LONG_RUNNING_ACTION) + .bean(creditService, "reserveCredit") + .log("Credit ${header.amount} reserved in action ${body}"); + + from("direct:refundCredit") + .transform().header(Exchange.SAGA_LONG_RUNNING_ACTION) + .bean(creditService, "refundCredit") + .log("Credit for action ${body} refunded"); + + // Final actions + from("direct:finalize") + .saga().propagation(SagaPropagation.NOT_SUPPORTED) + .choice() + .when(header("fail").isEqualTo(true)) + .process(x -> { + throw new Exception("fail"); + }) + .end(); + } +} diff --git a/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/service/CreditService.java b/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/service/CreditService.java new file mode 100644 index 0000000..37852e5 --- /dev/null +++ b/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/service/CreditService.java @@ -0,0 +1,51 @@ +/* + * 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.lra.it.service; + +import java.util.HashMap; +import java.util.Map; + +import io.quarkus.runtime.annotations.RegisterForReflection; +import org.apache.camel.Header; + +@RegisterForReflection(fields = false) +public class CreditService { + + private int totalCredit; + + private Map<String, Integer> reservations = new HashMap<>(); + + public CreditService(int totalCredit) { + this.totalCredit = totalCredit; + } + + public synchronized void reserveCredit(String id, @Header("amount") int amount) { + int credit = getCredit(); + if (amount > credit) { + throw new IllegalStateException("Insufficient credit"); + } + reservations.put(id, amount); + } + + public synchronized void refundCredit(String id) { + reservations.remove(id); + } + + public synchronized int getCredit() { + return totalCredit - reservations.values().stream().reduce(0, (a, b) -> a + b); + } +} diff --git a/extensions-jvm/lra/integration-test/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java b/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/service/OrderManagerService.java similarity index 58% copy from extensions-jvm/lra/integration-test/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java copy to integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/service/OrderManagerService.java index a0079c7..9cb24fc 100644 --- a/extensions-jvm/lra/integration-test/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java +++ b/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/service/OrderManagerService.java @@ -14,21 +14,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.quarkus.component.lra.it; +package org.apache.camel.quarkus.component.lra.it.service; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.RestAssured; -import org.junit.jupiter.api.Test; +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; -@QuarkusTest -class LraTest { +import io.quarkus.runtime.annotations.RegisterForReflection; - @Test - public void loadOtherLra() { - /* A simple autogenerated test */ - RestAssured.get("/lra/load/other/lra") - .then() - .statusCode(200); +@RegisterForReflection(fields = false) +public class OrderManagerService { + + private Set<String> orders = new HashSet<>(); + + public synchronized void newOrder(String id) { + orders.add(id); } + public synchronized void cancelOrder(String id) { + orders.remove(id); + } + + public synchronized Set<String> getOrders() { + return new TreeSet<>(orders); + } } diff --git a/extensions-jvm/lra/integration-test/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java b/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/service/ServiceProducers.java similarity index 66% copy from extensions-jvm/lra/integration-test/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java copy to integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/service/ServiceProducers.java index a0079c7..639390f 100644 --- a/extensions-jvm/lra/integration-test/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java +++ b/integration-tests/lra/src/main/java/org/apache/camel/quarkus/component/lra/it/service/ServiceProducers.java @@ -14,21 +14,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.quarkus.component.lra.it; +package org.apache.camel.quarkus.component.lra.it.service; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.RestAssured; -import org.junit.jupiter.api.Test; +import javax.inject.Singleton; -@QuarkusTest -class LraTest { +public class ServiceProducers { - @Test - public void loadOtherLra() { - /* A simple autogenerated test */ - RestAssured.get("/lra/load/other/lra") - .then() - .statusCode(200); + @javax.enterprise.inject.Produces + @Singleton + public CreditService creditService() { + return new CreditService(100); } + @javax.enterprise.inject.Produces + @Singleton + public OrderManagerService orderManagerService() { + return new OrderManagerService(); + } } diff --git a/extensions-jvm/lra/integration-test/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java b/integration-tests/lra/src/test/java/org/apache/camel/quarkus/component/lra/it/LraIT.java similarity index 71% rename from extensions-jvm/lra/integration-test/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java rename to integration-tests/lra/src/test/java/org/apache/camel/quarkus/component/lra/it/LraIT.java index a0079c7..dda7b3d 100644 --- a/extensions-jvm/lra/integration-test/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java +++ b/integration-tests/lra/src/test/java/org/apache/camel/quarkus/component/lra/it/LraIT.java @@ -16,19 +16,9 @@ */ package org.apache.camel.quarkus.component.lra.it; -import io.quarkus.test.junit.QuarkusTest; -import io.restassured.RestAssured; -import org.junit.jupiter.api.Test; +import io.quarkus.test.junit.NativeImageTest; -@QuarkusTest -class LraTest { - - @Test - public void loadOtherLra() { - /* A simple autogenerated test */ - RestAssured.get("/lra/load/other/lra") - .then() - .statusCode(200); - } +@NativeImageTest +class LraIT extends LraTest { } diff --git a/integration-tests/lra/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java b/integration-tests/lra/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java new file mode 100644 index 0000000..1052958 --- /dev/null +++ b/integration-tests/lra/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTest.java @@ -0,0 +1,84 @@ +/* + * 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.lra.it; + +import java.util.concurrent.TimeUnit; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.RestAssured; +import org.junit.jupiter.api.Test; + +import static org.awaitility.Awaitility.await; + +@QuarkusTest +@QuarkusTestResource(LraTestResource.class) +class LraTest { + + @Test + public void testLraTransaction() { + // Create valid orders + RestAssured.given() + .queryParam("amount", 20) + .queryParam("fail", false) + .post("/lra/order") + .then() + .statusCode(201); + + RestAssured.given() + .queryParam("amount", 70) + .queryParam("fail", false) + .post("/lra/order") + .then() + .statusCode(201); + + RestAssured.given() + .queryParam("amount", 5) + .queryParam("fail", false) + .post("/lra/order") + .then() + .statusCode(201); + + // Force failure scenario + RestAssured.given() + .queryParam("amount", 20) + .queryParam("fail", true) + .post("/lra/order") + .then() + .statusCode(500); + + // Verify count of valid orders + await().atMost(10, TimeUnit.SECONDS).until(() -> { + return RestAssured.get("/lra/order/count") + .then() + .statusCode(200) + .extract() + .body() + .asString().equals("3"); + }); + + // Verify credit remaining + await().atMost(10, TimeUnit.SECONDS).until(() -> { + return RestAssured.get("/lra/credit/available") + .then() + .statusCode(200) + .extract() + .body() + .asString().equals("5"); + }); + } +} diff --git a/integration-tests/lra/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTestResource.java b/integration-tests/lra/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTestResource.java new file mode 100644 index 0000000..aa539bf --- /dev/null +++ b/integration-tests/lra/src/test/java/org/apache/camel/quarkus/component/lra/it/LraTestResource.java @@ -0,0 +1,71 @@ +/* + * 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.lra.it; + +import java.util.Map; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; +import org.apache.camel.quarkus.test.AvailablePortFinder; +import org.apache.camel.util.CollectionHelper; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +public class LraTestResource implements QuarkusTestResourceLifecycleManager { + + private static final Integer LRA_PORT = AvailablePortFinder.getNextAvailable(); + // TODO: Use a newer lra-coordinator + // https://github.com/apache/camel-quarkus/issues/2285 + private static final String LRA_IMAGE = "jbosstm/lra-coordinator:5.9.3.Final"; + + private GenericContainer container; + + @Override + public Map<String, String> start() { + try { + container = new GenericContainer(LRA_IMAGE) + .withNetworkMode("host") + .withCommand( + "java", + "-jar", + "/deployments/lra-coordinator-swarm.jar", + "-Djava.net.preferIPv4Stack=true", + "-Dswarm.http.port=" + LRA_PORT) + .waitingFor(Wait.forLogMessage(".*WFSWARM99999.*", 1)); + + container.start(); + + return CollectionHelper.mapOf( + "camel.lra.coordinator-url", + String.format("http://%s:%d", container.getContainerIpAddress(), LRA_PORT), + "camel.lra.local-participant-url", + String.format("http://localhost:%s", System.getProperty("quarkus.http.test-port", "8081"))); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void stop() { + try { + if (container != null) { + container.stop(); + } + } catch (Exception e) { + // ignored + } + } +} diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 5b4c436..58c5ce4 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -138,6 +138,7 @@ <module>kubernetes</module> <module>kudu</module> <module>leveldb</module> + <module>lra</module> <module>lumberjack</module> <module>mail</module> <module>master</module> diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml index baaf2b3..8b0e2c9 100644 --- a/poms/bom/pom.xml +++ b/poms/bom/pom.xml @@ -1397,6 +1397,12 @@ <groupId>org.apache.camel</groupId> <artifactId>camel-lra</artifactId> <version>${camel.version}</version> + <exclusions> + <exclusion> + <groupId>org.apache.cxf</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.apache.camel</groupId> diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml index 7549a8a..342cff9 100644 --- a/tooling/scripts/test-categories.yaml +++ b/tooling/scripts/test-categories.yaml @@ -90,6 +90,7 @@ foundation: - jta - jsonpath - kamelet + - lra - micrometer - quartz - saga