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/21 11:55:51 UTC

[camel] 12/14: CAMEL-19765: camel-core - SPI for DumpRouteStrategy.

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

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

commit 6e44597538a54e2974d1bac7832a60083b1ac831
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 21 13:37:23 2023 +0200

    CAMEL-19765: camel-core - SPI for DumpRouteStrategy.
---
 .../org/apache/camel/spi/DumpRoutesStrategy.java   |   4 +-
 .../camel/impl/engine/SimpleCamelContext.java      |   4 +-
 .../org/apache/camel/impl/DefaultCamelContext.java |  28 ++----
 .../camel/impl/DefaultDumpRoutesStrategy.java      | 100 ++++++++++-----------
 .../MainConfigurationPropertiesConfigurer.java     |  24 +++++
 .../camel-main-configuration-metadata.json         |   4 +
 core/camel-main/src/main/docs/main.adoc            |   6 +-
 .../camel/main/DefaultConfigurationConfigurer.java |   8 ++
 .../camel/main/DefaultConfigurationProperties.java |  88 ++++++++++++++++++
 .../management/ManagedRouteDumpStrategyTest.java   |   9 +-
 10 files changed, 193 insertions(+), 82 deletions(-)

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 60ae15908a0..74c129aad22 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
@@ -54,8 +54,8 @@ public interface DumpRoutesStrategy extends StaticService {
     String getDirectory();
 
     /**
-     * Whether to save route dumps to files in the given directory. The name of the files are based on ids (route ids,
-     * etc.). Existing files will be overwritten.
+     * 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.
      */
     void setDirectory(String directory);
 
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index be963980977..49ca74f5a37 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -91,7 +91,6 @@ import org.apache.camel.spi.UnitOfWorkFactory;
 import org.apache.camel.spi.UriFactoryResolver;
 import org.apache.camel.spi.UuidGenerator;
 import org.apache.camel.spi.ValidatorRegistry;
-import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.DefaultRegistry;
 import org.apache.camel.support.DefaultUuidGenerator;
 import org.apache.camel.support.NormalizedUri;
@@ -414,8 +413,7 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     protected DumpRoutesStrategy createDumpRoutesStrategy() {
-        // any custom in registry
-        DumpRoutesStrategy answer = CamelContextHelper.findSingleByType(this, DumpRoutesStrategy.class);
+        DumpRoutesStrategy answer = getCamelContextReference().hasService(DumpRoutesStrategy.class);
         if (answer != null) {
             return answer;
         }
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 99c793c57fe..582c9848026 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
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.impl;
 
-import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -71,7 +70,6 @@ import org.apache.camel.spi.LocalBeanRepositoryAware;
 import org.apache.camel.spi.ModelReifierFactory;
 import org.apache.camel.spi.PackageScanClassResolver;
 import org.apache.camel.spi.PropertiesComponent;
-import org.apache.camel.spi.PropertyConfigurer;
 import org.apache.camel.spi.Registry;
 import org.apache.camel.spi.StartupStepRecorder;
 import org.apache.camel.spi.Transformer;
@@ -80,14 +78,10 @@ import org.apache.camel.spi.Validator;
 import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.DefaultRegistry;
 import org.apache.camel.support.LocalBeanRegistry;
-import org.apache.camel.support.PluginHelper;
-import org.apache.camel.support.PropertyBindingSupport;
 import org.apache.camel.support.SimpleUuidGenerator;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.OrderedLocationProperties;
 import org.apache.camel.util.StopWatch;
-import org.apache.camel.util.StringHelper;
-import org.apache.camel.util.URISupport;
 import org.apache.camel.util.concurrent.NamedThreadLocal;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -154,24 +148,12 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
 
     @Override
     protected void doDumpRoutes() {
-        DumpRoutesStrategy strategy = getCamelContextExtension().getContextPlugin(DumpRoutesStrategy.class);
+        DumpRoutesStrategy strategy = CamelContextHelper.findSingleByType(this, DumpRoutesStrategy.class);
+        if (strategy == null) {
+            strategy = getCamelContextExtension().getContextPlugin(DumpRoutesStrategy.class);
+        }
         if (strategy != null) {
-            String format = getDumpRoutes();
-            if (format.contains("?")) {
-                // advanced configuration using query parameters
-                String query = StringHelper.after(format, "?");
-                format = StringHelper.before(format, "?");
-                try {
-                    Map<String, Object> map = URISupport.parseQuery(query);
-                    PropertyConfigurer configurer = PluginHelper.getConfigurerResolver(this)
-                            .resolvePropertyConfigurer(strategy.getClass().getName(), this);
-                    PropertyBindingSupport.build().withCamelContext(this).withConfigurer(configurer)
-                            .withProperties(map).withTarget(strategy).bind();
-                } catch (URISyntaxException e) {
-                    throw new IllegalArgumentException("Invalid query parameters for dumpRoutes", e);
-                }
-            }
-            strategy.dumpRoutes(format);
+            strategy.dumpRoutes(getDumpRoutes());
         }
     }
 
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 ca28c5fa828..c18ff5c52f5 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
@@ -134,20 +134,19 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     RoutesDefinition routes = groups.computeIfAbsent(res, resource -> new RoutesDefinition());
                     routes.getRoutes().add(route);
                 }
-                StringBuilder sb = new StringBuilder();
+                StringBuilder sbLog = new StringBuilder();
                 for (Map.Entry<Resource, RoutesDefinition> entry : groups.entrySet()) {
                     RoutesDefinition def = entry.getValue();
                     Resource resource = entry.getKey();
 
-                    StringBuilder local = new StringBuilder();
-                    doDumpYaml(camelContext, def, resource == dummy ? null : resource, dumper, "routes", local);
-                    sb.append(local);
+                    StringBuilder sbLocal = new StringBuilder();
+                    doDumpYaml(camelContext, def, resource == dummy ? null : resource, dumper, "routes", sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpTiDisk(resource, local, "routes", "yaml");
+                    doDumpTiDisk(resource, sbLocal, "routes", "yaml");
                 }
-                if (!sb.isEmpty() && log) {
+                if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} routes as YAML", size);
-                    LOG.info("{}", sb);
+                    LOG.info("{}", sbLog);
                 }
             }
         }
