This is an automated email from the ASF dual-hosted git repository. jamesnetherton pushed a commit to branch 2.13.x in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit e8c1f6522badb1b1a47601e3bd28c25e35f7f94c Author: James Netherton <jamesnether...@gmail.com> AuthorDate: Fri Feb 3 16:45:03 2023 +0000 Improve yaml-dsl documentation and add simple test scenarios Fixes #4487 --- .../ROOT/pages/reference/extensions/yaml-dsl.adoc | 122 ++++++++++++++++++++- .../pages/user-guide/defining-camel-routes.adoc | 72 ++++++++++++ extensions-core/yaml-dsl/deployment/pom.xml | 16 +++ .../yaml/deployment/YamlDslClassicModeTest.java | 85 ++++++++++++++ .../src/test/resources/routes/routes.yaml | 11 +- .../yaml-dsl/runtime/src/main/doc/usage.adoc | 111 +++++++++++++++++++ .../quarkus/dsl/yaml/YamlDslConfiguration.java | 8 +- integration-tests/main-yaml/pom.xml | 28 +---- .../camel/quarkus/main/CoreMainYamlResource.java | 23 +++- .../apache/camel/quarkus/main/CustomException.java | 29 +++++ .../org/apache/camel/quarkus/main/ErrorBean.java | 26 +++++ .../apache/camel/quarkus/main/GreetingBean.java | 32 ++++++ .../src/main/resources/application.properties | 2 +- .../src/main/resources/routes/my-rests.yaml | 23 +++- .../src/main/resources/routes/my-routes.yaml | 48 +++++++- .../routes/{my-rests.yaml => my-templates.yaml} | 27 +++-- .../camel/quarkus/main/CoreMainYamlTest.java | 60 +++++++++- 17 files changed, 669 insertions(+), 54 deletions(-) diff --git a/docs/modules/ROOT/pages/reference/extensions/yaml-dsl.adoc b/docs/modules/ROOT/pages/reference/extensions/yaml-dsl.adoc index ebabf902d0..444adae77e 100644 --- a/docs/modules/ROOT/pages/reference/extensions/yaml-dsl.adoc +++ b/docs/modules/ROOT/pages/reference/extensions/yaml-dsl.adoc @@ -44,6 +44,124 @@ ifeval::[{doc-show-user-guide-link} == true] Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications. endif::[] +[id="extensions-yaml-dsl-usage"] +== Usage +[id="extensions-yaml-dsl-usage-native-mode"] +=== Native mode + +The following constructs when defined within Camel YAML DSL markup, require you to register classes for reflection. Refer to the xref:user-guide/native-mode.adoc#reflection[Native mode] guide for details. + +[id="extensions-yaml-dsl-usage-bean-definitions"] +==== Bean definitions + +The YAML DSL provides the capability to define beans as follows. + +[source,yaml] +---- +- beans: + - name: "greetingBean" + type: "org.acme.GreetingBean" + properties: + greeting: "Hello World!" +- route: + id: "my-yaml-route" + from: + uri: "timer:from-yaml?period=1000" + steps: + - to: "bean:greetingBean" +---- + +In this example, the `GreetingBean` class needs to be registered for reflection. This applies to any types that you refer to under the `beans` key in your YAML routes. + +[source,java] +---- +@RegisterForReflection +public class GreetingBean { +} +---- + +[id="extensions-yaml-dsl-usage-exception-handling"] +==== Exception handling + +Camel provides various methods of handling exceptions. Some of these require that any exception classes referenced in their DSL definitions are registered for reflection. + +`*on-exception*` + +[source,yaml] +---- +- on-exception: + handled: + constant: "true" + exception: + - "org.acme.MyHandledException" + steps: + - transform: + constant: "Sorry something went wrong" +---- + +[source,java] +---- +@RegisterForReflection +public class MyHandledException { +} +---- + +`*throw-exception*` + +[source,yaml] +---- +- route: + id: "my-yaml-route" + from: + uri: "direct:start" + steps: + - choice: + when: + - simple: "${body} == 'bad value'" + steps: + - throw-exception: + exception-type: "org.acme.ForcedException" + message: "Forced exception" + otherwise: + steps: + - to: "log:end" +---- + +[source,java] +---- +@RegisterForReflection +public class ForcedException { +} +---- + +`*do-catch*` + +[source,yaml] +---- +- route: + id: "my-yaml-route2" + from: + uri: "direct:tryCatch" + steps: + - do-try: + steps: + - to: "direct:readFile" + do-catch: + - exception: + - "java.io.FileNotFoundException" + steps: + - transform: + constant: "do-catch caught an exception" +---- + +[source,java] +---- +@RegisterForReflection(targets = FileNotFoundException.class) +public class MyClass { +} +---- + + [id="extensions-yaml-dsl-additional-camel-quarkus-configuration"] == Additional Camel Quarkus configuration @@ -54,8 +172,8 @@ endif::[] |icon:lock[title=Fixed at build time] [[quarkus.camel.yaml.flow-mode]]`link:#quarkus.camel.yaml.flow-mode[quarkus.camel.yaml.flow-mode]` -If `true` the YAML DSL support flow-mode which allow to write more concise routes as for EIPs that have their own output like filter, aggregate, split, etc. the `steps` element can be omitted an in that case, the next processing step is automatically wired to the EIP's outputs. -As example, a YAML DSL to process only the timer events from 5 to 10 would look like: `- from: +If `true` the YAML DSL supports flow-mode. This allows you to write more concise routes for EIPs that have their own output like filter, aggregate, split, etc. the `steps` element can be omitted and in that case, the next processing step is automatically wired to the EIPs outputs. +For example, a YAML route to process only the timer events from 5 to 10 would look like: `- from: uri: "timer:tick" steps: - filter: diff --git a/docs/modules/ROOT/pages/user-guide/defining-camel-routes.adoc b/docs/modules/ROOT/pages/user-guide/defining-camel-routes.adoc index 96ee7011d6..4d82d6e409 100644 --- a/docs/modules/ROOT/pages/user-guide/defining-camel-routes.adoc +++ b/docs/modules/ROOT/pages/user-guide/defining-camel-routes.adoc @@ -120,6 +120,78 @@ The route XML should be in the simplified version like: </routeTemplates> ---- +== YAML DSL + +To configure routes with YAML, you must add the `camel-quarkus-yaml-dsl` dependency to the classpath. + +With Camel Main, you can set a property that points to the location of YAML files containing routes, xref:manual::rest-dsl.adoc[REST DSL] and xref:manual::route-template.adoc[Route templates] definitions: + +[source,properties] +---- +camel.main.routes-include-pattern = routes/routes.yaml, routes/rests.yaml, rests/route-template.yaml +---- + +.Route +[source,yaml] +---- +- route: + id: "my-yaml-route" + from: + uri: "timer:from-yaml?period=1000" + steps: + - set-body: + constant: "Hello YAML!" + - to: "log:from-yaml" +---- + +.Rest DSL + +[source,yaml] +---- +- rest: + get: + - path: "/greeting" + to: "direct:greet" + +- route: + id: "rest-route" + from: + uri: "direct:greet" + steps: + - set-body: + constant: "Hello YAML!" +---- + +.Route Templates +[source,yaml] +---- +- route-template: + id: "myTemplate" + parameters: + - name: "name" + - name: "greeting" + defaultValue: "Hello" + - name: "myPeriod" + defaultValue: "3s" + from: + uri: "timer:{{name}}?period={{myPeriod}}" + steps: + - set-body: + expression: + simple: "{{greeting}} ${body}" + - log: "${body}" + +- templated-route: + route-template-ref: "myTemplate" + parameters: + - name: "name" + value: "tick" + - name: "greeting" + value: "Bonjour" + - name: "myPeriod" + value: "5s" +---- + == Other route DSLs * xref:reference/extensions/java-joor-dsl.adoc[Java jOOR] diff --git a/extensions-core/yaml-dsl/deployment/pom.xml b/extensions-core/yaml-dsl/deployment/pom.xml index 9b1272e554..0bf1c6db9c 100644 --- a/extensions-core/yaml-dsl/deployment/pom.xml +++ b/extensions-core/yaml-dsl/deployment/pom.xml @@ -38,6 +38,22 @@ <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-yaml-dsl</artifactId> </dependency> + + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-junit5-internal</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-direct</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel.quarkus</groupId> + <artifactId>camel-quarkus-mock</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/extensions-core/yaml-dsl/deployment/src/test/java/org/apache/camel/quarkus/dsl/yaml/deployment/YamlDslClassicModeTest.java b/extensions-core/yaml-dsl/deployment/src/test/java/org/apache/camel/quarkus/dsl/yaml/deployment/YamlDslClassicModeTest.java new file mode 100644 index 0000000000..f9419867ab --- /dev/null +++ b/extensions-core/yaml-dsl/deployment/src/test/java/org/apache/camel/quarkus/dsl/yaml/deployment/YamlDslClassicModeTest.java @@ -0,0 +1,85 @@ +/* + * 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.dsl.yaml.deployment; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Properties; + +import javax.inject.Inject; + +import io.quarkus.test.QuarkusUnitTest; +import org.apache.camel.CamelContext; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.dsl.yaml.YamlRoutesBuilderLoader; +import org.apache.camel.dsl.yaml.common.YamlDeserializationMode; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.Asset; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class YamlDslClassicModeTest { + @RegisterExtension + static final QuarkusUnitTest CONFIG = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) + .addAsResource("routes/routes.yaml", "routes/routes.yaml") + .addAsResource(applicationProperties(), "application.properties")); + + @Inject + CamelContext context; + + @Inject + ProducerTemplate producerTemplate; + + public static Asset applicationProperties() { + Writer writer = new StringWriter(); + + Properties props = new Properties(); + props.put("camel.main.routes-include-pattern", "routes/routes.yaml"); + props.put("quarkus.camel.yaml.flow-mode", "false"); + + try { + props.store(writer, ""); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return new StringAsset(writer.toString()); + } + + @Test + public void classicModeEnabled() { + String mode = context.getGlobalOptions().get(YamlRoutesBuilderLoader.DESERIALIZATION_MODE); + assertEquals(YamlDeserializationMode.CLASSIC.name(), mode); + } + + @Test + public void classicModeYamlRoute() throws InterruptedException { + MockEndpoint endpoint = context.getEndpoint("mock:split", MockEndpoint.class); + endpoint.expectedBodiesReceived("foo", "bar", "cheese"); + + producerTemplate.sendBody("direct:classicMode", "foo,bar,cheese"); + + endpoint.assertIsSatisfied(5000); + } +} diff --git a/integration-tests/main-yaml/src/main/resources/routes/my-routes.yaml b/extensions-core/yaml-dsl/deployment/src/test/resources/routes/routes.yaml similarity index 84% copy from integration-tests/main-yaml/src/main/resources/routes/my-routes.yaml copy to extensions-core/yaml-dsl/deployment/src/test/resources/routes/routes.yaml index d0a6f533fd..8f46657270 100644 --- a/integration-tests/main-yaml/src/main/resources/routes/my-routes.yaml +++ b/extensions-core/yaml-dsl/deployment/src/test/resources/routes/routes.yaml @@ -18,8 +18,9 @@ - route: id: "my-yaml-route" from: - uri: "timer:from-xml?period=3000" - steps: - - set-body: - constant: "Hello World!!!" - - to: "log:from-yaml" + uri: "direct:classicMode" + steps: + - split: + tokenize: "," + steps: + - to: "mock:split" diff --git a/extensions-core/yaml-dsl/runtime/src/main/doc/usage.adoc b/extensions-core/yaml-dsl/runtime/src/main/doc/usage.adoc new file mode 100644 index 0000000000..9aa928a93c --- /dev/null +++ b/extensions-core/yaml-dsl/runtime/src/main/doc/usage.adoc @@ -0,0 +1,111 @@ +=== Native mode + +The following constructs when defined within Camel YAML DSL markup, require you to register classes for reflection. Refer to the xref:user-guide/native-mode.adoc#reflection[Native mode] guide for details. + +==== Bean definitions + +The YAML DSL provides the capability to define beans as follows. + +[source,yaml] +---- +- beans: + - name: "greetingBean" + type: "org.acme.GreetingBean" + properties: + greeting: "Hello World!" +- route: + id: "my-yaml-route" + from: + uri: "timer:from-yaml?period=1000" + steps: + - to: "bean:greetingBean" +---- + +In this example, the `GreetingBean` class needs to be registered for reflection. This applies to any types that you refer to under the `beans` key in your YAML routes. + +[source,java] +---- +@RegisterForReflection +public class GreetingBean { +} +---- + +==== Exception handling + +Camel provides various methods of handling exceptions. Some of these require that any exception classes referenced in their DSL definitions are registered for reflection. + +`*on-exception*` + +[source,yaml] +---- +- on-exception: + handled: + constant: "true" + exception: + - "org.acme.MyHandledException" + steps: + - transform: + constant: "Sorry something went wrong" +---- + +[source,java] +---- +@RegisterForReflection +public class MyHandledException { +} +---- + +`*throw-exception*` + +[source,yaml] +---- +- route: + id: "my-yaml-route" + from: + uri: "direct:start" + steps: + - choice: + when: + - simple: "${body} == 'bad value'" + steps: + - throw-exception: + exception-type: "org.acme.ForcedException" + message: "Forced exception" + otherwise: + steps: + - to: "log:end" +---- + +[source,java] +---- +@RegisterForReflection +public class ForcedException { +} +---- + +`*do-catch*` + +[source,yaml] +---- +- route: + id: "my-yaml-route2" + from: + uri: "direct:tryCatch" + steps: + - do-try: + steps: + - to: "direct:readFile" + do-catch: + - exception: + - "java.io.FileNotFoundException" + steps: + - transform: + constant: "do-catch caught an exception" +---- + +[source,java] +---- +@RegisterForReflection(targets = FileNotFoundException.class) +public class MyClass { +} +---- diff --git a/extensions-core/yaml-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/yaml/YamlDslConfiguration.java b/extensions-core/yaml-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/yaml/YamlDslConfiguration.java index ec373bdfa8..ad7181959c 100644 --- a/extensions-core/yaml-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/yaml/YamlDslConfiguration.java +++ b/extensions-core/yaml-dsl/runtime/src/main/java/org/apache/camel/quarkus/dsl/yaml/YamlDslConfiguration.java @@ -24,11 +24,11 @@ import io.quarkus.runtime.annotations.ConfigRoot; @ConfigRoot(name = "camel.yaml", phase = ConfigPhase.BUILD_TIME) public class YamlDslConfiguration { /** - * If {@code true} the YAML DSL support flow-mode which allow to write more concise routes as for EIPs that have - * their own output like filter, aggregate, split, etc. the {@code steps} element can be omitted an in that case, - * the next processing step is automatically wired to the EIP's outputs. + * If {@code true} the YAML DSL supports flow-mode. This allows you to write more concise routes for EIPs that have + * their own output like filter, aggregate, split, etc. the {@code steps} element can be omitted and in that case, + * the next processing step is automatically wired to the EIPs outputs. * <p/> - * As example, a YAML DSL to process only the timer events from 5 to 10 would look like: + * For example, a YAML route to process only the timer events from 5 to 10 would look like: * * <pre> * {@code diff --git a/integration-tests/main-yaml/pom.xml b/integration-tests/main-yaml/pom.xml index f072a1a911..5251bb13d8 100644 --- a/integration-tests/main-yaml/pom.xml +++ b/integration-tests/main-yaml/pom.xml @@ -49,7 +49,7 @@ </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> - <artifactId>camel-quarkus-timer</artifactId> + <artifactId>camel-quarkus-bean</artifactId> </dependency> <dependency> @@ -60,10 +60,7 @@ <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-jsonb</artifactId> </dependency> - <dependency> - <groupId>org.apache.camel.quarkus</groupId> - <artifactId>camel-quarkus-xpath</artifactId> - </dependency> + <!-- test dependencies --> <dependency> @@ -124,20 +121,7 @@ <!-- 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-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> + <artifactId>camel-quarkus-bean-deployment</artifactId> <version>${project.version}</version> <type>pom</type> <scope>test</scope> @@ -150,7 +134,7 @@ </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> - <artifactId>camel-quarkus-rest-deployment</artifactId> + <artifactId>camel-quarkus-direct-deployment</artifactId> <version>${project.version}</version> <type>pom</type> <scope>test</scope> @@ -163,7 +147,7 @@ </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> - <artifactId>camel-quarkus-timer-deployment</artifactId> + <artifactId>camel-quarkus-log-deployment</artifactId> <version>${project.version}</version> <type>pom</type> <scope>test</scope> @@ -176,7 +160,7 @@ </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> - <artifactId>camel-quarkus-xpath-deployment</artifactId> + <artifactId>camel-quarkus-rest-deployment</artifactId> <version>${project.version}</version> <type>pom</type> <scope>test</scope> diff --git a/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/CoreMainYamlResource.java b/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/CoreMainYamlResource.java index 7963a0f726..87d4bb129c 100644 --- a/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/CoreMainYamlResource.java +++ b/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/CoreMainYamlResource.java @@ -26,19 +26,24 @@ import javax.json.JsonObject; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import org.apache.camel.ExtendedCamelContext; +import org.apache.camel.ProducerTemplate; import org.apache.camel.dsl.yaml.YamlRoutesBuilderLoader; import org.apache.camel.spi.RoutesBuilderLoader; -@Path("/test") +@Path("/main/yaml") @ApplicationScoped public class CoreMainYamlResource { @Inject CamelMain main; - @Path("/main/describe") + @Inject + ProducerTemplate producerTemplate; + + @Path("/describe") @GET @Produces(MediaType.APPLICATION_JSON) @SuppressWarnings("unchecked") @@ -63,4 +68,18 @@ public class CoreMainYamlResource { .add("global-options", Json.createObjectBuilder((Map) main.getCamelContext().getGlobalOptions()).build()) .build(); } + + @Path("/greet") + @GET + @Produces(MediaType.TEXT_PLAIN) + public String greet(@QueryParam("forceFailure") boolean forceFailure) { + return producerTemplate.requestBodyAndHeader("direct:start", null, "forceFailure", forceFailure, String.class); + } + + @Path("/try/catch") + @GET + @Produces(MediaType.TEXT_PLAIN) + public String tryCatch() { + return producerTemplate.requestBody("direct:tryCatch", null, String.class); + } } diff --git a/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/CustomException.java b/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/CustomException.java new file mode 100644 index 0000000000..ea96c6b274 --- /dev/null +++ b/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/CustomException.java @@ -0,0 +1,29 @@ +/* + * 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.main; + +import io.quarkus.runtime.annotations.RegisterForReflection; + +@RegisterForReflection +public class CustomException extends Exception { + public CustomException() { + } + + public CustomException(String message) { + super(message); + } +} diff --git a/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/ErrorBean.java b/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/ErrorBean.java new file mode 100644 index 0000000000..a9fc6f4277 --- /dev/null +++ b/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/ErrorBean.java @@ -0,0 +1,26 @@ +/* + * 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.main; + +import io.quarkus.runtime.annotations.RegisterForReflection; + +@RegisterForReflection +public class ErrorBean { + public void throwException() throws CustomException { + throw new CustomException(); + } +} diff --git a/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/GreetingBean.java b/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/GreetingBean.java new file mode 100644 index 0000000000..2e64ef8a8d --- /dev/null +++ b/integration-tests/main-yaml/src/main/java/org/apache/camel/quarkus/main/GreetingBean.java @@ -0,0 +1,32 @@ +/* + * 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.main; + +import io.quarkus.runtime.annotations.RegisterForReflection; + +@RegisterForReflection +public class GreetingBean { + String greeting; + + public void setGreeting(String greeting) { + this.greeting = greeting; + } + + public String greet() { + return greeting; + } +} diff --git a/integration-tests/main-yaml/src/main/resources/application.properties b/integration-tests/main-yaml/src/main/resources/application.properties index 0030f2fc34..a9d2581270 100644 --- a/integration-tests/main-yaml/src/main/resources/application.properties +++ b/integration-tests/main-yaml/src/main/resources/application.properties @@ -18,4 +18,4 @@ # # Main # -camel.main.routes-include-pattern = classpath:routes/my-routes.yaml,classpath:routes/my-rests.yaml +camel.main.routes-include-pattern = routes/my-routes.yaml,routes/my-rests.yaml,routes/my-templates.yaml diff --git a/integration-tests/main-yaml/src/main/resources/routes/my-rests.yaml b/integration-tests/main-yaml/src/main/resources/routes/my-rests.yaml index b248831808..bbb55ceefa 100644 --- a/integration-tests/main-yaml/src/main/resources/routes/my-rests.yaml +++ b/integration-tests/main-yaml/src/main/resources/routes/my-rests.yaml @@ -17,13 +17,28 @@ - rest: get: - - path: "/greeting" - to: "direct:rest" + - path: "/rest" + to: "direct:echoMethodPath" + post: + - path: "/rest" + to: "direct:echoMethodPath" + patch: + - path: "/rest" + to: "direct:echoMethodPath" + put: + - path: "/rest" + to: "direct:echoMethodPath" + delete: + - path: "/rest" + to: "direct:echoMethodPath" + head: + - path: "/rest" + to: "direct:echoMethodPath" - route: id: "rest-route" from: - uri: "direct:rest" + uri: "direct:echoMethodPath" steps: - set-body: - constant: "Hello World!!!" + simple: "${header.CamelHttpMethod}: ${header.CamelHttpPath}" diff --git a/integration-tests/main-yaml/src/main/resources/routes/my-routes.yaml b/integration-tests/main-yaml/src/main/resources/routes/my-routes.yaml index d0a6f533fd..00881b5386 100644 --- a/integration-tests/main-yaml/src/main/resources/routes/my-routes.yaml +++ b/integration-tests/main-yaml/src/main/resources/routes/my-routes.yaml @@ -15,11 +15,51 @@ # limitations under the License. # +- beans: + - name: "greetingBean" + type: "org.apache.camel.quarkus.main.GreetingBean" + properties: + greeting: "Hello World!" +- beans: + - name: "errorBean" + type: "org.apache.camel.quarkus.main.ErrorBean" + +- on-exception: + handled: + constant: "true" + exception: + - "org.apache.camel.quarkus.main.CustomException" + steps: + - transform: + constant: "Sorry something went wrong" + - route: id: "my-yaml-route" from: - uri: "timer:from-xml?period=3000" + uri: "direct:start" + steps: + - choice: + when: + - simple: "${header.forceFailure} == 'true'" + steps: + - throw-exception: + exception-type: "org.apache.camel.quarkus.main.CustomException" + message: "Forced custom exception" + otherwise: + steps: + - to: "bean:greetingBean?method=greet" + +- route: + id: "my-yaml-route2" + from: + uri: "direct:tryCatch" steps: - - set-body: - constant: "Hello World!!!" - - to: "log:from-yaml" + - do-try: + steps: + - to: "bean:errorBean" + do-catch: + - exception: + - "org.apache.camel.quarkus.main.CustomException" + steps: + - transform: + constant: "do-catch caught an exception" diff --git a/integration-tests/main-yaml/src/main/resources/routes/my-rests.yaml b/integration-tests/main-yaml/src/main/resources/routes/my-templates.yaml similarity index 64% copy from integration-tests/main-yaml/src/main/resources/routes/my-rests.yaml copy to integration-tests/main-yaml/src/main/resources/routes/my-templates.yaml index b248831808..d68cff77f4 100644 --- a/integration-tests/main-yaml/src/main/resources/routes/my-rests.yaml +++ b/integration-tests/main-yaml/src/main/resources/routes/my-templates.yaml @@ -15,15 +15,24 @@ # limitations under the License. # -- rest: - get: - - path: "/greeting" - to: "direct:rest" - -- route: - id: "rest-route" +- route-template: + id: "myTemplate" + parameters: + - name: "path" + - name: "method" + - name: "greeting" from: - uri: "direct:rest" + uri: "platform-http:{{path}}?httpMethodRestrict={{method}}" steps: - set-body: - constant: "Hello World!!!" + constant: "{{greeting}}" + +- templated-route: + route-template-ref: "myTemplate" + parameters: + - name: "path" + value: "/templated/greeting" + - name: "method" + value: "GET" + - name: "greeting" + value: "Hello World!" diff --git a/integration-tests/main-yaml/src/test/java/org/apache/camel/quarkus/main/CoreMainYamlTest.java b/integration-tests/main-yaml/src/test/java/org/apache/camel/quarkus/main/CoreMainYamlTest.java index 7e47d01898..c7f2742cf3 100644 --- a/integration-tests/main-yaml/src/test/java/org/apache/camel/quarkus/main/CoreMainYamlTest.java +++ b/integration-tests/main-yaml/src/test/java/org/apache/camel/quarkus/main/CoreMainYamlTest.java @@ -23,9 +23,14 @@ import io.restassured.RestAssured; import io.restassured.path.json.JsonPath; import org.apache.camel.dsl.yaml.YamlRoutesBuilderLoader; import org.apache.camel.dsl.yaml.common.YamlDeserializationMode; +import org.hamcrest.Matcher; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.emptyString; +import static org.hamcrest.Matchers.is; @QuarkusTest public class CoreMainYamlTest { @@ -33,7 +38,7 @@ public class CoreMainYamlTest { public void testMainInstanceWithYamlRoutes() { JsonPath p = RestAssured.given() .accept(MediaType.APPLICATION_JSON) - .get("/test/main/describe") + .get("/main/yaml/describe") .then() .statusCode(200) .extract() @@ -49,4 +54,57 @@ public class CoreMainYamlTest { assertThat(p.getMap("global-options", String.class, String.class)) .containsEntry(YamlRoutesBuilderLoader.DESERIALIZATION_MODE, YamlDeserializationMode.FLOW.name()); } + + @Test + public void yamlRoute() { + RestAssured.get("/main/yaml/greet") + .then() + .statusCode(200) + .body(is("Hello World!")); + + RestAssured.given() + .queryParam("forceFailure", "true") + .get("/main/yaml/greet") + .then() + .statusCode(200) + .body(is("Sorry something went wrong")); + } + + @Test + public void tryCatchYamlRoute() { + RestAssured.given() + .get("/main/yaml/try/catch") + .then() + .statusCode(200) + .body(is("do-catch caught an exception")); + } + + @ParameterizedTest + @ValueSource(strings = { "GET", "POST", "PATCH", "PUT", "DELETE", "HEAD" }) + public void yamlRests(String method) { + Matcher<String> matcher; + if (method.equals("HEAD")) { + matcher = emptyString(); + } else { + matcher = is(method + ": " + "/rest"); + } + + RestAssured.request(method, "/rest") + .then() + .statusCode(200) + .body(matcher); + } + + @Test + public void yamlTemplate() { + RestAssured.get("/templated/greeting") + .then() + .statusCode(200) + .body(is("Hello World!")); + + RestAssured.post("/templated/greeting") + .then() + .statusCode(404); + } + }