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
commit 2858b941a528f900ca150ded9d4f5b76b3cb2648 Author: James Netherton <jamesnether...@gmail.com> AuthorDate: Tue Aug 4 07:21:22 2020 +0100 Add master extension Fixes #711 --- docs/modules/ROOT/pages/extensions/master.adoc | 28 ++++ .../pages/list-of-camel-quarkus-extensions.adoc | 4 +- .../main/resources/META-INF/quarkus-extension.yaml | 2 + extensions/master/deployment/pom.xml | 63 ++++++++ .../master/deployment/MasterProcessor.java | 30 ++++ extensions/master/pom.xml | 39 +++++ extensions/master/runtime/pom.xml | 94 +++++++++++ .../main/resources/META-INF/quarkus-extension.yaml | 8 +- extensions/pom.xml | 1 + .../support/process/QuarkusProcessExecutor.java | 7 +- integration-tests/master/pom.xml | 180 +++++++++++++++++++++ .../component/master/it/MasterResource.java | 36 +++++ .../quarkus/component/master/it/MasterRoutes.java | 48 ++++++ .../src/main/resources/application.properties | 18 +++ .../quarkus/component/master/it/MasterIT.java | 24 +++ .../quarkus/component/master/it/MasterTest.java | 96 +++++++++++ integration-tests/pom.xml | 1 + poms/bom/pom.xml | 15 ++ tooling/scripts/test-categories.yaml | 3 +- 19 files changed, 691 insertions(+), 6 deletions(-) diff --git a/docs/modules/ROOT/pages/extensions/master.adoc b/docs/modules/ROOT/pages/extensions/master.adoc new file mode 100644 index 0000000..0ee6688 --- /dev/null +++ b/docs/modules/ROOT/pages/extensions/master.adoc @@ -0,0 +1,28 @@ +// Do not edit directly! +// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page + +[[master]] += Master + +[.badges] +[.badge-key]##Since Camel Quarkus##[.badge-version]##1.0.0-CR4## [.badge-key]##JVM##[.badge-supported]##supported## [.badge-key]##Native##[.badge-supported]##supported## + +Have only a single consumer in a cluster consuming from a given endpoint; with automatic failover if the JVM dies. + +== What's inside + +* https://camel.apache.org/components/latest/master-component.html[Master component], URI syntax: `master:namespace:delegateUri` + +Please refer to the above link for usage and configuration details. + +== Maven coordinates + +[source,xml] +---- +<dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-master</artifactId> +</dependency> +---- + +Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications. diff --git a/docs/modules/ROOT/pages/list-of-camel-quarkus-extensions.adoc b/docs/modules/ROOT/pages/list-of-camel-quarkus-extensions.adoc index a2e0a2c..67b1359 100644 --- a/docs/modules/ROOT/pages/list-of-camel-quarkus-extensions.adoc +++ b/docs/modules/ROOT/pages/list-of-camel-quarkus-extensions.adoc @@ -18,7 +18,7 @@ In case you are missing some Camel feature in the list: == Camel Components // components: START -Number of Camel components: 155 in 120 JAR artifacts (0 deprecated) +Number of Camel components: 156 in 121 JAR artifacts (0 deprecated) [width="100%",cols="4,1,1,1,5",options="header"] |=== @@ -230,6 +230,8 @@ Number of Camel components: 155 in 120 JAR artifacts (0 deprecated) | xref:extensions/mail.adoc[Mail] | camel-quarkus-mail | Native + Stable | 0.2.0 | Send and receive emails using imap, pop3 and smtp protocols. +| xref:extensions/master.adoc[Master] | camel-quarkus-master | Native + Stable | 1.0.0-CR4 | Have only a single consumer in a cluster consuming from a given endpoint; with automatic failover if the JVM dies. + | xref:extensions/microprofile-metrics.adoc[MicroProfile Metrics] | camel-quarkus-microprofile-metrics | Native + Stable | 0.2.0 | Expose metrics from Camel routes. | xref:extensions/mock.adoc[Mock] | camel-quarkus-mock | Native + Stable | 1.0.0-CR3 | Test routes and mediation rules using mocks. diff --git a/extensions/grok/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/grok/runtime/src/main/resources/META-INF/quarkus-extension.yaml index dd7b4bb..2e38fb8 100644 --- a/extensions/grok/runtime/src/main/resources/META-INF/quarkus-extension.yaml +++ b/extensions/grok/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -27,3 +27,5 @@ metadata: guide: "https://camel.apache.org/camel-quarkus/latest/extensions/grok.html" categories: - "integration" + status: + - "stable" diff --git a/extensions/master/deployment/pom.xml b/extensions/master/deployment/pom.xml new file mode 100644 index 0000000..4eb032d --- /dev/null +++ b/extensions/master/deployment/pom.xml @@ -0,0 +1,63 @@ +<?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-master-parent</artifactId> + <version>1.1.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>camel-quarkus-master-deployment</artifactId> + <name>Camel Quarkus :: Master :: Deployment</name> + + <dependencies> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-core-deployment</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-master</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <annotationProcessorPaths> + <path> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-extension-processor</artifactId> + <version>${quarkus.version}</version> + </path> + </annotationProcessorPaths> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/extensions/master/deployment/src/main/java/org/apache/camel/quarkus/component/master/deployment/MasterProcessor.java b/extensions/master/deployment/src/main/java/org/apache/camel/quarkus/component/master/deployment/MasterProcessor.java new file mode 100644 index 0000000..2ba982d --- /dev/null +++ b/extensions/master/deployment/src/main/java/org/apache/camel/quarkus/component/master/deployment/MasterProcessor.java @@ -0,0 +1,30 @@ +/* + * 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.master.deployment; + +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.FeatureBuildItem; + +class MasterProcessor { + + private static final String FEATURE = "camel-master"; + + @BuildStep + FeatureBuildItem feature() { + return new FeatureBuildItem(FEATURE); + } +} diff --git a/extensions/master/pom.xml b/extensions/master/pom.xml new file mode 100644 index 0000000..f5ba971 --- /dev/null +++ b/extensions/master/pom.xml @@ -0,0 +1,39 @@ +<?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</artifactId> + <version>1.1.0-SNAPSHOT</version> + <relativePath>../../poms/build-parent/pom.xml</relativePath> + </parent> + + <artifactId>camel-quarkus-master-parent</artifactId> + <name>Camel Quarkus :: Master</name> + <packaging>pom</packaging> + + <modules> + <module>deployment</module> + <module>runtime</module> + </modules> +</project> diff --git a/extensions/master/runtime/pom.xml b/extensions/master/runtime/pom.xml new file mode 100644 index 0000000..bb0bfee --- /dev/null +++ b/extensions/master/runtime/pom.xml @@ -0,0 +1,94 @@ +<?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-master-parent</artifactId> + <version>1.1.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>camel-quarkus-master</artifactId> + <name>Camel Quarkus :: Master :: Runtime</name> + <description>Have only a single consumer in a cluster consuming from a given endpoint; with automatic failover if the JVM dies.</description> + + <properties> + <firstVersion>1.0.0-CR4</firstVersion> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-bom</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-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-master</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-maven-plugin</artifactId> + <executions> + <execution> + <id>update-extension-doc-page</id> + <goals><goal>update-extension-doc-page</goal></goals> + <phase>process-classes</phase> + </execution> + </executions> + </plugin> + <plugin> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-bootstrap-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <annotationProcessorPaths> + <path> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-extension-processor</artifactId> + <version>${quarkus.version}</version> + </path> + </annotationProcessorPaths> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/extensions/grok/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/master/runtime/src/main/resources/META-INF/quarkus-extension.yaml similarity index 84% copy from extensions/grok/runtime/src/main/resources/META-INF/quarkus-extension.yaml copy to extensions/master/runtime/src/main/resources/META-INF/quarkus-extension.yaml index dd7b4bb..0791c31 100644 --- a/extensions/grok/runtime/src/main/resources/META-INF/quarkus-extension.yaml +++ b/extensions/master/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -21,9 +21,11 @@ # mvn -N cq:update-quarkus-metadata # --- -name: "Camel Grok" -description: "Unmarshal unstructured data to objects using Logstash based Grok patterns" +name: "Camel Master" +description: "Have only a single consumer in a cluster consuming from a given endpoint; with automatic failover if the JVM dies" metadata: - guide: "https://camel.apache.org/camel-quarkus/latest/extensions/grok.html" + guide: "https://camel.apache.org/camel-quarkus/latest/extensions/master.html" categories: - "integration" + status: + - "stable" diff --git a/extensions/pom.xml b/extensions/pom.xml index 62cf6b7..8e10044 100644 --- a/extensions/pom.xml +++ b/extensions/pom.xml @@ -125,6 +125,7 @@ <module>log</module> <module>lzf</module> <module>mail</module> + <module>master</module> <module>microprofile-fault-tolerance</module> <module>microprofile-health</module> <module>microprofile-metrics</module> diff --git a/integration-tests-support/process-executor-support/src/main/java/org/apache/camel/quarkus/test/support/process/QuarkusProcessExecutor.java b/integration-tests-support/process-executor-support/src/main/java/org/apache/camel/quarkus/test/support/process/QuarkusProcessExecutor.java index 4aa9249..ee1b409 100644 --- a/integration-tests-support/process-executor-support/src/main/java/org/apache/camel/quarkus/test/support/process/QuarkusProcessExecutor.java +++ b/integration-tests-support/process-executor-support/src/main/java/org/apache/camel/quarkus/test/support/process/QuarkusProcessExecutor.java @@ -67,7 +67,12 @@ public class QuarkusProcessExecutor { final boolean isWindows = System.getProperty("os.name").toLowerCase().contains("windows"); final String javaExecutable = System.getProperty("java.home") + (isWindows ? "/bin/java.exe" : "/bin/java"); String runner = System.getProperty("quarkus.runner"); - if (runner != null && !Paths.get(runner).toFile().exists()) { + + if (runner == null) { + throw new IllegalStateException("The quarkus.runner system property is not set"); + } + + if (!Paths.get(runner).toFile().exists()) { throw new IllegalStateException("Quarkus application runner does not exist: " + runner); } diff --git a/integration-tests/master/pom.xml b/integration-tests/master/pom.xml new file mode 100644 index 0000000..f1eb225 --- /dev/null +++ b/integration-tests/master/pom.xml @@ -0,0 +1,180 @@ +<?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.1.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>camel-quarkus-integration-test-master</artifactId> + <name>Camel Quarkus :: Integration Tests :: Master</name> + <description>Integration tests for Camel Quarkus Master extension</description> + + <properties> + <!-- mvnd, a.k.a. Maven Daemon: https://github.com/gnodet/mvnd --> + <!-- The following rule tells mvnd to build the listed deployment modules before this module. --> + <!-- This is important because mvnd builds modules in parallel by default. The deployment modules are not --> + <!-- explicit dependencies of this module in the Maven sense, although they are required by the Quarkus Maven plugin. --> + <!-- Please update rule whenever you change the dependencies of this module by running --> + <!-- mvn process-resources -Pformat from the root directory --> + <mvnd.builder.rule>camel-quarkus-file-deployment,camel-quarkus-master-deployment,camel-quarkus-support-policy-deployment</mvnd.builder.rule> + + <quarkus.runner>${project.build.directory}/${project.artifactId}-${project.version}-runner.jar</quarkus.runner> + </properties> + + <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-file</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-master</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-microprofile-health</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-timer</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-tests-process-executor-support</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.awaitility</groupId> + <artifactId>awaitility</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>build</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <!-- Move surefire:test to integration-test phase to be able to run + java -jar target/*runner.jar from a test --> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <executions> + <execution> + <id>default-test</id> + <goals> + <goal>test</goal> + </goals> + <phase>integration-test</phase> + <configuration> + <systemProperties> + <quarkus.runner>${quarkus.runner}</quarkus.runner> + </systemProperties> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>native</id> + <activation> + <property> + <name>native</name> + </property> + </activation> + <properties> + <quarkus.package.type>native</quarkus.package.type> + <quarkus.runner>${project.build.directory}/${project.artifactId}-${project.version}-runner</quarkus.runner> + </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> + <configuration> + <systemProperties> + <quarkus.runner>${quarkus.runner}</quarkus.runner> + </systemProperties> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --git a/integration-tests/master/src/main/java/org/apache/camel/quarkus/component/master/it/MasterResource.java b/integration-tests/master/src/main/java/org/apache/camel/quarkus/component/master/it/MasterResource.java new file mode 100644 index 0000000..eb3a44b --- /dev/null +++ b/integration-tests/master/src/main/java/org/apache/camel/quarkus/component/master/it/MasterResource.java @@ -0,0 +1,36 @@ +/* + * 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.master.it; + +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.apache.camel.CamelContext; + +@Path("/master") +public class MasterResource { + + @Inject + private CamelContext camelContext; + + @Path("/camel/stop") + @GET + public void stopCamelContext() { + camelContext.stop(); + } +} diff --git a/integration-tests/master/src/main/java/org/apache/camel/quarkus/component/master/it/MasterRoutes.java b/integration-tests/master/src/main/java/org/apache/camel/quarkus/component/master/it/MasterRoutes.java new file mode 100644 index 0000000..4bb7140 --- /dev/null +++ b/integration-tests/master/src/main/java/org/apache/camel/quarkus/component/master/it/MasterRoutes.java @@ -0,0 +1,48 @@ +/* + * 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.master.it; + +import java.util.concurrent.TimeUnit; + +import javax.enterprise.context.ApplicationScoped; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.cluster.FileLockClusterService; +import org.eclipse.microprofile.config.inject.ConfigProperty; + +@ApplicationScoped +public class MasterRoutes extends RouteBuilder { + + @ConfigProperty(name = "application.id") + String applicationId; + + @Override + public void configure() throws Exception { + FileLockClusterService service = new FileLockClusterService(); + service.setRoot("target/cluster"); + service.setAcquireLockDelay(1, TimeUnit.SECONDS); + service.setAcquireLockInterval(1, TimeUnit.SECONDS); + getContext().addService(service); + + // Output the id of the application into a file + from("master:ns:timer:test?period=100") + .setBody(constant(applicationId)) + .setHeader(Exchange.FILE_NAME, constant("leader.txt")) + .to("file:target/cluster/"); + } +} diff --git a/integration-tests/master/src/main/resources/application.properties b/integration-tests/master/src/main/resources/application.properties new file mode 100644 index 0000000..0054a29 --- /dev/null +++ b/integration-tests/master/src/main/resources/application.properties @@ -0,0 +1,18 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- + +application.id = leader diff --git a/integration-tests/master/src/test/java/org/apache/camel/quarkus/component/master/it/MasterIT.java b/integration-tests/master/src/test/java/org/apache/camel/quarkus/component/master/it/MasterIT.java new file mode 100644 index 0000000..e734a28 --- /dev/null +++ b/integration-tests/master/src/test/java/org/apache/camel/quarkus/component/master/it/MasterIT.java @@ -0,0 +1,24 @@ +/* + * 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.master.it; + +import io.quarkus.test.junit.NativeImageTest; + +@NativeImageTest +class MasterIT extends MasterTest { + +} diff --git a/integration-tests/master/src/test/java/org/apache/camel/quarkus/component/master/it/MasterTest.java b/integration-tests/master/src/test/java/org/apache/camel/quarkus/component/master/it/MasterTest.java new file mode 100644 index 0000000..c1c10de --- /dev/null +++ b/integration-tests/master/src/test/java/org/apache/camel/quarkus/component/master/it/MasterTest.java @@ -0,0 +1,96 @@ +/* + * 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.master.it; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.concurrent.TimeUnit; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.RestAssured; +import org.apache.camel.quarkus.test.support.process.QuarkusProcessExecutor; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.Test; +import org.zeroturnaround.exec.StartedProcess; + +@QuarkusTest +class MasterTest { + + @Test + public void testFailover() throws IOException { + // Start secondary application process + QuarkusProcessExecutor quarkusProcessExecutor = new QuarkusProcessExecutor("-Dapplication.id=follower"); + StartedProcess process = quarkusProcessExecutor.start(); + + // Wait until the process is fully initialized + awaitStartup(quarkusProcessExecutor); + + try { + // Verify that this process is the cluster leader + Awaitility.await().atMost(10, TimeUnit.SECONDS).with().until(() -> { + return readLeaderFile().equals("leader"); + }); + + // Stop camel to trigger failover + RestAssured.given() + .get("/master/camel/stop") + .then() + .statusCode(204); + + // Verify that the secondary application has been elected as the cluster leader + Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> { + return readLeaderFile().equals("follower"); + }); + } finally { + if (process != null && process.getProcess().isAlive()) { + process.getProcess().destroy(); + } + } + } + + private void awaitStartup(QuarkusProcessExecutor quarkusProcessExecutor) { + Awaitility.await().atMost(10, TimeUnit.SECONDS).pollDelay(1, TimeUnit.SECONDS).until(() -> { + return isApplicationHealthy(quarkusProcessExecutor.getHttpPort()); + }); + } + + private boolean isApplicationHealthy(int port) { + try { + int status = RestAssured.given() + .port(port) + .get("/health") + .then() + .extract() + .statusCode(); + return status == 200; + } catch (Exception e) { + return false; + } + } + + private String readLeaderFile() throws IOException { + Path path = Paths.get("target/cluster/leader.txt"); + if (path.toFile().exists()) { + byte[] bytes = Files.readAllBytes(path); + return new String(bytes, StandardCharsets.UTF_8); + } + return ""; + } +} diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 3796189..85b7074 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -110,6 +110,7 @@ <module>kubernetes</module> <module>kudu</module> <module>mail</module> + <module>master</module> <module>messaging</module> <module>microprofile</module> <module>mock</module> diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml index ff125e1..4d33264 100644 --- a/poms/bom/pom.xml +++ b/poms/bom/pom.xml @@ -851,6 +851,11 @@ </dependency> <dependency> <groupId>org.apache.camel</groupId> + <artifactId>camel-master</artifactId> + <version>${camel.version}</version> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> <artifactId>camel-microprofile-config</artifactId> <version>${camel.version}</version> </dependency> @@ -2276,6 +2281,16 @@ </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-master</artifactId> + <version>${camel-quarkus.version}</version> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-master-deployment</artifactId> + <version>${camel-quarkus.version}</version> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-microprofile-fault-tolerance</artifactId> <version>${camel-quarkus.version}</version> </dependency> diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml index bcc4153..ceb568a 100644 --- a/tooling/scripts/test-categories.yaml +++ b/tooling/scripts/test-categories.yaml @@ -85,8 +85,9 @@ misc: - graphql - grok - jolt - - mustache + - master - mock + - mustache - pdf - qute - stream