@@ -164,20 +163,19 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     RestsDefinition rests = groups.computeIfAbsent(res, resource -> new RestsDefinition());
                     rests.getRests().add(rest);
                 }
-                StringBuilder sb = new StringBuilder();
+                StringBuilder sbLog = new StringBuilder();
                 for (Map.Entry<Resource, RestsDefinition> entry : groups.entrySet()) {
                     RestsDefinition def = entry.getValue();
                     Resource resource = entry.getKey();
 
-                    StringBuilder local = new StringBuilder();
-                    doDumpYaml(camelContext, def, resource == dummy ? null : resource, dumper, "rests", local);
-                    sb.append(local);
+                    StringBuilder sbLocal = new StringBuilder();
+                    doDumpYaml(camelContext, def, resource == dummy ? null : resource, dumper, "rests", sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpTiDisk(resource, local, "rests", "yaml");
+                    doDumpTiDisk(resource, sbLocal, "rests", "yaml");
                 }
-                if (!sb.isEmpty() && log) {
+                if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} rests as YAML", size);
-                    LOG.info("{}", sb);
+                    LOG.info("{}", sbLog);
                 }
             }
         }
@@ -195,20 +193,19 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     RouteTemplatesDefinition rests = groups.computeIfAbsent(res, resource -> new RouteTemplatesDefinition());
                     rests.getRouteTemplates().add(rt);
                 }
-                StringBuilder sb = new StringBuilder();
+                StringBuilder sbLog = new StringBuilder();
                 for (Map.Entry<Resource, RouteTemplatesDefinition> entry : groups.entrySet()) {
                     RouteTemplatesDefinition def = entry.getValue();
                     Resource resource = entry.getKey();
 
-                    StringBuilder local = new StringBuilder();
-                    doDumpYaml(camelContext, def, resource == dummy ? null : resource, dumper, "route-templates", local);
-                    sb.append(local);
+                    StringBuilder sbLocal = new StringBuilder();
+                    doDumpYaml(camelContext, def, resource == dummy ? null : resource, dumper, "route-templates", sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpTiDisk(resource, local, "route-templates", "yaml");
+                    doDumpTiDisk(resource, sbLocal, "route-templates", "yaml");
                 }
-                if (!sb.isEmpty() && log) {
+                if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} route-templates as YAML", size);
-                    LOG.info("{}", sb);
+                    LOG.info("{}", sbLog);
                 }
             }
         }
