You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/08/23 07:36:18 UTC

[camel] branch camel19772 created (now 3326d0782be)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a change to branch camel19772
in repository https://gitbox.apache.org/repos/asf/camel.git


      at 3326d0782be CAMEL-19772: camel-core - Dump routes to include custom beans

This branch includes the following new commits:

     new aee85e3555e CAMEL-19772: camel-core - Dump routes to include custom beans
     new c7b5a815def CAMEL-19772: camel-core - Dump routes to include custom beans
     new 24baad81990 CAMEL-19772: camel-core - Dump routes to include custom beans
     new 3e46b08af94 CAMEL-19772: camel-core - Dump routes to include custom beans
     new bb616fbc2db CAMEL-19772: camel-core - Dump routes to include custom beans
     new 3326d0782be CAMEL-19772: camel-core - Dump routes to include custom beans

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[camel] 06/06: CAMEL-19772: camel-core - Dump routes to include custom beans

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel19772
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 3326d0782be10169987015023e7dc166577b8197
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Aug 23 09:26:25 2023 +0200

    CAMEL-19772: camel-core - Dump routes to include custom beans
---
 docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc
index 41523b0a9c2..ab28a6834b1 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc
@@ -6,6 +6,10 @@ from both 4.0 to 4.1 and 4.1 to 4.2.
 
 == Upgrading Camel 4.0 to 4.1
 
+=== camel-management
+
+Dumping routes to JMX no longer includes `customId="true"` in the XML nodes.
+
 === camel-aws2-step-functions
 
 The following Message Headers of `camel-aws2-step-functions` component have been renamed to follow standard camel naming convention.


[camel] 03/06: CAMEL-19772: camel-core - Dump routes to include custom beans

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel19772
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 24baad81990cf1ee3784d0fb19b29fada835f284
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Aug 23 06:53:30 2023 +0200

    CAMEL-19772: camel-core - Dump routes to include custom beans
---
 .../camel/impl/DefaultDumpRoutesStrategy.java      | 37 +++++++++++++++++++---
 1 file changed, 32 insertions(+), 5 deletions(-)

diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
index 1e999ad7c36..34c83298201 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
@@ -17,6 +17,7 @@
 package org.apache.camel.impl;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -62,8 +63,7 @@ import static org.apache.camel.support.LoggerHelper.stripSourceLocationLineNumbe
 @ServiceFactory("default-" + DumpRoutesStrategy.FACTORY)
 public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRoutesStrategy, CamelContextAware {
 
-    // TODO: XML to disk with beans should use <camel>
-    // TODO: inlined routes in <camel> should be array of <route> and not have <routes> (the same for rests, etc.)
+    // yaml dump (remove auto-generated id - option to turn on|off)
 
     private static final Logger LOG = LoggerFactory.getLogger(DefaultDumpRoutesStrategy.class);
     private static final String DIVIDER = "--------------------------------------------------------------------------------";
@@ -473,6 +473,11 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                 }
             }
         }
+
+        if (directory != null && !files.isEmpty()) {
+            // all XML files need to have <camel> as root tag
+            doAdjustXmlFiles(files);
+        }
     }
 
     protected void doDumpXmlBeans(
@@ -492,10 +497,13 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
             ModelToXMLDumper dumper, String replace, String kind, StringBuilder sbLocal, StringBuilder sbLog) {
         try {
             String xml = dumper.dumpModelAsXml(camelContext, def, resolvePlaceholders);
-            // lets separate with empty line
-            xml = StringHelper.replaceFirst(xml, "xmlns=\"http://camel.apache.org/schema/spring\">",
-                    "xmlns=\"http://camel.apache.org/schema/spring\">\n");
+            // remove spring schema xmlns that camel-jaxb dumper includes
+            xml = StringHelper.replaceFirst(xml, " xmlns=\"http://camel.apache.org/schema/spring\">", ">");
             xml = xml.replace("</" + replace + ">", "</" + replace + ">\n");
+            // remove outer routes tag
+            xml = StringHelper.replaceFirst(xml, "<routes>", "");
+            xml = StringHelper.replaceFirst(xml, "</routes>", "");
+
             sbLocal.append(xml);
             appendLogDump(resource, xml, sbLog);
         } catch (Exception e) {
@@ -537,6 +545,25 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
         }
     }
 
