You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2023/02/07 07:33:03 UTC

[camel-quarkus] 17/18: Improve yaml-dsl documentation and add simple test scenarios

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 <ja...@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);
+    }
+
 }