@@ -216,10 +213,11 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
 
     protected void doDumpYaml(
             CamelContext camelContext, NamedNode def, Resource resource,
-            ModelToYAMLDumper dumper, String kind, StringBuilder sb) {
+            ModelToYAMLDumper dumper, String kind, StringBuilder sbLocal, StringBuilder sbLog) {
         try {
             String dump = dumper.dumpModelAsYaml(camelContext, def, true, uriAsParameters);
-            appendDump(resource, dump, sb);
+            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);
         }
@@ -242,20 +240,19 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     RoutesDefinition routes = groups.computeIfAbsent(res, resource -> new RoutesDefinition());
                     routes.getRoutes().add(route);
                 }
-                StringBuilder sb = new StringBuilder();
+                StringBuilder sbLog = new StringBuilder();
                 for (Map.Entry<Resource, RoutesDefinition> entry : groups.entrySet()) {
                     RoutesDefinition def = entry.getValue();
                     Resource resource = entry.getKey();
 
-                    StringBuilder local = new StringBuilder();
-                    doDumpXml(camelContext, def, resource == dummy ? null : resource, dumper, "route", "routes", local);
-                    sb.append(local);
+                    StringBuilder sbLocal = new StringBuilder();
+                    doDumpXml(camelContext, def, resource == dummy ? null : resource, dumper, "route", "routes", sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpTiDisk(resource, local, "routes", "xml");
+                    doDumpTiDisk(resource, sbLocal, "routes", "xml");
                 }
-                if (!sb.isEmpty() && log) {
+                if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} routes as XML", size);
-                    LOG.info("{}", sb);
+                    LOG.info("{}", sbLog);
                 }
             }
         }
@@ -272,20 +269,19 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     RestsDefinition routes = groups.computeIfAbsent(res, resource -> new RestsDefinition());
                     routes.getRests().add(rest);
                 }
-                StringBuilder sb = new StringBuilder();
+                StringBuilder sbLog = new StringBuilder();
                 for (Map.Entry<Resource, RestsDefinition> entry : groups.entrySet()) {
                     RestsDefinition def = entry.getValue();
                     Resource resource = entry.getKey();
 
-                    StringBuilder local = new StringBuilder();
-                    doDumpXml(camelContext, def, resource == dummy ? null : resource, dumper, "rest", "rests", local);
-                    sb.append(local);
+                    StringBuilder sbLocal = new StringBuilder();
+                    doDumpXml(camelContext, def, resource == dummy ? null : resource, dumper, "rest", "rests", sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpTiDisk(resource, local, "rests", "xml");
+                    doDumpTiDisk(resource, sbLocal, "rests", "xml");
                 }
-                if (!sb.isEmpty() && log) {
+                if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} rests as XML", size);
-                    LOG.info("{}", sb);
+                    LOG.info("{}", sbLog);
                 }
             }
         }
@@ -303,21 +299,20 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
                     RouteTemplatesDefinition routes = groups.computeIfAbsent(res, resource -> new RouteTemplatesDefinition());
                     routes.getRouteTemplates().add(rt);
                 }
-                StringBuilder sb = new StringBuilder();
+                StringBuilder sbLog = new StringBuilder();
                 for (Map.Entry<Resource, RouteTemplatesDefinition> entry : groups.entrySet()) {
                     RouteTemplatesDefinition def = entry.getValue();
                     Resource resource = entry.getKey();
 
-                    StringBuilder local = new StringBuilder();
+                    StringBuilder sbLocal = new StringBuilder();
                     doDumpXml(camelContext, def, resource == dummy ? null : resource, dumper, "routeTemplate",
-                            "route-templates", local);
-                    sb.append(local);
+                            "route-templates", sbLocal, sbLog);
                     // dump each resource into its own file
-                    doDumpTiDisk(resource, local, "route-templates", "xml");
+                    doDumpTiDisk(resource, sbLocal, "route-templates", "xml");
                 }