+    protected void doAdjustXmlFiles(Set<String> files) {
+        for (String name : files) {
+            if (name.endsWith(".xml")) {
+                try {
+                    File file = new File(directory, name);
+                    // wrap xml files with <camel> root tag
+                    StringBuilder sb = new StringBuilder();
+                    sb.append("<camel>\n\n");
+                    String xml = IOHelper.loadText(new FileInputStream(file));
+                    sb.append(xml);
+                    sb.append("\n</camel>\n");
+                    IOHelper.writeText(sb.toString(), file);
+                } catch (Exception e) {
+                    LOG.warn("Error adjusting dumped XML file: {} due to {}. This exception is ignored.", name, e.getMessage(), e);
+                }
+            }
+        }
+    }
+
     protected void appendLogDump(Resource resource, String dump, StringBuilder sbLog) {
         String loc = null;
         if (resource != null) {


[camel] 05/06: CAMEL-19772: camel-core - Dump routes to include custom beans

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel19772
in repository https://gitbox.apache.org/repos/asf/camel.git

commit bb616fbc2db4a40158aed376ecbb0a3ced5fafc5
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Aug 23 09:23:59 2023 +0200

    CAMEL-19772: camel-core - Dump routes to include custom beans
---
 .../main/camel-main-configuration-metadata.json    |  1 +
 .../spring/DumpModelAsXmlPlaceholdersTest.java     |  4 +--
 .../SpringJmxDumpCBRRoutesAsXmlTest.java           |  6 ++--
 .../routebuilder/SpringRouteTemplateTest.java      |  4 +--
 .../org/apache/camel/spi/DumpRoutesStrategy.java   |  7 +++++
 .../org/apache/camel/spi/ModelToXMLDumper.java     |  3 +-
 .../org/apache/camel/spi/ModelToYAMLDumper.java    |  3 +-
 .../impl/DefaultDumpRoutesStrategyConfigurer.java  |  6 ++++
 .../camel/impl/DefaultDumpRoutesStrategy.java      | 15 ++++++---
 .../util/DumpModelAsXmlFromRouteTemplateTest.java  |  5 +--
 .../camel/util/DumpModelAsXmlPlaceholdersTest.java |  4 +--
 .../util/DumpModelAsXmlSplitBodyRouteTest.java     |  1 -
 .../DumpModelAsXmlTransformRouteConstantTest.java  |  1 -
 .../DumpModelAsXmlTransformRouteLanguageTest.java  |  1 -
 .../util/DumpModelAsXmlTransformRouteTest.java     |  1 -
 .../util/DumpModelAsYamlUriAsParametersTest.java   | 17 +++++++++-
 .../camel/util/uri-as-parameters-no-ids.yaml       | 36 ++++++++++++++++++++++
 .../MainConfigurationPropertiesConfigurer.java     |  6 ++++
 .../camel-main-configuration-metadata.json         |  1 +
 core/camel-main/src/main/docs/main.adoc            |  3 +-
 .../camel/main/DefaultConfigurationConfigurer.java |  1 +
 .../camel/main/DefaultConfigurationProperties.java | 20 ++++++++++++
 .../management/mbean/ManagedCamelContextMBean.java |  6 ++++
 .../api/management/mbean/ManagedRouteMBean.java    |  6 ++++
 .../management/mbean/ManagedCamelContext.java      | 23 ++++++++++----
 .../camel/management/mbean/ManagedRoute.java       | 16 ++++++++--
 .../org/apache/camel/xml/LwModelToXMLDumper.java   | 13 ++++----
 .../camel/xml/jaxb/JaxbModelToXMLDumper.java       | 25 ++++++++++-----
 .../org/apache/camel/yaml/LwModelToYAMLDumper.java | 13 ++++----
 29 files changed, 194 insertions(+), 54 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index 6dd2a3c22de..e8028acc780 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -40,6 +40,7 @@
     { "name": "camel.main.devConsoleEnabled", "description": "Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.dumpRoutes", "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML\/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml [...]
     { "name": "camel.main.dumpRoutesDirectory", "description": "Whether to save route dumps to files in the given directory. The name of the files are based on original loaded resource, or an autogenerated name.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
+    { "name": "camel.main.dumpRoutesGeneratedIds", "description": "Whether to include auto generated IDs in the dumped output. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.dumpRoutesInclude", "description": "Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans. Multiple values can be separated by comma. Default is routes.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "routes" },
     { "name": "camel.main.dumpRoutesLog", "description": "Whether to log route dumps to Logger", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.main.dumpRoutesResolvePlaceholders", "description": "Whether to resolve property placeholders in the dumped output. Default is true.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
index 2d8aad7d51b..6628f967ad9 100644
--- a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
@@ -42,9 +42,9 @@ public class DumpModelAsXmlPlaceholdersTest extends SpringTestSupport {
         assertNotNull(xml);
         log.info(xml);
 
-        assertTrue(xml.contains("<route xmlns=\"http://camel.apache.org/schema/spring\" customId=\"true\" id=\"Gouda\">"));
+        assertTrue(xml.contains("<route xmlns=\"http://camel.apache.org/schema/spring\" id=\"Gouda\">"));
         assertTrue(xml.contains("<from uri=\"direct:start-{{cheese.type}}\"/>"));
-        assertTrue(xml.contains("<to customId=\"true\" id=\"log\" uri=\"direct:end-{{cheese.type}}\"/>"));
+        assertTrue(xml.contains("<to id=\"log\" uri=\"direct:end-{{cheese.type}}\"/>"));
     }
 
 }
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringJmxDumpCBRRoutesAsXmlTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringJmxDumpCBRRoutesAsXmlTest.java
index 729e9a4c0a2..34849caf703 100644
--- a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringJmxDumpCBRRoutesAsXmlTest.java
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringJmxDumpCBRRoutesAsXmlTest.java
@@ -58,10 +58,8 @@ public class SpringJmxDumpCBRRoutesAsXmlTest extends SpringTestSupport {
         assertTrue(xml.contains("myRoute"), xml);
         assertTrue(xml.matches("[\\S\\s]*<when id=\"when[0-9]+\">[\\S\\s]*"));
         assertTrue(xml.matches("[\\S\\s]*<otherwise id=\"otherwise[0-9]+\">[\\S\\s]*"));
-        assertTrue(xml.contains("<route customId=\"true\" id=\"myRoute\">")
-                || xml.contains("<route id=\"myRoute\" customId=\"true\">"));
-        assertTrue(xml.contains("<choice customId=\"true\" id=\"myChoice\">")
-                || xml.contains("<choice id=\"myChoice\" customId=\"true\">"));
+        assertTrue(xml.contains("<route id=\"myRoute\">"));
+        assertTrue(xml.contains("<choice id=\"myChoice\">"));
     }
 
 }
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/routebuilder/SpringRouteTemplateTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/routebuilder/SpringRouteTemplateTest.java
index 3a678a7cfff..44101e84a1a 100644
--- a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/routebuilder/SpringRouteTemplateTest.java
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/routebuilder/SpringRouteTemplateTest.java
@@ -155,7 +155,7 @@ public class SpringRouteTemplateTest extends SpringTestSupport {
 
         RouteDefinition def = context.getRouteDefinition("first");
 
-        String xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, true);
+        String xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, true, false);
 
         assertNotNull(xml);
         Assertions.assertTrue(xml.contains("<from uri=\"direct:one\"/>"));
@@ -171,7 +171,7 @@ public class SpringRouteTemplateTest extends SpringTestSupport {
         RoutesDefinition def = new RoutesDefinition();
         def.setRoutes(context.getRouteDefinitions());
 
-        String xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, true);
+        String xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, true, false);
 
         assertNotNull(xml);
         Assertions.assertTrue(xml.contains("<from uri=\"direct:one\"/>"));
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java b/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java
index 54ad32226d5..6372591b996 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java
@@ -60,6 +60,13 @@ public interface DumpRoutesStrategy extends StaticService {
      */
     void setUriAsParameters(boolean uriAsParameters);
 
+    boolean isGeneratedIds();
+
+    /**
+     * Whether to include auto generated IDs in the dumped output. Default is false.
+     */
+    void setGeneratedIds(boolean generatedIds);
+
     boolean isLog();
 
     /**
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToXMLDumper.java b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToXMLDumper.java
index 94f5ec8a764..47ee821349a 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToXMLDumper.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToXMLDumper.java
@@ -47,11 +47,12 @@ public interface ModelToXMLDumper {
      * @param  context             the CamelContext
      * @param  definition          the definition, such as a {@link org.apache.camel.NamedNode}
      * @param  resolvePlaceholders whether to resolve property placeholders in the dumped XML
+     * @param  generatedIds        whether to include auto generated IDs
      * @return                     the output in XML (is formatted)
      * @throws Exception           is throw if error marshalling to XML
      */
     String dumpModelAsXml(
-            CamelContext context, NamedNode definition, boolean resolvePlaceholders)
+            CamelContext context, NamedNode definition, boolean resolvePlaceholders, boolean generatedIds)
             throws Exception;
 
     /**
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java
index 6f4ae0f1423..e4139b1a089 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java
@@ -48,12 +48,13 @@ public interface ModelToYAMLDumper {
      * @param  definition          the definition, such as a {@link NamedNode}
      * @param  resolvePlaceholders whether to resolve property placeholders in the dumped YAML
      * @param  uriAsParameters     whether to expand uri into a key/value parameters
+     * @param  generatedIds        whether to include auto generated IDs
      * @return                     the output in YAML (is formatted)
      * @throws Exception           is throw if error marshalling to YAML
      */
     String dumpModelAsYaml(
             CamelContext context, NamedNode definition,
-            boolean resolvePlaceholders, boolean uriAsParameters)
+            boolean resolvePlaceholders, boolean uriAsParameters, boolean generatedIds)
             throws Exception;
 
     /**
diff --git a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/DefaultDumpRoutesStrategyConfigurer.java b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/DefaultDumpRoutesStrategyConfigurer.java
index 69ed6aad744..fabccd51adb 100644
--- a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/DefaultDumpRoutesStrategyConfigurer.java
+++ b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/DefaultDumpRoutesStrategyConfigurer.java
@@ -25,6 +25,8 @@ public class DefaultDumpRoutesStrategyConfigurer extends org.apache.camel.suppor
         case "CamelContext": target.setCamelContext(property(camelContext, org.apache.camel.CamelContext.class, value)); return true;
         case "directory":
         case "Directory": target.setDirectory(property(camelContext, java.lang.String.class, value)); return true;
+        case "generatedids":
+        case "GeneratedIds": target.setGeneratedIds(property(camelContext, boolean.class, value)); return true;
         case "include":
         case "Include": target.setInclude(property(camelContext, java.lang.String.class, value)); return true;
         case "log":
@@ -44,6 +46,8 @@ public class DefaultDumpRoutesStrategyConfigurer extends org.apache.camel.suppor
         case "CamelContext": return org.apache.camel.CamelContext.class;
         case "directory":
         case "Directory": return java.lang.String.class;
+        case "generatedids":
+        case "GeneratedIds": return boolean.class;
         case "include":
         case "Include": return java.lang.String.class;
         case "log":
@@ -64,6 +68,8 @@ public class DefaultDumpRoutesStrategyConfigurer extends org.apache.camel.suppor
         case "CamelContext": return target.getCamelContext();
         case "directory":
         case "Directory": return target.getDirectory();
+        case "generatedids":
+        case "GeneratedIds": return target.isGeneratedIds();
         case "include":
         case "Include": return target.getInclude();
         case "log":
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
index 0edff3b4690..cf0e4093d3f 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
@@ -63,8 +63,6 @@ import static org.apache.camel.support.LoggerHelper.stripSourceLocationLineNumbe
 @ServiceFactory("default-" + DumpRoutesStrategy.FACTORY)
 public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRoutesStrategy, CamelContextAware {
 
-    // yaml dump (remove auto-generated id - option to turn on|off)
-
     private static final Logger LOG = LoggerFactory.getLogger(DefaultDumpRoutesStrategy.class);
     private static final String DIVIDER = "--------------------------------------------------------------------------------";
 
@@ -74,6 +72,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
     private String include = "routes";
     private boolean resolvePlaceholders = true;
     private boolean uriAsParameters;
+    private boolean generatedIds = true;
     private boolean log = true;
     private String directory;
 
@@ -103,6 +102,14 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
         this.resolvePlaceholders = resolvePlaceholders;
     }
 
+    public boolean isGeneratedIds() {
+        return generatedIds;
+    }
+
+    public void setGeneratedIds(boolean generatedIds) {
+        this.generatedIds = generatedIds;
+    }
+
     public boolean isLog() {
         return log;
     }
@@ -297,7 +304,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
             CamelContext camelContext, NamedNode def, Resource resource,
             ModelToYAMLDumper dumper, String kind, StringBuilder sbLocal, StringBuilder sbLog) {
         try {
-            String dump = dumper.dumpModelAsYaml(camelContext, def, resolvePlaceholders, uriAsParameters);
+            String dump = dumper.dumpModelAsYaml(camelContext, def, resolvePlaceholders, uriAsParameters, generatedIds);
             sbLocal.append(dump);
             appendLogDump(resource, dump, sbLog);
         } catch (Exception e) {
@@ -496,7 +503,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
             CamelContext camelContext, NamedNode def, Resource resource,
             ModelToXMLDumper dumper, String replace, String kind, StringBuilder sbLocal, StringBuilder sbLog) {
         try {
-            String xml = dumper.dumpModelAsXml(camelContext, def, resolvePlaceholders);
+            String xml = dumper.dumpModelAsXml(camelContext, def, resolvePlaceholders, generatedIds);
             // remove spring schema xmlns that camel-jaxb dumper includes
             xml = StringHelper.replaceFirst(xml, " xmlns=\"http://camel.apache.org/schema/spring\">", ">");
             xml = xml.replace("</" + replace + ">", "</" + replace + ">\n");
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlFromRouteTemplateTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlFromRouteTemplateTest.java
index 8174cee9e8e..50e50f4f30c 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlFromRouteTemplateTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlFromRouteTemplateTest.java
@@ -81,7 +81,8 @@ public class DumpModelAsXmlFromRouteTemplateTest extends ContextTestSupport {
         map.put("whereto", "Jacks");
         context.addRouteFromTemplate("bar2", "myTemplate", map);
 
-        String xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, context.getRouteDefinition("bar"), true);
+        String xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, context.getRouteDefinition("bar"), true,
+                true);
         assertNotNull(xml);
         log.info(xml);
 
@@ -103,7 +104,7 @@ public class DumpModelAsXmlFromRouteTemplateTest extends ContextTestSupport {
         node = (Element) nodes.item(0);
         assertEquals("bar", node.getAttribute("id"));
 
-        xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, context.getRouteDefinition("bar2"), true);
+        xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, context.getRouteDefinition("bar2"), true, true);
         assertNotNull(xml);
         log.info(xml);
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlPlaceholdersTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlPlaceholdersTest.java
index f2d9e6deb3c..edd18a473d1 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlPlaceholdersTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlPlaceholdersTest.java
@@ -32,9 +32,9 @@ public class DumpModelAsXmlPlaceholdersTest extends ContextTestSupport {
         String xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, context.getRouteDefinition("Gouda"));
         assertNotNull(xml);
         log.info(xml);
-        assertTrue(xml.contains("<route xmlns=\"http://camel.apache.org/schema/spring\" customId=\"true\" id=\"Gouda\">"));
+        assertTrue(xml.contains("<route xmlns=\"http://camel.apache.org/schema/spring\" id=\"Gouda\">"));
         assertTrue(xml.contains("<from uri=\"direct:start-{{cheese.type}}\"/>"));
-        assertTrue(xml.contains("<to customId=\"true\" id=\"log\" uri=\"direct:end-{{cheese.type}}\"/>"));
+        assertTrue(xml.contains("<to id=\"log\" uri=\"direct:end-{{cheese.type}}\"/>"));
     }
 
     @Override
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlSplitBodyRouteTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlSplitBodyRouteTest.java
index dec9c19d241..67526fa62ce 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlSplitBodyRouteTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlSplitBodyRouteTest.java
@@ -56,7 +56,6 @@ public class DumpModelAsXmlSplitBodyRouteTest extends ContextTestSupport {
         assertNotNull(node, "Node <to> expected to be instanceof Element");
         assertEquals("mock:sub", node.getAttribute("uri"));
         assertEquals("myMock", node.getAttribute("id"));
-        assertEquals("true", node.getAttribute("customId"));
     }
 
     @Override
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteConstantTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteConstantTest.java
index fb04e447e95..00fb2802fd0 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteConstantTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteConstantTest.java
@@ -53,7 +53,6 @@ public class DumpModelAsXmlTransformRouteConstantTest extends ContextTestSupport
         assertNotNull(node, "Node <to> expected to be instanceof Element");
         assertEquals("mock:result", node.getAttribute("uri"));
         assertEquals("myMock", node.getAttribute("id"));
-        assertEquals("true", node.getAttribute("customId"));
     }
 
     @Override
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteLanguageTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteLanguageTest.java
index 5c30a125b6a..1bc10f2da7a 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteLanguageTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteLanguageTest.java
@@ -55,7 +55,6 @@ public class DumpModelAsXmlTransformRouteLanguageTest extends ContextTestSupport
         assertNotNull(node, "Node <to> expected to be instanceof Element");
         assertEquals("mock:result", node.getAttribute("uri"));
         assertEquals("myMock", node.getAttribute("id"));
-        assertEquals("true", node.getAttribute("customId"));
     }
 
     @Override
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteTest.java
index 3e3b17cb8df..feb44e8cc41 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsXmlTransformRouteTest.java
@@ -53,7 +53,6 @@ public class DumpModelAsXmlTransformRouteTest extends ContextTestSupport {
         assertNotNull(node, "Node <to> expected to be instanceof Element");
         assertEquals("mock:result", node.getAttribute("uri"));
         assertEquals("myMock", node.getAttribute("id"));
-        assertEquals("true", node.getAttribute("customId"));
     }
 
     @Override
diff --git a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlUriAsParametersTest.java b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlUriAsParametersTest.java
index 3268951e050..46770e1de9a 100644
--- a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlUriAsParametersTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlUriAsParametersTest.java
@@ -30,7 +30,7 @@ public class DumpModelAsYamlUriAsParametersTest extends DumpModelAsYamlTestSuppo
     @Test
     public void testDumpModelAsYaml() throws Exception {
         String out = PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, context.getRouteDefinition("myRoute"),
-                true, true);
+                true, true, true);
         assertNotNull(out);
         log.info(out);
 
@@ -40,6 +40,21 @@ public class DumpModelAsYamlUriAsParametersTest extends DumpModelAsYamlTestSuppo
         Assertions.assertEquals(expected, out);
     }
 
+    @Test
+    public void testDumpModelAsYamlGeneratedIds() throws Exception {
+        String out = PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, context.getRouteDefinition("myRoute"),
+                true, true, false);
+        assertNotNull(out);
+        log.info(out);
+
+        String expected
+                = IOHelper.stripLineComments(
+                        Paths.get("src/test/resources/org/apache/camel/util/uri-as-parameters-no-ids.yaml"),
+                        "#",
+                        true);
+        Assertions.assertEquals(expected, out);
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
diff --git a/core/camel-core/src/test/resources/org/apache/camel/util/uri-as-parameters-no-ids.yaml b/core/camel-core/src/test/resources/org/apache/camel/util/uri-as-parameters-no-ids.yaml
new file mode 100644
index 00000000000..f9da0fca7f7
--- /dev/null
+++ b/core/camel-core/src/test/resources/org/apache/camel/util/uri-as-parameters-no-ids.yaml
@@ -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.
+#
+
+- route:
+    id: myRoute
+    from:
+      uri: seda
+      parameters:
+        name: foo
+        size: 1234
+        multipleConsumers: true
+      steps:
+        - transform:
+            simple:
+              expression: "Hello ${body}"
+        - to:
+            id: myMock
+            uri: mock
+            parameters:
+              name: result
+              retainFirst: 5
+              failFast: true
diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
index 288a99df147..0bc0b781c4e 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
@@ -75,6 +75,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "DumpRoutes": target.setDumpRoutes(property(camelContext, java.lang.String.class, value)); return true;
         case "dumproutesdirectory":
         case "DumpRoutesDirectory": target.setDumpRoutesDirectory(property(camelContext, java.lang.String.class, value)); return true;
+        case "dumproutesgeneratedids":
+        case "DumpRoutesGeneratedIds": target.setDumpRoutesGeneratedIds(property(camelContext, boolean.class, value)); return true;
         case "dumproutesinclude":
         case "DumpRoutesInclude": target.setDumpRoutesInclude(property(camelContext, java.lang.String.class, value)); return true;
         case "dumprouteslog":
@@ -332,6 +334,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "DumpRoutes": return java.lang.String.class;
         case "dumproutesdirectory":
         case "DumpRoutesDirectory": return java.lang.String.class;
+        case "dumproutesgeneratedids":
+        case "DumpRoutesGeneratedIds": return boolean.class;
         case "dumproutesinclude":
         case "DumpRoutesInclude": return java.lang.String.class;
         case "dumprouteslog":
@@ -590,6 +594,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "DumpRoutes": return target.getDumpRoutes();
         case "dumproutesdirectory":
         case "DumpRoutesDirectory": return target.getDumpRoutesDirectory();
+        case "dumproutesgeneratedids":
+        case "DumpRoutesGeneratedIds": return target.isDumpRoutesGeneratedIds();
         case "dumproutesinclude":
         case "DumpRoutesInclude": return target.getDumpRoutesInclude();
         case "dumprouteslog":
diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 6dd2a3c22de..e8028acc780 100644
--- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -40,6 +40,7 @@
     { "name": "camel.main.devConsoleEnabled", "description": "Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.dumpRoutes", "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML\/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml [...]
     { "name": "camel.main.dumpRoutesDirectory", "description": "Whether to save route dumps to files in the given directory. The name of the files are based on original loaded resource, or an autogenerated name.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
+    { "name": "camel.main.dumpRoutesGeneratedIds", "description": "Whether to include auto generated IDs in the dumped output. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.dumpRoutesInclude", "description": "Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans. Multiple values can be separated by comma. Default is routes.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "routes" },
     { "name": "camel.main.dumpRoutesLog", "description": "Whether to log route dumps to Logger", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.main.dumpRoutesResolvePlaceholders", "description": "Whether to resolve property placeholders in the dumped output. Default is true.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index b0c27393219..0614e98e98c 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -19,7 +19,7 @@ The following tables lists all the options:
 
 // main options: START
 === Camel Main configurations
-The camel.main supports 125 options, which are listed below.
+The camel.main supports 126 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -51,6 +51,7 @@ The camel.main supports 125 options, which are listed below.
 | *camel.main.devConsoleEnabled* | Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage. | false | boolean
 | *camel.main.dumpRoutes* | If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml-io/camel-yaml-io on the cla [...]
 | *camel.main.dumpRoutesDirectory* | Whether to save route dumps to files in the given directory. The name of the files are based on original loaded resource, or an autogenerated name. |  | String
+| *camel.main.dumpRoutesGenerated{zwsp}Ids* | Whether to include auto generated IDs in the dumped output. Default is false. | false | boolean
 | *camel.main.dumpRoutesInclude* | Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans. Multiple values can be separated by comma. Default is routes. | routes | String
 | *camel.main.dumpRoutesLog* | Whether to log route dumps to Logger | true | boolean
 | *camel.main.dumpRoutesResolve{zwsp}Placeholders* | Whether to resolve property placeholders in the dumped output. Default is true. | true | boolean
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index f55b933bc1a..1d6346c7625 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -264,6 +264,7 @@ public final class DefaultConfigurationConfigurer {
             drs.setInclude(config.getDumpRoutesInclude());
             drs.setLog(config.isDumpRoutesLog());
             drs.setUriAsParameters(config.isDumpRoutesUriAsParameters());
+            drs.setGeneratedIds(config.isDumpRoutesGeneratedIds());
             drs.setResolvePlaceholders(config.isDumpRoutesResolvePlaceholders());
             drs.setDirectory(config.getDumpRoutesDirectory());
         }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index 29a092a3935..6c028717251 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -135,6 +135,7 @@ public abstract class DefaultConfigurationProperties<T> {
     private boolean dumpRoutesLog = true;
     private boolean dumpRoutesResolvePlaceholders = true;
     private boolean dumpRoutesUriAsParameters;
+    private boolean dumpRoutesGeneratedIds;
     private String dumpRoutesDirectory;
     private Map<String, String> globalOptions;
     // route controller
@@ -1439,6 +1440,17 @@ public abstract class DefaultConfigurationProperties<T> {
         this.dumpRoutesUriAsParameters = dumpRoutesUriAsParameters;
     }
 
+    public boolean isDumpRoutesGeneratedIds() {
+        return dumpRoutesGeneratedIds;
+    }
+
+    /**
+     * Whether to include auto generated IDs in the dumped output. Default is false.
+     */
+    public void setDumpRoutesGeneratedIds(boolean dumpRoutesGeneratedIds) {
+        this.dumpRoutesGeneratedIds = dumpRoutesGeneratedIds;
+    }
+
     public String getDumpRoutesDirectory() {
         return dumpRoutesDirectory;
     }
@@ -2679,6 +2691,14 @@ public abstract class DefaultConfigurationProperties<T> {
         return (T) this;
     }
 
+    /**
+     * Whether to include auto generated IDs in the dumped output. Default is false.
+     */
+    public T withDumpRoutesGeneratedIds(boolean dumpRoutesGeneratedIds) {
+        this.dumpRoutesGeneratedIds = dumpRoutesGeneratedIds;
+        return (T) this;
+    }
+
     /**
      * Whether to save route dumps to files in the given directory. The name of the files are based on original loaded
      * resource, or an autogenerated name.
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
index d7de3e7fb1c..e7ed34cf98d 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
@@ -195,6 +195,9 @@ public interface ManagedCamelContextMBean extends ManagedPerformanceCounterMBean
     @ManagedOperation(description = "Dumps the routes as XML")
     String dumpRoutesAsXml(boolean resolvePlaceholders) throws Exception;
 
+    @ManagedOperation(description = "Dumps the routes as XML")
+    String dumpRoutesAsXml(boolean resolvePlaceholders, boolean generatedIds) throws Exception;
+
     @ManagedOperation(description = "Dumps the CamelContext and routes stats as XML")
     String dumpRoutesStatsAsXml(boolean fullStats, boolean includeProcessors) throws Exception;
 
@@ -216,6 +219,9 @@ public interface ManagedCamelContextMBean extends ManagedPerformanceCounterMBean
     @ManagedOperation(description = "Dumps the routes as YAML")
     String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean uriAsParameters) throws Exception;
 
+    @ManagedOperation(description = "Dumps the routes as YAML")
+    String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean uriAsParameters, boolean generatedIds) throws Exception;
+
     /**
      * Creates the endpoint by the given uri
      *
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
index 4f6e7dc2b8a..1ea2d61ca74 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
@@ -121,6 +121,9 @@ public interface ManagedRouteMBean extends ManagedPerformanceCounterMBean {
     @ManagedOperation(description = "Dumps the route as XML")
     String dumpRouteAsXml(boolean resolvePlaceholders) throws Exception;
 
+    @ManagedOperation(description = "Dumps the route as XML")
+    String dumpRouteAsXml(boolean resolvePlaceholders, boolean generatedIds) throws Exception;
+
     @ManagedOperation(description = "Dumps the route as YAML")
     String dumpRouteAsYaml() throws Exception;
 
@@ -130,6 +133,9 @@ public interface ManagedRouteMBean extends ManagedPerformanceCounterMBean {
     @ManagedOperation(description = "Dumps the route as YAML")
     String dumpRouteAsYaml(boolean resolvePlaceholders, boolean uriAsParameters) throws Exception;
 
+    @ManagedOperation(description = "Dumps the route as YAML")
+    String dumpRouteAsYaml(boolean resolvePlaceholders, boolean uriAsParameters, boolean generatedIds) throws Exception;
+
     @ManagedOperation(description = "Dumps the route stats as XML")
     String dumpRouteStatsAsXml(boolean fullStats, boolean includeProcessors) throws Exception;
 
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index 382f54fa0c0..b709ad93c29 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -447,7 +447,6 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
         try (ProducerTemplate template = context.createProducerTemplate()) {
             return template.requestBodyAndHeaders(endpointUri, body, headers);
         }
-
     }
 
     @Override
@@ -465,16 +464,21 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
         RestsDefinition def = new RestsDefinition();
         def.setRests(rests);
 
-        return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, resolvePlaceholders);
+        return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, resolvePlaceholders, true);
     }
 
     @Override
     public String dumpRoutesAsXml() throws Exception {
-        return dumpRoutesAsXml(false);
+        return dumpRoutesAsXml(false, true);
     }
 
     @Override
     public String dumpRoutesAsXml(boolean resolvePlaceholders) throws Exception {
+        return dumpRoutesAsXml(resolvePlaceholders, true);
+    }
+
+    @Override
+    public String dumpRoutesAsXml(boolean resolvePlaceholders, boolean generatedIds) throws Exception {
         List<RouteDefinition> routes = context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinitions();
         if (routes.isEmpty()) {
             return null;
@@ -484,7 +488,7 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
         RoutesDefinition def = new RoutesDefinition();
         def.setRoutes(routes);
 
-        return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, resolvePlaceholders);
+        return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, resolvePlaceholders, generatedIds);
     }
 
     @Override
@@ -494,11 +498,17 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
 
     @Override
     public String dumpRoutesAsYaml(boolean resolvePlaceholders) throws Exception {
-        return dumpRoutesAsYaml(resolvePlaceholders, false);
+        return dumpRoutesAsYaml(resolvePlaceholders, false, true);
     }
 
     @Override
     public String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean uriAsParameters) throws Exception {
+        return dumpRoutesAsYaml(resolvePlaceholders, uriAsParameters, true);
+    }
+
+    @Override
+    public String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean uriAsParameters, boolean generatedIds)
+            throws Exception {
         List<RouteDefinition> routes = context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinitions();
         if (routes.isEmpty()) {
             return null;
@@ -508,7 +518,8 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
         RoutesDefinition def = new RoutesDefinition();
         def.setRoutes(routes);
 
-        return PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, def, resolvePlaceholders, uriAsParameters);
+        return PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, def, resolvePlaceholders, uriAsParameters,
+                generatedIds);
     }
 
     @Override
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
index 7b8154c363e..0f7e00790e1 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
@@ -388,10 +388,15 @@ public class ManagedRoute extends ManagedPerformanceCounter implements TimerList
 
     @Override
     public String dumpRouteAsXml(boolean resolvePlaceholders) throws Exception {
+        return dumpRouteAsXml(resolvePlaceholders, true);
+    }
+
+    @Override
+    public String dumpRouteAsXml(boolean resolvePlaceholders, boolean generatedIds) throws Exception {
         String id = route.getId();
         RouteDefinition def = context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinition(id);
         if (def != null) {
-            return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, resolvePlaceholders);
+            return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, resolvePlaceholders, generatedIds);
         }
 
         return null;
@@ -404,16 +409,21 @@ public class ManagedRoute extends ManagedPerformanceCounter implements TimerList
 
     @Override
     public String dumpRouteAsYaml(boolean resolvePlaceholders) throws Exception {
-        return dumpRouteAsYaml(resolvePlaceholders, false);
+        return dumpRouteAsYaml(resolvePlaceholders, false, true);
     }
 
     @Override
     public String dumpRouteAsYaml(boolean resolvePlaceholders, boolean uriAsParameters) throws Exception {
+        return dumpRouteAsYaml(resolvePlaceholders, uriAsParameters, true);
+    }
+
+    @Override
+    public String dumpRouteAsYaml(boolean resolvePlaceholders, boolean uriAsParameters, boolean generatedIds) throws Exception {
         String id = route.getId();
         RouteDefinition def = context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinition(id);
         if (def != null) {
             return PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, def, resolvePlaceholders,
-                    uriAsParameters);
+                    uriAsParameters, generatedIds);
         }
 
         return null;
diff --git a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
index db76fe5ca41..91bb5d9fef4 100644
--- a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
+++ b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
@@ -58,12 +58,12 @@ public class LwModelToXMLDumper implements ModelToXMLDumper {
 
     @Override
     public String dumpModelAsXml(CamelContext context, NamedNode definition) throws Exception {
-        return dumpModelAsXml(context, definition, false);
+        return dumpModelAsXml(context, definition, false, true);
     }
 
     @Override
     public String dumpModelAsXml(
-            CamelContext context, NamedNode definition, boolean resolvePlaceholders)
+            CamelContext context, NamedNode definition, boolean resolvePlaceholders, boolean generatedIds)
             throws Exception {
 
         Properties properties = new Properties();
@@ -88,12 +88,11 @@ public class LwModelToXMLDumper implements ModelToXMLDumper {
             @Override
             protected void doWriteOptionalIdentifiedDefinitionAttributes(OptionalIdentifiedDefinition<?> def)
                     throws IOException {
-                // write customId if not false
-                if (Boolean.TRUE.equals(def.getCustomId())) {
-                    doWriteAttribute("customId", toString(def.getCustomId()));
+
+                if (generatedIds || Boolean.TRUE.equals(def.getCustomId())) {
+                    // write id
+                    doWriteAttribute("id", def.getId());
                 }
-                // write id
-                doWriteAttribute("id", def.getId());
                 // write description
                 if (def.getDescriptionText() != null) {
                     doWriteAttribute("description", def.getDescriptionText());
diff --git a/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java b/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
index 266162386b4..0d4ca70f8c7 100644
--- a/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
+++ b/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
@@ -74,6 +74,10 @@ public class JaxbModelToXMLDumper implements ModelToXMLDumper {
 
     @Override
     public String dumpModelAsXml(CamelContext context, NamedNode definition) throws Exception {
+        return doDumpModelAsXml(context, definition, true);
+    }
+
+    public String doDumpModelAsXml(CamelContext context, NamedNode definition, boolean generatedIds) throws Exception {
         final JAXBContext jaxbContext = getJAXBContext(context);
         final Map<String, String> namespaces = new LinkedHashMap<>();
         final Map<String, KeyValueHolder<Integer, String>> locations = new HashMap<>();
@@ -129,10 +133,10 @@ public class JaxbModelToXMLDumper implements ModelToXMLDumper {
             throw new TypeConversionException(xml, Document.class, e);
         }
 
-        sanitizeXml(dom);
         if (context.isDebugging()) {
             enrichLocations(dom, locations);
         }
+        sanitizeXml(dom, generatedIds);
 
         // Add additional namespaces to the document root element
         Element documentElement = dom.getDocumentElement();
@@ -156,7 +160,7 @@ public class JaxbModelToXMLDumper implements ModelToXMLDumper {
 
     @Override
     public String dumpModelAsXml(
-            CamelContext context, NamedNode definition, boolean resolvePlaceholders)
+            CamelContext context, NamedNode definition, boolean resolvePlaceholders, boolean generatedIds)
             throws Exception {
         String xml = dumpModelAsXml(context, definition);
 
@@ -208,11 +212,10 @@ public class JaxbModelToXMLDumper implements ModelToXMLDumper {
             // okay there were some property placeholder or delegate endpoints
             // replaced so re-create the model
             if (changed.get()) {
-                // remove all generated ID from dom, as we do not want to copy those over
                 removeAutoAssignedIds(dom.getDocumentElement());
                 xml = context.getTypeConverter().mandatoryConvertTo(String.class, dom);
                 NamedNode copy = modelToXml(context, xml, NamedNode.class);
-                xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, copy);
+                xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, copy, false, generatedIds);
             }
         }
 
@@ -241,18 +244,26 @@ public class JaxbModelToXMLDumper implements ModelToXMLDumper {
         return buffer.toString();
     }
 
-    private static void sanitizeXml(Node node) {
+    private static void sanitizeXml(Node node, boolean generatedIds) {
         // we want to remove all customId="false" attributes as they are noisy
         if (node.hasAttributes()) {
             Node att = node.getAttributes().getNamedItem("customId");
-            if (att != null && "false".equals(att.getNodeValue())) {
+            boolean custom = att != null && "true".equals(att.getNodeValue());
+            if (att != null) {
                 node.getAttributes().removeNamedItem("customId");
             }
+            if (!generatedIds && !custom) {
+                // remove auto-generated ids
+                Node attId = node.getAttributes().getNamedItem("id");
+                if (attId != null) {
+                    node.getAttributes().removeNamedItem("id");
+                }
+            }
         }
         if (node.hasChildNodes()) {
             for (int i = 0; i < node.getChildNodes().getLength(); i++) {
                 Node child = node.getChildNodes().item(i);
-                sanitizeXml(child);
+                sanitizeXml(child, generatedIds);
             }
         }
     }
diff --git a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
index 72e52a6f93b..c3081ca2d68 100644
--- a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
+++ b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
@@ -58,13 +58,13 @@ public class LwModelToYAMLDumper implements ModelToYAMLDumper {
 
     @Override
     public String dumpModelAsYaml(CamelContext context, NamedNode definition) throws Exception {
-        return dumpModelAsYaml(context, definition, false, false);
+        return dumpModelAsYaml(context, definition, false, false, true);
     }
 
     @Override
     public String dumpModelAsYaml(
             CamelContext context, NamedNode definition, boolean resolvePlaceholders,
-            boolean uriAsParameters)
+            boolean uriAsParameters, boolean generatedIds)
             throws Exception {
         Properties properties = new Properties();
         Map<String, String> namespaces = new LinkedHashMap<>();
@@ -88,12 +88,11 @@ public class LwModelToYAMLDumper implements ModelToYAMLDumper {
             @Override
             protected void doWriteOptionalIdentifiedDefinitionAttributes(OptionalIdentifiedDefinition<?> def)
                     throws IOException {
-                // write customId if not false
-                if (Boolean.TRUE.equals(def.getCustomId())) {
-                    doWriteAttribute("customId", toString(def.getCustomId()));
+
+                if (generatedIds || Boolean.TRUE.equals(def.getCustomId())) {
+                    // write id
+                    doWriteAttribute("id", def.getId());
                 }
-                // write id
-                doWriteAttribute("id", def.getId());
                 // write location information
                 if (context.isDebugging()) {
                     String loc = (def instanceof RouteDefinition ? ((RouteDefinition) def).getInput() : def).getLocation();


[camel] 04/06: CAMEL-19772: camel-core - Dump routes to include custom beans

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel19772
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 3e46b08af942f53ed3225eeaccfc9de0f83c9f2e
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Aug 23 06:58:42 2023 +0200

    CAMEL-19772: camel-core - Dump routes to include custom beans
---
 .../src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
index 34c83298201..0edff3b4690 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
@@ -558,7 +558,8 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     sb.append("\n</camel>\n");
                     IOHelper.writeText(sb.toString(), file);
                 } catch (Exception e) {
-                    LOG.warn("Error adjusting dumped XML file: {} due to {}. This exception is ignored.", name, e.getMessage(), e);
+                    LOG.warn("Error adjusting dumped XML file: {} due to {}. This exception is ignored.", name, e.getMessage(),
+                            e);
                 }
             }
         }


[camel] 01/06: CAMEL-19772: camel-core - Dump routes to include custom beans

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel19772
in repository https://gitbox.apache.org/repos/asf/camel.git

commit aee85e3555e6505f8269496e86c9a028bb58d9e3
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Aug 22 12:43:33 2023 +0200

    CAMEL-19772: camel-core - Dump routes to include custom beans
---
 .../main/camel-main-configuration-metadata.json    |   2 +-
 .../org/apache/camel/spi/DumpRoutesStrategy.java   |   4 +-
 .../org/apache/camel/spi/ModelToXMLDumper.java     |  12 ++
 .../org/apache/camel/spi/ModelToYAMLDumper.java    |  12 ++
 .../org/apache/camel/impl/DefaultCamelContext.java |  11 ++
 .../camel/impl/DefaultDumpRoutesStrategy.java      | 121 +++++++++++++++++++--
 .../java/org/apache/camel/impl/DefaultModel.java   |  15 +++
 .../org/apache/camel/builder/RouteBuilder.java     |  22 ++++
 .../main/java/org/apache/camel/model/Model.java    |  11 ++
 .../camel-main-configuration-metadata.json         |   2 +-
 core/camel-main/src/main/docs/main.adoc            |   2 +-
 .../camel/main/DefaultConfigurationProperties.java |   8 +-
 .../main/java/org/apache/camel/util/IOHelper.java  |  14 +--
 .../org/apache/camel/xml/LwModelToXMLDumper.java   |  77 +++++++++++++
 .../camel/xml/jaxb/JaxbModelToXMLDumper.java       |  76 +++++++++++++
 .../org/apache/camel/yaml/LwModelToYAMLDumper.java |  81 ++++++++++++++
 .../camel/dsl/xml/io/XmlRoutesBuilderLoader.java   |   6 +
 .../dsl/yaml/deserializers/BeansDeserializer.java  |   6 +
 18 files changed, 455 insertions(+), 27 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index 302701cffaf..6dd2a3c22de 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -40,7 +40,7 @@
     { "name": "camel.main.devConsoleEnabled", "description": "Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.dumpRoutes", "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML\/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml [...]
     { "name": "camel.main.dumpRoutesDirectory", "description": "Whether to save route dumps to files in the given directory. The name of the files are based on original loaded resource, or an autogenerated name.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
-    { "name": "camel.main.dumpRoutesInclude", "description": "Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates. Multiple values can be separated by comma. Default is routes.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "routes" },
+    { "name": "camel.main.dumpRoutesInclude", "description": "Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans. Multiple values can be separated by comma. Default is routes.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "routes" },
     { "name": "camel.main.dumpRoutesLog", "description": "Whether to log route dumps to Logger", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.main.dumpRoutesResolvePlaceholders", "description": "Whether to resolve property placeholders in the dumped output. Default is true.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.main.dumpRoutesUriAsParameters", "description": "When dumping routes to YAML format, then this option controls whether endpoint URIs should be expanded into a key\/value parameters.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java b/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java
index 04cba2962f6..54ad32226d5 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java
@@ -40,8 +40,8 @@ public interface DumpRoutesStrategy extends StaticService {
     /**
      * Controls what to include in output.
      *
-     * Possible values: all, routes, rests, routeConfigurations, routeTemplates. Multiple values can be separated by
-     * comma. Default is routes.
+     * Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans. Multiple values can be separated
+     * by comma. Default is routes.
      */
     void setInclude(String include);
 
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToXMLDumper.java b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToXMLDumper.java
index cbd9b885316..94f5ec8a764 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToXMLDumper.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToXMLDumper.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.spi;
 
+import java.util.List;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.NamedNode;
 
@@ -52,4 +54,14 @@ public interface ModelToXMLDumper {
             CamelContext context, NamedNode definition, boolean resolvePlaceholders)
             throws Exception;
 
+    /**
+     * Dumps the beans as XML
+     *
+     * @param  context   the CamelContext
+     * @param  beans     list of beans (RegistryBeanDefinition)
+     * @return           the output in XML (is formatted)
+     * @throws Exception is throw if error marshalling to XML
+     */
+    String dumpBeansAsXml(CamelContext context, List<Object> beans) throws Exception;
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java
index 6c76313bd9d..6f4ae0f1423 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToYAMLDumper.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.spi;
 
+import java.util.List;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.NamedNode;
 
@@ -54,4 +56,14 @@ public interface ModelToYAMLDumper {
             boolean resolvePlaceholders, boolean uriAsParameters)
             throws Exception;
 
+    /**
+     * Dumps the beans as YAML
+     *
+     * @param  context   the CamelContext
+     * @param  beans     list of beans (RegistryBeanDefinition)
+     * @return           the output in YAML (is formatted)
+     * @throws Exception is throw if error marshalling to YAML
+     */
+    String dumpBeansAsYaml(CamelContext context, List<Object> beans) throws Exception;
+
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 582c9848026..6752f19be27 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -56,6 +56,7 @@ import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RouteDefinitionHelper;
 import org.apache.camel.model.RouteTemplateDefinition;
 import org.apache.camel.model.TemplatedRouteDefinition;
+import org.apache.camel.model.app.RegistryBeanDefinition;
 import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.rest.RestDefinition;
@@ -517,6 +518,16 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
         return model.getRouteFilter();
     }
 
+    @Override
+    public void addRegistryBean(RegistryBeanDefinition bean) {
+        model.addRegistryBean(bean);
+    }
+
+    @Override
+    public List<RegistryBeanDefinition> getRegistryBeans() {
+        return model.getRegistryBeans();
+    }
+
     @Override
     public ModelReifierFactory getModelReifierFactory() {
         return model.getModelReifierFactory();
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
index efbf597efe0..4e550933bf3 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
@@ -19,8 +19,12 @@ package org.apache.camel.impl;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.camel.CamelContext;
@@ -33,6 +37,7 @@ import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RouteTemplateDefinition;
 import org.apache.camel.model.RouteTemplatesDefinition;
 import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.app.RegistryBeanDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
 import org.apache.camel.spi.DumpRoutesStrategy;
@@ -57,6 +62,9 @@ import static org.apache.camel.support.LoggerHelper.stripSourceLocationLineNumbe
 @ServiceFactory("default-" + DumpRoutesStrategy.FACTORY)
 public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRoutesStrategy, CamelContextAware {
 
+    // TODO: XML to disk with beans should use <camel>
+    // TODO: inlined routes in <camel> should be array of <route> and not have <routes>
+
     private static final Logger LOG = LoggerFactory.getLogger(DefaultDumpRoutesStrategy.class);
     private static final String DIVIDER = "--------------------------------------------------------------------------------";
 
@@ -132,6 +140,36 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
         final ModelToYAMLDumper dumper = PluginHelper.getModelToYAMLDumper(camelContext);
         final Model model = camelContext.getCamelContextExtension().getContextPlugin(Model.class);
         final DummyResource dummy = new DummyResource(null, null);
+        final Set<String> files = new HashSet<>();
+
+        if (include.contains("*") || include.contains("all") || include.contains("beans")) {
+            int size = model.getRegistryBeans().size();
+            if (size > 0) {
+                Map<Resource, List<RegistryBeanDefinition>> groups = new LinkedHashMap<>();
+                for (RegistryBeanDefinition bean : model.getRegistryBeans()) {
+                    Resource res = bean.getResource();
+                    if (res == null) {
+                        res = dummy;
+                    }
+                    List<RegistryBeanDefinition> beans = groups.computeIfAbsent(res, resource -> new ArrayList<>());
+                    beans.add(bean);
+                }
+                StringBuilder sbLog = new StringBuilder();
+                for (Map.Entry<Resource, List<RegistryBeanDefinition>> entry : groups.entrySet()) {
+                    List<RegistryBeanDefinition> beans = entry.getValue();
+                    Resource resource = entry.getKey();
+
+                    StringBuilder sbLocal = new StringBuilder();
+                    doDumpYamlBeans(camelContext, beans, resource == dummy ? null : resource, dumper, "beans", sbLocal, sbLog);
+                    // dump each resource into its own file
+                    doDumpToDirectory(resource, sbLocal, "beans", "yaml", files);
+                }
+                if (!sbLog.isEmpty() && log) {
+                    LOG.info("Dumping {} beans as YAML", size);
+                    LOG.info("{}", sbLog);
+                }
+            }
+        }
 
         if (include.contains("*") || include.contains("all") || include.contains("routes")) {
             int size = model.getRouteDefinitions().size();
@@ -153,7 +191,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     StringBuilder sbLocal = new StringBuilder();
                     doDumpYaml(camelContext, def, resource == dummy ? null : resource, dumper, "routes", sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpToDirectory(resource, sbLocal, "routes", "yaml");
+                    doDumpToDirectory(resource, sbLocal, "routes", "yaml", files);
                 }
                 if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} routes as YAML", size);
@@ -185,7 +223,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     doDumpYaml(camelContext, def, resource == dummy ? null : resource, dumper, "route-configurations", sbLocal,
                             sbLog);
                     // dump each resource into its own file
-                    doDumpToDirectory(resource, sbLocal, "route-configurations", "yaml");
+                    doDumpToDirectory(resource, sbLocal, "route-configurations", "yaml", files);
                 }
                 if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} route-configurations as YAML", size);