-                if (!sb.isEmpty() && log) {
+                if (!sbLog.isEmpty() && log) {
                     LOG.info("Dumping {} route-templates as XML", size);
-                    LOG.info("{}", sb);
+                    LOG.info("{}", sbLog);
                 }
             }
         }
@@ -325,21 +320,22 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
 
     protected void doDumpXml(
             CamelContext camelContext, NamedNode def, Resource resource,
-            ModelToXMLDumper dumper, String replace, String kind, StringBuilder sb) {
+            ModelToXMLDumper dumper, String replace, String kind, StringBuilder sbLocal, StringBuilder sbLog) {
         try {
             String xml = dumper.dumpModelAsXml(camelContext, def, true);
             // lets separate with empty line
             xml = StringHelper.replaceFirst(xml, "xmlns=\"http://camel.apache.org/schema/spring\">",
                     "xmlns=\"http://camel.apache.org/schema/spring\">\n");
             xml = xml.replace("</" + replace + ">", "</" + replace + ">\n");
-            appendDump(resource, xml, sb);
+            sbLocal.append(xml);
+            appendLogDump(resource, xml, sbLog);
         } catch (Exception e) {
             LOG.warn("Error dumping {}} to XML due to {}. This exception is ignored.", kind, e.getMessage(), e);
         }
     }
 