@@ -214,7 +252,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     StringBuilder sbLocal = new StringBuilder();
                     doDumpYaml(camelContext, def, resource == dummy ? null : resource, dumper, "rests", sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpToDirectory(resource, sbLocal, "rests", "yaml");
+                    doDumpToDirectory(resource, sbLocal, "rests", "yaml", files);
                 }
                 if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} rests as YAML", size);
@@ -245,7 +283,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     doDumpYaml(camelContext, def, resource == dummy ? null : resource, dumper, "route-templates", sbLocal,
                             sbLog);
                     // dump each resource into its own file
-                    doDumpToDirectory(resource, sbLocal, "route-templates", "yaml");
+                    doDumpToDirectory(resource, sbLocal, "route-templates", "yaml", files);
                 }
                 if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} route-templates as YAML", size);
@@ -267,10 +305,52 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
         }
     }
 
+    protected void doDumpYamlBeans(
+            CamelContext camelContext, List beans, Resource resource,
+            ModelToYAMLDumper dumper, String kind, StringBuilder sbLocal, StringBuilder sbLog) {
+        try {
+            String dump = dumper.dumpBeansAsYaml(camelContext, beans);
+            sbLocal.append(dump);
+            appendLogDump(resource, dump, sbLog);
+        } catch (Exception e) {
+            LOG.warn("Error dumping {}} to YAML due to {}. This exception is ignored.", kind, e.getMessage(), e);
+        }
+    }
+
     protected void doDumpRoutesAsXml(CamelContext camelContext) {
         final ModelToXMLDumper dumper = PluginHelper.getModelToXMLDumper(camelContext);
         final Model model = camelContext.getCamelContextExtension().getContextPlugin(Model.class);
         final DummyResource dummy = new DummyResource(null, null);
+        final Set<String> files = new HashSet<>();
+
+        if (include.contains("*") || include.contains("all") || include.contains("beans")) {
+            int size = model.getRegistryBeans().size();
+            if (size > 0) {
+                Map<Resource, List<RegistryBeanDefinition>> groups = new LinkedHashMap<>();
+                for (RegistryBeanDefinition bean : model.getRegistryBeans()) {
+                    Resource res = bean.getResource();
+                    if (res == null) {
+                        res = dummy;
+                    }
+                    List<RegistryBeanDefinition> beans = groups.computeIfAbsent(res, resource -> new ArrayList<>());
+                    beans.add(bean);
+                }
+                StringBuilder sbLog = new StringBuilder();
+                for (Map.Entry<Resource, List<RegistryBeanDefinition>> entry : groups.entrySet()) {
+                    List<RegistryBeanDefinition> beans = entry.getValue();
+                    Resource resource = entry.getKey();
+
+                    StringBuilder sbLocal = new StringBuilder();
+                    doDumpXmlBeans(camelContext, beans, resource == dummy ? null : resource, dumper, "beans", sbLocal, sbLog);
+                    // dump each resource into its own file
+                    doDumpToDirectory(resource, sbLocal, "beans", "xml", files);
+                }
+                if (!sbLog.isEmpty() && log) {
+                    LOG.info("Dumping {} beans as XML", size);
+                    LOG.info("{}", sbLog);
+                }
+            }
+        }
 
         if (include.contains("*") || include.contains("all") || include.contains("routes")) {
             int size = model.getRouteDefinitions().size();
@@ -293,7 +373,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     doDumpXml(camelContext, def, resource == dummy ? null : resource, dumper, "route", "routes", sbLocal,
                             sbLog);
                     // dump each resource into its own file
-                    doDumpToDirectory(resource, sbLocal, "routes", "xml");
+                    doDumpToDirectory(resource, sbLocal, "routes", "xml", files);
                 }
                 if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} routes as XML", size);
@@ -325,7 +405,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     doDumpXml(camelContext, def, resource == dummy ? null : resource, dumper, "rest", "route-configurations",
                             sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpToDirectory(resource, sbLocal, "route-configurations", "xml");
+                    doDumpToDirectory(resource, sbLocal, "route-configurations", "xml", files);
                 }
                 if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} route-configurations as XML", size);
@@ -354,7 +434,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     StringBuilder sbLocal = new StringBuilder();
                     doDumpXml(camelContext, def, resource == dummy ? null : resource, dumper, "rest", "rests", sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpToDirectory(resource, sbLocal, "rests", "xml");
+                    doDumpToDirectory(resource, sbLocal, "rests", "xml", files);
                 }
                 if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} rests as XML", size);
@@ -385,7 +465,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     doDumpXml(camelContext, def, resource == dummy ? null : resource, dumper, "routeTemplate",
                             "route-templates", sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpToDirectory(resource, sbLocal, "route-templates", "xml");
+                    doDumpToDirectory(resource, sbLocal, "route-templates", "xml", files);
                 }
                 if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} route-templates as XML", size);
@@ -395,6 +475,18 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
         }
     }
 
+    protected void doDumpXmlBeans(
+            CamelContext camelContext, List beans, Resource resource,
+            ModelToXMLDumper dumper, String kind, StringBuilder sbLocal, StringBuilder sbLog) {
+        try {
+            String dump = dumper.dumpBeansAsXml(camelContext, beans);
+            sbLocal.append(dump);
+            appendLogDump(resource, dump, sbLog);
+        } catch (Exception e) {
+            LOG.warn("Error dumping {}} to XML due to {}. This exception is ignored.", kind, e.getMessage(), e);
+        }
+    }
+
     protected void doDumpXml(
             CamelContext camelContext, NamedNode def, Resource resource,
             ModelToXMLDumper dumper, String replace, String kind, StringBuilder sbLocal, StringBuilder sbLog) {
@@ -411,7 +503,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
         }
     }
 