-    protected void doDumpTiDisk(Resource resource, StringBuilder local, String kind, String ext) {
-        if (directory != null && !local.isEmpty()) {
+    protected void doDumpTiDisk(Resource resource, StringBuilder sbLocal, String kind, String ext) {
+        if (directory != null && !sbLocal.isEmpty()) {
             // make sure directory exists
             File dir = new File(directory);
             dir.mkdirs();
@@ -355,7 +351,7 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
             name = FileUtil.onlyName(name) + "." + ext;
             File target = new File(directory, name);
             try {
-                IOHelper.writeText(local.toString(), target);
+                IOHelper.writeText(sbLocal.toString(), target);
                 LOG.debug("Dumped {} to file: {}", target, name);
             } catch (IOException e) {
                 throw new RuntimeException("Error dumping " + kind + " to file: " + target, e);
@@ -363,15 +359,15 @@ public class DefaultDumpRoutesStrategy extends ServiceSupport implements DumpRou
         }
     }
 
-    protected void appendDump(Resource resource, String dump, StringBuilder sb) {
+    protected void appendLogDump(Resource resource, String dump, StringBuilder sbLog) {
         String loc = null;
         if (resource != null) {
             loc = extractLocationName(resource.getLocation());
         }
         if (loc != null) {
-            sb.append(String.format("\nSource: %s%n%s%n%s%n", loc, DIVIDER, dump));
+            sbLog.append(String.format("\nSource: %s%n%s%n%s%n", loc, DIVIDER, dump));
         } else {
-            sb.append(String.format("%n%n%s%n", dump));
+            sbLog.append(String.format("%n%n%s%n", dump));
         }
     }
 
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 a135eac6123..4f8b3b4931d 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
@@ -73,6 +73,14 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "DevConsoleEnabled": target.setDevConsoleEnabled(property(camelContext, boolean.class, value)); return true;
         case "dumproutes":
         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 "dumproutesinclude":
+        case "DumpRoutesInclude": target.setDumpRoutesInclude(property(camelContext, java.lang.String.class, value)); return true;
+        case "dumprouteslog":
+        case "DumpRoutesLog": target.setDumpRoutesLog(property(camelContext, boolean.class, value)); return true;
+        case "dumproutesuriasparameters":
+        case "DumpRoutesUriAsParameters": target.setDumpRoutesUriAsParameters(property(camelContext, boolean.class, value)); return true;
         case "durationhitexitcode":
         case "DurationHitExitCode": target.setDurationHitExitCode(property(camelContext, int.class, value)); return true;
         case "durationmaxaction":
@@ -320,6 +328,14 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "DevConsoleEnabled": return boolean.class;
         case "dumproutes":
         case "DumpRoutes": return java.lang.String.class;
+        case "dumproutesdirectory":
+        case "DumpRoutesDirectory": return java.lang.String.class;
+        case "dumproutesinclude":
+        case "DumpRoutesInclude": return java.lang.String.class;
+        case "dumprouteslog":
+        case "DumpRoutesLog": return boolean.class;
+        case "dumproutesuriasparameters":
+        case "DumpRoutesUriAsParameters": return boolean.class;
         case "durationhitexitcode":
         case "DurationHitExitCode": return int.class;
         case "durationmaxaction":
@@ -568,6 +584,14 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "DevConsoleEnabled": return target.isDevConsoleEnabled();
         case "dumproutes":
         case "DumpRoutes": return target.getDumpRoutes();
+        case "dumproutesdirectory":
+        case "DumpRoutesDirectory": return target.getDumpRoutesDirectory();
+        case "dumproutesinclude":
+        case "DumpRoutesInclude": return target.getDumpRoutesInclude();
+        case "dumprouteslog":
+        case "DumpRoutesLog": return target.isDumpRoutesLog();
+        case "dumproutesuriasparameters":
+        case "DumpRoutesUriAsParameters": return target.isDumpRoutesUriAsParameters();
         case "durationhitexitcode":
         case "DurationHitExitCode": return target.getDurationHitExitCode();
         case "durationmaxaction":
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 7e4a2e04b05..29c023fde81 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
@@ -39,6 +39,10 @@
     { "name": "camel.main.description", "description": "Sets the description (intended for humans) of the Camel application.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
     { "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: routes, rests, 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.dumpRoutesLog", "description": "Whether to log route dumps to Logger", "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" },
     { "name": "camel.main.durationHitExitCode", "description": "Sets the exit code for the application if duration was hit", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "integer", "javaType": "int" },
     { "name": "camel.main.durationMaxAction", "description": "Controls whether the Camel application should shutdown the JVM, or stop all routes, when duration max is triggered.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "shutdown", "enum": [ "shutdown", "stop" ] },
     { "name": "camel.main.durationMaxIdleSeconds", "description": "To specify for how long time in seconds Camel can be idle before automatic terminating the JVM. You can use this to run Camel for a short while.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int" },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index fff84225c33..da33b6e96c2 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 120 options, which are listed below.
+The camel.main supports 124 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -50,6 +50,10 @@ The camel.main supports 120 options, which are listed below.
 | *camel.main.description* | Sets the description (intended for humans) of the Camel application. |  | String
 | *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: routes, rests, routeTemplates. 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.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
 | *camel.main.durationHitExitCode* | Sets the exit code for the application if duration was hit |  | int
 | *camel.main.durationMaxAction* | Controls whether the Camel application should shutdown the JVM, or stop all routes, when duration max is triggered. | shutdown | String
 | *camel.main.durationMaxIdle{zwsp}Seconds* | To specify for how long time in seconds Camel can be idle before automatic terminating the JVM. You can use this to run Camel for a short while. |  | int
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 28e9254e496..410e5e9272b 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
@@ -48,6 +48,7 @@ import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.CliConnectorFactory;
 import org.apache.camel.spi.ContextReloadStrategy;
 import org.apache.camel.spi.Debugger;
+import org.apache.camel.spi.DumpRoutesStrategy;
 import org.apache.camel.spi.EndpointStrategy;
 import org.apache.camel.spi.EventFactory;
 import org.apache.camel.spi.EventNotifier;
@@ -258,6 +259,13 @@ public final class DefaultConfigurationConfigurer {
             reloader.setRemoveAllRoutes(config.isRoutesReloadRemoveAllRoutes());
             camelContext.addService(reloader);
         }
+        if (config.getDumpRoutes() != null) {
+            DumpRoutesStrategy drs = camelContext.getCamelContextExtension().getContextPlugin(DumpRoutesStrategy.class);
+            drs.setInclude(config.getDumpRoutesInclude());
+            drs.setLog(config.isDumpRoutesLog());
+            drs.setUriAsParameters(config.isDumpRoutesUriAsParameters());
+            drs.setDirectory(config.getDumpRoutesDirectory());
+        }
         if (config.isContextReloadEnabled() && camelContext.hasService(ContextReloadStrategy.class) == null) {
             ContextReloadStrategy reloader = new DefaultContextReloadStrategy();
             camelContext.addService(reloader);
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 ee44283e346..481d960bec3 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
@@ -131,6 +131,10 @@ public abstract class DefaultConfigurationProperties<T> {
     private boolean exchangeFactoryStatisticsEnabled;
     @Metadata(enums = "xml,yaml")
     private String dumpRoutes;
+    private String dumpRoutesInclude = "routes";
+    private boolean dumpRoutesLog = true;
+    private boolean dumpRoutesUriAsParameters;
+    private String dumpRoutesDirectory;
     private Map<String, String> globalOptions;
     // route controller
     private boolean routeControllerSuperviseEnabled;
@@ -1386,6 +1390,54 @@ public abstract class DefaultConfigurationProperties<T> {
         this.dumpRoutes = dumpRoutes;
     }
 
+    public String getDumpRoutesInclude() {
+        return dumpRoutesInclude;
+    }
+
+    /**
+     * Controls what to include in output for route dumping.
+     *
+     * Possible values: routes, rests, routeTemplates. Multiple values can be separated by comma. Default is routes.
+     */
+    public void setDumpRoutesInclude(String dumpRoutesInclude) {
+        this.dumpRoutesInclude = dumpRoutesInclude;
+    }
+
+    public boolean isDumpRoutesLog() {
+        return dumpRoutesLog;
+    }
+
+    /**
+     * Whether to log route dumps to Logger
+     */
+    public void setDumpRoutesLog(boolean dumpRoutesLog) {
+        this.dumpRoutesLog = dumpRoutesLog;
+    }
+
+    public boolean isDumpRoutesUriAsParameters() {
+        return dumpRoutesUriAsParameters;
+    }
+
+    /**
+     * When dumping routes to YAML format, then this option controls whether endpoint URIs should be expanded into a
+     * key/value parameters.
+     */
+    public void setDumpRoutesUriAsParameters(boolean dumpRoutesUriAsParameters) {
+        this.dumpRoutesUriAsParameters = dumpRoutesUriAsParameters;
+    }
+
+    public String getDumpRoutesDirectory() {
+        return 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.
+     */
+    public void setDumpRoutesDirectory(String dumpRoutesDirectory) {
+        this.dumpRoutesDirectory = dumpRoutesDirectory;
+    }
+
     public Map<String, String> getGlobalOptions() {
         return globalOptions;
     }
@@ -2578,6 +2630,42 @@ public abstract class DefaultConfigurationProperties<T> {
         return (T) this;
     }
 
+    /**
+     * Controls what to include in output for route dumping.
+     *
+     * Possible values: routes, rests, routeTemplates. Multiple values can be separated by comma. Default is routes.
+     */
+    public T withDumpRoutesInclude(String dumpRoutesInclude) {
+        this.dumpRoutesInclude = dumpRoutesInclude;
+        return (T) this;
+    }
+
+    /**
+     * Whether to log route dumps to Logger
+     */
+    public T withDumpRoutesLog(boolean dumpRoutesLog) {
+        this.dumpRoutesLog = dumpRoutesLog;
+        return (T) this;
+    }
+
+    /**
+     * When dumping routes to YAML format, then this option controls whether endpoint URIs should be expanded into a
+     * key/value parameters.
+     */
+    public T withDumpRoutesUriAsParameters(boolean dumpRoutesUriAsParameters) {
+        this.dumpRoutesUriAsParameters = dumpRoutesUriAsParameters;
+        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.
+     */
+    public T withDumpRoutesDirectory(String dumpRoutesDirectory) {
+        this.dumpRoutesDirectory = dumpRoutesDirectory;
+        return (T) this;
+    }
+
     /**
      * Sets global options that can be referenced in the camel context
      * <p/>
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedRouteDumpStrategyTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedRouteDumpStrategyTest.java
index 080dcb55c7e..0e398db0c6c 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedRouteDumpStrategyTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedRouteDumpStrategyTest.java
@@ -43,7 +43,14 @@ public class ManagedRouteDumpStrategyTest extends ManagementTestSupport {
         String dir = testDirectory().toString();
 
         CamelContext context = super.createCamelContext();
-        context.setDumpRoutes("xml?include=all&log=false&directory=" + dir); // dump route is lazy
+        context.setDumpRoutes("xml");
+
+        DefaultDumpRoutesStrategy drd = new DefaultDumpRoutesStrategy();
+        drd.setInclude("all");
+        drd.setLog(false);
+        drd.setDirectory(dir);
+        context.addService(drd);
+
         return context;
     }