-    protected void doDumpToDirectory(Resource resource, StringBuilder sbLocal, String kind, String ext) {
+    protected void doDumpToDirectory(Resource resource, StringBuilder sbLocal, String kind, String ext, Set<String> files) {
         if (directory != null && !sbLocal.isEmpty()) {
             // make sure directory exists
             File dir = new File(directory);
@@ -425,10 +517,19 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
             if (name.contains(":")) {
                 name = StringHelper.after(name, ":");
             }
+
             name = FileUtil.onlyName(name) + "." + ext;
+            boolean newFile = files.isEmpty() || !files.contains(name);
             File target = new File(directory, name);
             try {
-                IOHelper.writeText(sbLocal.toString(), target);
+                if (newFile) {
+                    // write as new file (override old file if exists)
+                    IOHelper.writeText(sbLocal.toString(), target);
+                } else {
+                    // append to existing file
+                    IOHelper.appendText(sbLocal.toString(), target);
+                }
+                files.add(name);
                 LOG.info("Dumped {} to file: {}", kind, target);
             } catch (IOException e) {
                 throw new RuntimeException("Error dumping " + kind + " to file: " + target, e);
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
index dbbf80ce1f6..729bb3ce5ff 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
@@ -56,6 +56,7 @@ import org.apache.camel.model.TemplatedRouteBeanDefinition;
 import org.apache.camel.model.TemplatedRouteDefinition;
 import org.apache.camel.model.TemplatedRouteParameterDefinition;
 import org.apache.camel.model.ToDefinition;
+import org.apache.camel.model.app.RegistryBeanDefinition;
 import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
@@ -91,6 +92,8 @@ public class DefaultModel implements Model {
     private Map<String, DataFormatDefinition> dataFormats = new HashMap<>();
     private List<TransformerDefinition> transformers = new ArrayList<>();
     private List<ValidatorDefinition> validators = new ArrayList<>();
+    // XML and YAML DSL allows to declare beans in the DSL
+    private List<RegistryBeanDefinition> beans = new ArrayList<>();
     private final Map<String, ServiceCallConfigurationDefinition> serviceCallConfigurations = new ConcurrentHashMap<>();
     private final Map<String, Resilience4jConfigurationDefinition> resilience4jConfigurations = new ConcurrentHashMap<>();
     private final Map<String, FaultToleranceConfigurationDefinition> faultToleranceConfigurations = new ConcurrentHashMap<>();
@@ -917,6 +920,18 @@ public class DefaultModel implements Model {
         this.modelReifierFactory = modelReifierFactory;
     }
 
+    @Override
+    public void addRegistryBean(RegistryBeanDefinition bean) {
+        // remove exiting bean with same name to update
+        beans.removeIf(b -> bean.getName().equals(b.getName()));
+        beans.add(bean);
+    }
+
+    @Override
+    public List<RegistryBeanDefinition> getRegistryBeans() {
+        return beans;
+    }
+
     /**
      * Should we start newly added routes?
      */
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/builder/RouteBuilder.java b/core/camel-core-model/src/main/java/org/apache/camel/builder/RouteBuilder.java
index 3c99c0c385a..048ccc05416 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/builder/RouteBuilder.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/builder/RouteBuilder.java
@@ -46,6 +46,7 @@ import org.apache.camel.model.RouteTemplatesDefinition;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.TemplatedRouteDefinition;
 import org.apache.camel.model.TemplatedRoutesDefinition;
+import org.apache.camel.model.app.RegistryBeanDefinition;
 import org.apache.camel.model.errorhandler.RefErrorHandlerDefinition;
 import org.apache.camel.model.rest.RestConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
@@ -75,6 +76,8 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
     private final List<RouteBuilderLifecycleStrategy> lifecycleInterceptors = new ArrayList<>();
     private final List<TransformerBuilder> transformerBuilders = new ArrayList<>();
     private final List<ValidatorBuilder> validatorBuilders = new ArrayList<>();
+    // XML and YAML DSL allows to define custom beans which we need to capture
+    private final List<RegistryBeanDefinition> beans = new ArrayList<>();
 
     private RestsDefinition restCollection = new RestsDefinition();
     private RestConfigurationDefinition restConfiguration;
@@ -603,6 +606,7 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
         configureRests(context);
 
         // but populate rests before routes, as we want to turn rests into routes
+        populateBeans();
         populateRests();
         populateTransformers();
         populateValidators();
@@ -633,6 +637,7 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
         configureRests(context);
 
         // but populate rests before routes, as we want to turn rests into routes
+        populateBeans();
         populateRests();
         populateTransformers();
         populateValidators();
@@ -731,6 +736,9 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
             getRouteCollection().setResource(getResource());
             getRestCollection().setResource(getResource());
             getRouteTemplateCollection().setResource(getResource());
+            for (RegistryBeanDefinition def : beans) {
+                def.setResource(getResource());
+            }
 
             for (RouteDefinition route : getRouteCollection().getRoutes()) {
                 // ensure the route is prepared after configure method is complete
@@ -855,6 +863,20 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
         }
     }
 
+    protected void populateBeans() {
+        CamelContext camelContext = notNullCamelContext();
+
+        Model model = camelContext.getCamelContextExtension().getContextPlugin(Model.class);
+        for (RegistryBeanDefinition def : beans) {
+            // add to model
+            model.addRegistryBean(def);
+        }
+    }
+
+    public List<RegistryBeanDefinition> getBeans() {
+        return beans;
+    }
+
     public RestsDefinition getRestCollection() {
         return restCollection;
     }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/Model.java b/core/camel-core-model/src/main/java/org/apache/camel/model/Model.java
index 7008c586159..7efa1b59452 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/Model.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/Model.java
@@ -23,6 +23,7 @@ import java.util.function.Function;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.RouteTemplateContext;
+import org.apache.camel.model.app.RegistryBeanDefinition;
 import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
@@ -489,4 +490,14 @@ public interface Model {
      */
     void setModelReifierFactory(ModelReifierFactory modelReifierFactory);
 
+    /**
+     * Adds the custom bean
+     */
+    void addRegistryBean(RegistryBeanDefinition bean);
+
+    /**
+     * Gets the custom beans
+     */
+    List<RegistryBeanDefinition> getRegistryBeans();
+
 }
diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 302701cffaf..6dd2a3c22de 100644
--- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -40,7 +40,7 @@
     { "name": "camel.main.devConsoleEnabled", "description": "Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.dumpRoutes", "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML\/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml [...]
     { "name": "camel.main.dumpRoutesDirectory", "description": "Whether to save route dumps to files in the given directory. The name of the files are based on original loaded resource, or an autogenerated name.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
-    { "name": "camel.main.dumpRoutesInclude", "description": "Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates. Multiple values can be separated by comma. Default is routes.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "routes" },
+    { "name": "camel.main.dumpRoutesInclude", "description": "Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans. Multiple values can be separated by comma. Default is routes.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "routes" },
     { "name": "camel.main.dumpRoutesLog", "description": "Whether to log route dumps to Logger", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.main.dumpRoutesResolvePlaceholders", "description": "Whether to resolve property placeholders in the dumped output. Default is true.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.main.dumpRoutesUriAsParameters", "description": "When dumping routes to YAML format, then this option controls whether endpoint URIs should be expanded into a key\/value parameters.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index 190214d6498..b0c27393219 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -51,7 +51,7 @@ The camel.main supports 125 options, which are listed below.
 | *camel.main.devConsoleEnabled* | Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage. | false | boolean
 | *camel.main.dumpRoutes* | If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml-io/camel-yaml-io on the cla [...]
 | *camel.main.dumpRoutesDirectory* | Whether to save route dumps to files in the given directory. The name of the files are based on original loaded resource, or an autogenerated name. |  | String
-| *camel.main.dumpRoutesInclude* | Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates. Multiple values can be separated by comma. Default is routes. | routes | String
+| *camel.main.dumpRoutesInclude* | Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans. Multiple values can be separated by comma. Default is routes. | routes | String
 | *camel.main.dumpRoutesLog* | Whether to log route dumps to Logger | true | boolean
 | *camel.main.dumpRoutesResolve{zwsp}Placeholders* | Whether to resolve property placeholders in the dumped output. Default is true. | true | boolean
 | *camel.main.dumpRoutesUriAs{zwsp}Parameters* | When dumping routes to YAML format, then this option controls whether endpoint URIs should be expanded into a key/value parameters. | false | boolean
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index e962f1a8825..29a092a3935 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -1398,8 +1398,8 @@ public abstract class DefaultConfigurationProperties<T> {
     /**
      * Controls what to include in output for route dumping.
      *
-     * Possible values: all, routes, rests, routeConfigurations, routeTemplates. Multiple values can be separated by
-     * comma. Default is routes.
+     * Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans. Multiple values can be separated
+     * by comma. Default is routes.
      */
     public void setDumpRoutesInclude(String dumpRoutesInclude) {
         this.dumpRoutesInclude = dumpRoutesInclude;
@@ -2646,8 +2646,8 @@ public abstract class DefaultConfigurationProperties<T> {
     /**
      * Controls what to include in output for route dumping.
      *
-     * Possible values: all, routes, rests, routeConfigurations, routeTemplates. Multiple values can be separated by
-     * comma. Default is routes.
+     * Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans. Multiple values can be separated
+     * by comma. Default is routes.
      */
     public T withDumpRoutesInclude(String dumpRoutesInclude) {
         this.dumpRoutesInclude = dumpRoutesInclude;
diff --git a/core/camel-util/src/main/java/org/apache/camel/util/IOHelper.java b/core/camel-util/src/main/java/org/apache/camel/util/IOHelper.java
index d0c76c2e08b..e18d2168e46 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/IOHelper.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/IOHelper.java
@@ -479,26 +479,24 @@ public final class IOHelper {
      * Appends the text to the file.
      */
     public static void appendText(String text, File file) throws IOException {
-        if (!file.exists()) {
-            String path = FileUtil.onlyPath(file.getPath());
-            if (path != null) {
-                new File(path).mkdirs();
-            }
-        }
-        writeText(text, new FileOutputStream(file, true));
+        doWriteText(text, file, true);
     }
 
     /**
      * Writes the text to the file.
      */
     public static void writeText(String text, File file) throws IOException {
+        doWriteText(text, file, false);
+    }
+
+    private static void doWriteText(String text, File file, boolean append) throws IOException {
         if (!file.exists()) {
             String path = FileUtil.onlyPath(file.getPath());
             if (path != null) {
                 new File(path).mkdirs();
             }
         }
-        writeText(text, new FileOutputStream(file, false));
+        writeText(text, new FileOutputStream(file, append));
     }
 
     /**
diff --git a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
index 5e379f9836a..db76fe5ca41 100644
--- a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
+++ b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
@@ -18,14 +18,17 @@ package org.apache.camel.xml;
 
 import java.io.IOException;
 import java.io.StringWriter;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.function.Consumer;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
 import org.apache.camel.Expression;
 import org.apache.camel.NamedNode;
 import org.apache.camel.model.ExpressionNode;
@@ -37,6 +40,7 @@ import org.apache.camel.model.RouteTemplatesDefinition;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.SendDefinition;
 import org.apache.camel.model.ToDynamicDefinition;
+import org.apache.camel.model.app.RegistryBeanDefinition;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.spi.ModelToXMLDumper;
 import org.apache.camel.spi.NamespaceAware;
@@ -173,6 +177,28 @@ public class LwModelToXMLDumper implements ModelToXMLDumper {
         return buffer.toString();
     }
 
+    @Override
+    public String dumpBeansAsXml(CamelContext context, List<Object> beans) throws Exception {
+        StringWriter buffer = new StringWriter();
+        BeanModelWriter writer = new BeanModelWriter(buffer);
+
+        List<RegistryBeanDefinition> list = new ArrayList<>();
+        for (Object bean : beans) {
+            if (bean instanceof RegistryBeanDefinition rb) {
+                list.add(rb);
+            }
+        }
+        writer.setCamelContext(context);
+        writer.start();
+        try {
+            writer.writeBeans(list);
+        } finally {
+            writer.stop();
+        }
+
+        return buffer.toString();
+    }
+
     /**
      * Extract all XML namespaces from the expressions in the route
      *
@@ -258,4 +284,55 @@ public class LwModelToXMLDumper implements ModelToXMLDumper {
         return na;
     }
 
+    private static class BeanModelWriter implements CamelContextAware {
+
+        private final StringWriter buffer;
+        private CamelContext camelContext;
+
+        public BeanModelWriter(StringWriter buffer) {
+            this.buffer = buffer;
+        }
+
+        @Override
+        public CamelContext getCamelContext() {
+            return camelContext;
+        }
+
+        @Override
+        public void setCamelContext(CamelContext camelContext) {
+            this.camelContext = camelContext;
+        }
+
+        public void start() {
+            // noop
+        }
+
+        public void stop() {
+            // noop
+        }
+
+        public void writeBeans(List<RegistryBeanDefinition> beans) {
+            if (beans.isEmpty()) {
+                return;
+            }
+            for (RegistryBeanDefinition b : beans) {
+                doWriteRegistryBeanDefinition(b);
+            }
+        }
+
+        private void doWriteRegistryBeanDefinition(RegistryBeanDefinition b) {
+            buffer.write(String.format("    <bean name=\"%s\" type=\"%s\">%n", b.getName(), b.getType()));
+            if (b.getProperties() != null && !b.getProperties().isEmpty()) {
+                buffer.write(String.format("        <properties>%n"));
+                for (Map.Entry<String, Object> entry : b.getProperties().entrySet()) {
+                    String key = entry.getKey();
+                    Object value = entry.getValue();
+                    buffer.write(String.format("            <property key=\"%s\" value=\"%s\"/>%n", key, value));
+                }
+                buffer.write(String.format("        </properties>%n"));
+            }
+            buffer.write(String.format("    </bean>%n"));
+        }
+    }
+
 }
diff --git a/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java b/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
index 3bf298e862e..266162386b4 100644
--- a/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
+++ b/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
@@ -20,6 +20,7 @@ import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.io.StringWriter;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -40,6 +41,7 @@ import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
 import org.apache.camel.NamedNode;
 import org.apache.camel.TypeConversionException;
 import org.apache.camel.converter.jaxp.XmlConverter;
@@ -47,6 +49,7 @@ import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RouteTemplateDefinition;
 import org.apache.camel.model.RouteTemplatesDefinition;
 import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.app.RegistryBeanDefinition;
 import org.apache.camel.spi.ModelToXMLDumper;
 import org.apache.camel.spi.PropertiesComponent;
 import org.apache.camel.spi.annotations.JdkService;
@@ -216,6 +219,28 @@ public class JaxbModelToXMLDumper implements ModelToXMLDumper {
         return xml;
     }
 
+    @Override
+    public String dumpBeansAsXml(CamelContext context, List<Object> beans) throws Exception {
+        StringWriter buffer = new StringWriter();
+        BeanModelWriter writer = new BeanModelWriter(buffer);
+
+        List<RegistryBeanDefinition> list = new ArrayList<>();
+        for (Object bean : beans) {
+            if (bean instanceof RegistryBeanDefinition rb) {
+                list.add(rb);
+            }
+        }
+        writer.setCamelContext(context);
+        writer.start();
+        try {
+            writer.writeBeans(list);
+        } finally {
+            writer.stop();
+        }
+
+        return buffer.toString();
+    }
+
     private static void sanitizeXml(Node node) {
         // we want to remove all customId="false" attributes as they are noisy
         if (node.hasAttributes()) {
@@ -260,4 +285,55 @@ public class JaxbModelToXMLDumper implements ModelToXMLDumper {
         }
     }
 
+    private static class BeanModelWriter implements CamelContextAware {
+
+        private final StringWriter buffer;
+        private CamelContext camelContext;
+
+        public BeanModelWriter(StringWriter buffer) {
+            this.buffer = buffer;
+        }
+
+        @Override
+        public CamelContext getCamelContext() {
+            return camelContext;
+        }
+
+        @Override
+        public void setCamelContext(CamelContext camelContext) {
+            this.camelContext = camelContext;
+        }
+
+        public void start() {
+            // noop
+        }
+
+        public void stop() {
+            // noop
+        }
+
+        public void writeBeans(List<RegistryBeanDefinition> beans) {
+            if (beans.isEmpty()) {
+                return;
+            }
+            for (RegistryBeanDefinition b : beans) {
+                doWriteRegistryBeanDefinition(b);
+            }
+        }
+
+        private void doWriteRegistryBeanDefinition(RegistryBeanDefinition b) {
+            buffer.write(String.format("    <bean name=\"%s\" type=\"%s\">%n", b.getName(), b.getType()));
+            if (b.getProperties() != null && !b.getProperties().isEmpty()) {
+                buffer.write(String.format("        <properties>%n"));
+                for (Map.Entry<String, Object> entry : b.getProperties().entrySet()) {
+                    String key = entry.getKey();
+                    Object value = entry.getValue();
+                    buffer.write(String.format("            <property key=\"%s\" value=\"%s\"/>%n", key, value));
+                }
+                buffer.write(String.format("        </properties>%n"));
+            }
+            buffer.write(String.format("    </bean>%n"));
+        }
+    }
+
 }
diff --git a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
index de16de01052..72e52a6f93b 100644
--- a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
+++ b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/LwModelToYAMLDumper.java
@@ -18,14 +18,17 @@ package org.apache.camel.yaml;
 
 import java.io.IOException;
 import java.io.StringWriter;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.function.Consumer;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
 import org.apache.camel.Expression;
 import org.apache.camel.NamedNode;
 import org.apache.camel.model.ExpressionNode;
@@ -37,6 +40,7 @@ import org.apache.camel.model.RouteTemplatesDefinition;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.SendDefinition;
 import org.apache.camel.model.ToDynamicDefinition;
+import org.apache.camel.model.app.RegistryBeanDefinition;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.spi.ModelToYAMLDumper;
 import org.apache.camel.spi.NamespaceAware;
@@ -160,6 +164,28 @@ public class LwModelToYAMLDumper implements ModelToYAMLDumper {
         return buffer.toString();
     }
 
+    @Override
+    public String dumpBeansAsYaml(CamelContext context, List<Object> beans) throws Exception {
+        StringWriter buffer = new StringWriter();
+        BeanModelWriter writer = new BeanModelWriter(buffer);
+
+        List<RegistryBeanDefinition> list = new ArrayList<>();
+        for (Object bean : beans) {
+            if (bean instanceof RegistryBeanDefinition rb) {
+                list.add(rb);
+            }
+        }
+        writer.setCamelContext(context);
+        writer.start();
+        try {
+            writer.writeBeans(list);
+        } finally {
+            writer.stop();
+        }
+
+        return buffer.toString();
+    }
+
     /**
      * Extract all XML namespaces from the expressions in the route
      *
@@ -245,4 +271,59 @@ public class LwModelToYAMLDumper implements ModelToYAMLDumper {
         return na;
     }
 
+    private static class BeanModelWriter implements CamelContextAware {
+
+        private final StringWriter buffer;
+        private CamelContext camelContext;
+
+        public BeanModelWriter(StringWriter buffer) {
+            this.buffer = buffer;
+        }
+
+        @Override
+        public CamelContext getCamelContext() {
+            return camelContext;
+        }
+
+        @Override
+        public void setCamelContext(CamelContext camelContext) {
+            this.camelContext = camelContext;
+        }
+
+        public void start() {
+            // noop
+        }
+
+        public void stop() {
+            // noop
+        }
+
+        public void writeBeans(List<RegistryBeanDefinition> beans) {
+            if (beans.isEmpty()) {
+                return;
+            }
+            buffer.write("- beans:\n");
+            for (RegistryBeanDefinition b : beans) {
+                doWriteRegistryBeanDefinition(b);
+            }
+        }
+
+        private void doWriteRegistryBeanDefinition(RegistryBeanDefinition b) {
+            buffer.write(String.format("    - name: %s%n", b.getName()));
+            buffer.write(String.format("      type: %s%n", b.getType()));
+            if (b.getProperties() != null && !b.getProperties().isEmpty()) {
+                buffer.write(String.format("      properties:%n"));
+                for (Map.Entry<String, Object> entry : b.getProperties().entrySet()) {
+                    String key = entry.getKey();
+                    Object value = entry.getValue();
+                    if (value instanceof String) {
+                        buffer.write(String.format("        %s: \"%s\"%n", key, value));
+                    } else {
+                        buffer.write(String.format("        %s: %s%n", key, value));
+                    }
+                }
+            }
+        }
+    }
+
 }
diff --git a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
index 91cd9354341..2cfb1a2341c 100644
--- a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
+++ b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java
@@ -32,6 +32,7 @@ import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.builder.RouteConfigurationBuilder;
 import org.apache.camel.dsl.support.RouteBuilderLoaderSupport;
+import org.apache.camel.model.Model;
 import org.apache.camel.model.RouteConfigurationDefinition;
 import org.apache.camel.model.RouteConfigurationsDefinition;
 import org.apache.camel.model.RouteDefinition;
@@ -320,6 +321,11 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport {
                 }
                 getCamelContext().getRegistry().unbind(name);
                 getCamelContext().getRegistry().bind(name, target);
+
+                // register bean in model
+                Model model = getCamelContext().getCamelContextExtension().getContextPlugin(Model.class);
+                model.addRegistryBean(def);
+
             } catch (Exception e) {
                 if (delayIfFailed) {
                     delayedRegistrations.add(def);
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
index 5cd0301f3eb..4be1c650219 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
@@ -24,6 +24,7 @@ import org.apache.camel.dsl.yaml.common.YamlDeserializationContext;
 import org.apache.camel.dsl.yaml.common.YamlDeserializerResolver;
 import org.apache.camel.dsl.yaml.common.YamlDeserializerSupport;
 import org.apache.camel.dsl.yaml.common.YamlSupport;
+import org.apache.camel.model.Model;
 import org.apache.camel.model.app.RegistryBeanDefinition;
 import org.apache.camel.spi.CamelContextCustomizer;
 import org.apache.camel.spi.annotations.YamlIn;
@@ -74,6 +75,11 @@ public class BeansDeserializer extends YamlDeserializerSupport implements Constr
                         camelContext.getRegistry().bind(
                                 name,
                                 newInstance(bean, camelContext));
+
+                        // register bean in model
+                        Model model = camelContext.getCamelContextExtension().getContextPlugin(Model.class);
+                        model.addRegistryBean(bean);
+
                     } catch (Exception e) {
                         throw new RuntimeException(e);
                     }


[camel] 02/06: CAMEL-19772: camel-core - Dump routes to include custom beans

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel19772
in repository https://gitbox.apache.org/repos/asf/camel.git

commit c7b5a815def510102a700a9c45bf18f206302b1f
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Aug 22 12:51:55 2023 +0200

    CAMEL-19772: camel-core - Dump routes to include custom beans
---
 .../src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
index 4e550933bf3..1e999ad7c36 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
@@ -63,7 +63,7 @@ import static org.apache.camel.support.LoggerHelper.stripSourceLocationLineNumbe
 public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRoutesStrategy, CamelContextAware {
 
     // TODO: XML to disk with beans should use <camel>
-    // TODO: inlined routes in <camel> should be array of <route> and not have <routes>
+    // TODO: inlined routes in <camel> should be array of <route> and not have <routes> (the same for rests, etc.)
 
     private static final Logger LOG = LoggerFactory.getLogger(DefaultDumpRoutesStrategy.class);
     private static final String DIVIDER = "--------------------------------------------------------------------------------";