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

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


The following commit(s) were added to refs/heads/main by this push:
     new 2aacbb7f7607 CAMEL-22604: camel-jbang - Route dump in brief mode
2aacbb7f7607 is described below

commit 2aacbb7f7607d5afaf44ba8f0e70823bf2996c90
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Oct 25 16:23:46 2025 +0200

    CAMEL-22604: camel-jbang - Route dump in brief mode
---
 .../camel/spring/config/SpringRouteNoFromTest.java |  2 +-
 .../processor/SpringTryCatchMisconfiguredTest.java |  4 +-
 .../org/apache/camel/spi/ModelToXMLDumper.java     | 10 +++
 .../org/apache/camel/spi/ModelToYAMLDumper.java    | 10 +++
 .../camel/impl/console/RouteDumpDevConsole.java    | 37 +++++++--
 .../java/org/apache/camel/model/LogDefinition.java |  7 +-
 .../org/apache/camel/model/SendDefinition.java     |  2 +-
 .../java/org/apache/camel/model/ToDefinition.java  |  2 +-
 .../apache/camel/model/ToDynamicDefinition.java    |  2 +-
 .../camel/model/OnFallbackDefinitionTest.java      |  2 +-
 .../model/StartingRoutesErrorReportedTest.java     |  4 +-
 .../ParentChildInterceptStrategyTest.java          |  2 +-
 .../CustomInterceptorRouteWithChildOutputTest.java |  4 +-
 .../interceptor/DebugSingleStepConditionTest.java  |  4 +-
 .../processor/interceptor/DebugSingleStepTest.java | 12 +--
 .../camel/processor/interceptor/DebugTest.java     |  6 +-
 .../management/mbean/ManagedCamelContextMBean.java |  9 +++
 .../management/mbean/ManagedProcessorMBean.java    |  3 +
 .../api/management/mbean/ManagedRouteMBean.java    |  9 +++
 .../management/mbean/ManagedCamelContext.java      | 49 ++++++++++++
 .../camel/management/mbean/ManagedProcessor.java   |  5 ++
 .../camel/management/mbean/ManagedRoute.java       | 69 +++++++++++++++++
 ...edCamelContextDumpRouteStructureAsTextTest.java | 86 +++++++++++++++++++++
 ...gedCamelContextDumpRouteStructureAsXmlTest.java | 89 ++++++++++++++++++++++
 ...edCamelContextDumpRouteStructureAsYamlTest.java | 74 ++++++++++++++++++
 .../org/apache/camel/xml/LwModelToXMLDumper.java   | 48 ++++++++++++
 .../camel/xml/jaxb/JaxbModelToXMLDumper.java       |  5 ++
 .../org/apache/camel/yaml/LwModelToYAMLDumper.java | 55 +++++++++++++
 .../camel/cli/connector/LocalCliConnector.java     |  3 +-
 .../core/commands/action/CamelRouteDumpAction.java | 26 ++++++-
 30 files changed, 606 insertions(+), 34 deletions(-)

diff --git 
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/config/SpringRouteNoFromTest.java
 
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/config/SpringRouteNoFromTest.java
index 71dd50b0b700..d5a6b0c911c6 100644
--- 
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/config/SpringRouteNoFromTest.java
+++ 
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/config/SpringRouteNoFromTest.java
@@ -47,7 +47,7 @@ public class SpringRouteNoFromTest extends SpringTestSupport {
             fail("Should have thrown exception");
         } catch (RuntimeCamelException e) {
             IllegalArgumentException iae = (IllegalArgumentException) 
e.getCause();
-            assertEquals("Route myRoute has no inputs: Route(myRoute)[ -> 
[To[mock:result]]]", iae.getMessage());
+            assertEquals("Route myRoute has no inputs: Route(myRoute)[ -> 
[to[mock:result]]]", iae.getMessage());
             return null;
         }
 
diff --git 
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringTryCatchMisconfiguredTest.java
 
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringTryCatchMisconfiguredTest.java
index b51e98e09a1f..17e47e304f00 100644
--- 
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringTryCatchMisconfiguredTest.java
+++ 
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringTryCatchMisconfiguredTest.java
@@ -36,7 +36,7 @@ public class SpringTryCatchMisconfiguredTest extends 
ContextTestSupport {
             FailedToCreateRouteException ftce = 
assertIsInstanceOf(FailedToCreateRouteException.class, e);
             IllegalArgumentException iae = 
assertIsInstanceOf(IllegalArgumentException.class, ftce.getCause());
             assertEquals(
-                    "This doCatch should have a doTry as its parent on 
DoCatch[ [class java.io.IOException] -> [To[mock:fail]]]",
+                    "This doCatch should have a doTry as its parent on 
DoCatch[ [class java.io.IOException] -> [to[mock:fail]]]",
                     iae.getMessage());
         }
 
@@ -46,7 +46,7 @@ public class SpringTryCatchMisconfiguredTest extends 
ContextTestSupport {
         } catch (Exception e) {
             FailedToCreateRouteException ftcre = 
assertIsInstanceOf(FailedToCreateRouteException.class, e);
             IllegalArgumentException iae = 
assertIsInstanceOf(IllegalArgumentException.class, ftcre.getCause());
-            assertEquals("This doFinally should have a doTry as its parent on 
DoFinally[[To[mock:finally]]]", iae.getMessage());
+            assertEquals("This doFinally should have a doTry as its parent on 
DoFinally[[to[mock:finally]]]", iae.getMessage());
         }
 
         // return a working context instead, to let this test pass
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 c9a210b33e6e..c526c5e26266 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
@@ -76,4 +76,14 @@ public interface ModelToXMLDumper {
      */
     String dumpDataFormatsAsXml(CamelContext context, Map<String, Object> 
dataFormats) throws Exception;
 
+    /**
+     * Dumps the definition (structure only) as XML
+     *
+     * @param  context    the CamelContext
+     * @param  definition the definition, such as a {@link NamedNode}
+     * @return            the output in XML (is formatted)
+     * @throws Exception  is throw if error marshalling to XML
+     */
+    String dumpStructureModelAsXml(CamelContext context, NamedNode definition) 
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 ab8b5b67f064..ac26a9dfb79b 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
@@ -78,4 +78,14 @@ public interface ModelToYAMLDumper {
      */
     String dumpDataFormatsAsYaml(CamelContext context, Map<String, Object> 
dataFormats) throws Exception;
 
+    /**
+     * Dumps the definition (structure only) as YAML
+     *
+     * @param  context    the CamelContext
+     * @param  definition the definition, such as a {@link NamedNode}
+     * @return            the output in YAML (is formatted)
+     * @throws Exception  is throw if error marshalling to YAML
+     */
+    String dumpStructureModelAsYaml(CamelContext context, NamedNode 
definition) throws Exception;
+
 }
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
index aacea236c85d..01d9df8b0342 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
@@ -38,7 +38,7 @@ import org.apache.camel.util.json.JsonObject;
 public class RouteDumpDevConsole extends AbstractDevConsole {
 
     /**
-     * To use either xml or yaml output format
+     * To output in either xml, yaml, or text format
      */
     public static final String FORMAT = "format";
 
@@ -57,6 +57,11 @@ public class RouteDumpDevConsole extends AbstractDevConsole {
      */
     public static final String URI_AS_PARAMETERS = "uriAsParameters";
 
+    /**
+     * Whether to dump in brief mode (only overall structure, and no detailed 
options or expressions)
+     */
+    public static final String BRIEF = "brief";
+
     public RouteDumpDevConsole() {
         super("camel", "route-dump", "Route Dump", "Dump route in XML or YAML 
format");
     }
@@ -64,6 +69,7 @@ public class RouteDumpDevConsole extends AbstractDevConsole {
     @Override
     protected String doCallText(Map<String, Object> options) {
         final String uriAsParameters = (String) 
options.getOrDefault(URI_AS_PARAMETERS, "false");
+        final String brief = (String) options.getOrDefault(BRIEF, "false");
 
         final StringBuilder sb = new StringBuilder();
         Function<ManagedRouteMBean, Object> task = mrb -> {
@@ -71,9 +77,19 @@ public class RouteDumpDevConsole extends AbstractDevConsole {
             try {
                 String format = (String) options.get(FORMAT);
                 if (format == null || "xml".equals(format)) {
-                    dump = mrb.dumpRouteAsXml();
+                    if ("true".equals(brief)) {
+                        dump = mrb.dumpStructureRouteAsXml();
+                    } else {
+                        dump = mrb.dumpRouteAsXml(true);
+                    }
                 } else if ("yaml".equals(format)) {
-                    dump = mrb.dumpRouteAsYaml(true, 
"true".equals(uriAsParameters));
+                    if ("true".equals(brief)) {
+                        dump = mrb.dumpStructureRouteAsYaml();
+                    } else {
+                        dump = mrb.dumpRouteAsYaml(true, 
"true".equals(uriAsParameters));
+                    }
+                } else if ("text".equals(format)) {
+                    dump = mrb.dumpStructureRouteAsText("true".equals(brief));
                 }
             } catch (Exception e) {
                 // ignore
@@ -100,6 +116,7 @@ public class RouteDumpDevConsole extends AbstractDevConsole 
{
     @Override
     protected JsonObject doCallJson(Map<String, Object> options) {
         final String uriAsParameters = (String) 
options.getOrDefault(URI_AS_PARAMETERS, "false");
+        final String brief = (String) options.getOrDefault(BRIEF, "false");
 
         final JsonObject root = new JsonObject();
         final List<JsonObject> list = new ArrayList<>();
@@ -119,10 +136,20 @@ public class RouteDumpDevConsole extends 
AbstractDevConsole {
                 String format = (String) options.get(FORMAT);
                 if (format == null || "xml".equals(format)) {
                     jo.put("format", "xml");
-                    dump = mrb.dumpRouteAsXml();
+                    if ("true".equals(brief)) {
+                        dump = mrb.dumpStructureRouteAsXml();
+                    } else {
+                        dump = mrb.dumpRouteAsXml(true);
+                    }
                 } else if ("yaml".equals(format)) {
                     jo.put("format", "yaml");
-                    dump = mrb.dumpRouteAsYaml(true, 
"true".equals(uriAsParameters));
+                    if ("true".equals(brief)) {
+                        dump = mrb.dumpStructureRouteAsYaml();
+                    } else {
+                        dump = mrb.dumpRouteAsYaml(true, 
"true".equals(uriAsParameters));
+                    }
+                } else if ("text".equals(format)) {
+                    dump = mrb.dumpStructureRouteAsText("true".equals(brief));
                 }
                 if (dump != null) {
                     List<JsonObject> code = ConsoleHelper.loadSourceAsJson(new 
StringReader(dump), null);
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/LogDefinition.java 
b/core/camel-core-model/src/main/java/org/apache/camel/model/LogDefinition.java
index 30e5f58764da..0dc1a316469d 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/LogDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/LogDefinition.java
@@ -88,7 +88,12 @@ public class LogDefinition extends 
NoOutputDefinition<LogDefinition> {
 
     @Override
     public String getLabel() {
-        return "log";
+        String m = message;
+        if (m != null) {
+            // log messages may have new lines so replace them with a space as 
we want the label to be in a single line
+            m = m.replace('\n', ' ');
+        }
+        return "log[" + m + "]";
     }
 
     public Logger getLoggerBean() {
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/SendDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/SendDefinition.java
index 3149092147f5..10a868b7526b 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/SendDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/SendDefinition.java
@@ -129,7 +129,7 @@ public abstract class SendDefinition<Type extends 
ProcessorDefinition<Type>> ext
         }
 
         String uri = endpointUriToString;
-        return uri != null ? uri : "no uri supplied";
+        return "to[" + uri + "]";
     }
 
     protected void clear() {
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/ToDefinition.java 
b/core/camel-core-model/src/main/java/org/apache/camel/model/ToDefinition.java
index 79b16af106ec..2b8f59fa65a6 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/ToDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/ToDefinition.java
@@ -89,7 +89,7 @@ public class ToDefinition extends 
SendDefinition<ToDefinition> {
 
     @Override
     public String toString() {
-        return "To[" + getLabel() + "]";
+        return getLabel();
     }
 
     @Override
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java
index af9a90a37242..1e728a6a5ae1 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java
@@ -94,7 +94,7 @@ public class ToDynamicDefinition extends 
NoOutputDefinition<ToDynamicDefinition>
 
     @Override
     public String getLabel() {
-        return uri;
+        return "toD[" + uri + "]";
     }
 
     // Fluent API
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/model/OnFallbackDefinitionTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/model/OnFallbackDefinitionTest.java
index 2997ab03fef3..60fcd2d4f9b9 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/model/OnFallbackDefinitionTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/model/OnFallbackDefinitionTest.java
@@ -27,6 +27,6 @@ public class OnFallbackDefinitionTest {
         OnFallbackDefinition ofd = new OnFallbackDefinition();
         ofd.addOutput(new ToDefinition("urn:foo1"));
         ofd.addOutput(new ToDefinition("urn:foo2"));
-        assertEquals("onFallback[urn:foo1,urn:foo2]", ofd.getLabel());
+        assertEquals("onFallback[to[urn:foo1],to[urn:foo2]]", ofd.getLabel());
     }
 }
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/model/StartingRoutesErrorReportedTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/model/StartingRoutesErrorReportedTest.java
index f68a24d01fb3..19b75f3021fe 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/model/StartingRoutesErrorReportedTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/model/StartingRoutesErrorReportedTest.java
@@ -56,7 +56,7 @@ public class StartingRoutesErrorReportedTest extends 
ContextTestSupport {
         });
 
         assertTrue(
-                e.getMessage().startsWith("Failed to create route: route2 at: 
>>> To[direct:result?foo=bar] <<< in route:"));
+                e.getMessage().startsWith("Failed to create route: route2 at: 
>>> to[direct:result?foo=bar] <<< in route:"));
     }
 
     @Test
@@ -72,7 +72,7 @@ public class StartingRoutesErrorReportedTest extends 
ContextTestSupport {
         });
 
         assertTrue(
-                e.getMessage().startsWith("Failed to create route: route2 at: 
>>> To[direct:result?foo=bar] <<< in route:"));
+                e.getMessage().startsWith("Failed to create route: route2 at: 
>>> to[direct:result?foo=bar] <<< in route:"));
     }
 
     @Test
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/intercept/ParentChildInterceptStrategyTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/intercept/ParentChildInterceptStrategyTest.java
index d5878308a674..202d62b9c07e 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/intercept/ParentChildInterceptStrategyTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/intercept/ParentChildInterceptStrategyTest.java
@@ -58,7 +58,7 @@ public class ParentChildInterceptStrategyTest extends 
ContextTestSupport {
         assertEquals("Parent choice -> target task-e", LIST.get(4));
         assertEquals("Parent route -> target choice", LIST.get(5));
         // the last one has no custom id so its using its label instead
-        assertEquals("Parent route -> target mock:done", LIST.get(6));
+        assertEquals("Parent route -> target to[mock:done]", LIST.get(6));
     }
 
     @Override
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/CustomInterceptorRouteWithChildOutputTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/CustomInterceptorRouteWithChildOutputTest.java
index 21321ed830ee..505170c75c29 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/CustomInterceptorRouteWithChildOutputTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/CustomInterceptorRouteWithChildOutputTest.java
@@ -52,10 +52,10 @@ public class CustomInterceptorRouteWithChildOutputTest 
extends ContextTestSuppor
         assertEquals(4, myInterceptor.getDefs().size());
         assertIsInstanceOf(LogDefinition.class, 
myInterceptor.getDefs().get(0));
         assertIsInstanceOf(ToDefinition.class, myInterceptor.getDefs().get(1));
-        assertEquals("mock:child", myInterceptor.getDefs().get(1).getLabel());
+        assertEquals("to[mock:child]", 
myInterceptor.getDefs().get(1).getLabel());
         assertIsInstanceOf(SplitDefinition.class, 
myInterceptor.getDefs().get(2));
         assertIsInstanceOf(ToDefinition.class, myInterceptor.getDefs().get(3));
-        assertEquals("mock:result", myInterceptor.getDefs().get(3).getLabel());
+        assertEquals("to[mock:result]", 
myInterceptor.getDefs().get(3).getLabel());
     }
 
     @Override
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugSingleStepConditionTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugSingleStepConditionTest.java
index 8b507af7deab..b022ef679604 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugSingleStepConditionTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugSingleStepConditionTest.java
@@ -71,8 +71,8 @@ public class DebugSingleStepConditionTest extends 
ContextTestSupport {
         assertMockEndpointsSatisfied();
 
         assertEquals(2, logs.size());
-        assertEquals("Single stepping at log:beer with body: Carlsberg", 
logs.get(0));
-        assertEquals("Single stepping at mock:result with body: Carlsberg", 
logs.get(1));
+        assertEquals("Single stepping at to[log:beer] with body: Carlsberg", 
logs.get(0));
+        assertEquals("Single stepping at to[mock:result] with body: 
Carlsberg", logs.get(1));
     }
 
     @Override
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugSingleStepTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugSingleStepTest.java
index 00677f841e02..56b654077450 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugSingleStepTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugSingleStepTest.java
@@ -62,12 +62,12 @@ public class DebugSingleStepTest extends ContextTestSupport 
{
         assertMockEndpointsSatisfied();
 
         assertEquals(6, logs.size());
-        assertEquals("Single stepping at log:foo with body: Hello World", 
logs.get(0));
-        assertEquals("Single stepping at log:bar with body: Hello World", 
logs.get(1));
-        assertEquals("Single stepping at mock:result with body: Hello World", 
logs.get(2));
-        assertEquals("Single stepping at log:foo with body: Hello Camel", 
logs.get(3));
-        assertEquals("Single stepping at log:bar with body: Hello Camel", 
logs.get(4));
-        assertEquals("Single stepping at mock:result with body: Hello Camel", 
logs.get(5));
+        assertEquals("Single stepping at to[log:foo] with body: Hello World", 
logs.get(0));
+        assertEquals("Single stepping at to[log:bar] with body: Hello World", 
logs.get(1));
+        assertEquals("Single stepping at to[mock:result] with body: Hello 
World", logs.get(2));
+        assertEquals("Single stepping at to[log:foo] with body: Hello Camel", 
logs.get(3));
+        assertEquals("Single stepping at to[log:bar] with body: Hello Camel", 
logs.get(4));
+        assertEquals("Single stepping at to[mock:result] with body: Hello 
Camel", logs.get(5));
     }
 
     @Override
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugTest.java
index 208127a5997f..7225b8bb18cc 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/DebugTest.java
@@ -97,8 +97,8 @@ public class DebugTest extends ContextTestSupport {
         assertMockEndpointsSatisfied();
 
         assertEquals(2, logs.size());
-        assertEquals("Breakpoint at To[log:foo] with body: Hello Camel", 
logs.get(0));
-        assertEquals("Breakpoint at To[mock:result] with body: Hello Camel", 
logs.get(1));
+        assertEquals("Breakpoint at to[log:foo] with body: Hello Camel", 
logs.get(0));
+        assertEquals("Breakpoint at to[mock:result] with body: Hello Camel", 
logs.get(1));
     }
 
     @Test
@@ -147,7 +147,7 @@ public class DebugTest extends ContextTestSupport {
         assertMockEndpointsSatisfied();
 
         assertEquals(1, logs.size());
-        assertEquals("Breakpoint at To[mock:result] with body: Hello Camel", 
logs.get(0));
+        assertEquals("Breakpoint at to[mock:result] with body: Hello Camel", 
logs.get(0));
     }
 
     @Test
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 c23394bbd767..734b5151e493 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
@@ -237,6 +237,15 @@ public interface ManagedCamelContextMBean extends 
ManagedPerformanceCounterMBean
     @ManagedOperation(description = "Dumps the route templates as XML")
     String dumpRouteTemplatesAsXml() throws Exception;
 
+    @ManagedOperation(description = "Dumps the structure of routes as YAML")
+    String dumpStructureRoutesAsYaml() throws Exception;
+
+    @ManagedOperation(description = "Dumps the structure of routes as XML")
+    String dumpStructureRoutesAsXml() throws Exception;
+
+    @ManagedOperation(description = "Dumps the structure of routes as text")
+    String dumpStructureRoutesAsText(boolean brief) throws Exception;
+
     @ManagedOperation(description = "Dumps the routes as YAML")
     String dumpRoutesAsYaml() throws Exception;
 
diff --git 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedProcessorMBean.java
 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedProcessorMBean.java
index b7deeb098331..e60a4dc99718 100644
--- 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedProcessorMBean.java
+++ 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedProcessorMBean.java
@@ -48,6 +48,9 @@ public interface ManagedProcessorMBean extends 
ManagedPerformanceCounterMBean {
     @ManagedAttribute(description = "Processor Description")
     String getDescription();
 
+    @ManagedAttribute(description = "Processor Model Label")
+    String getModelLabel();
+
     @ManagedAttribute(description = "Processor Note")
     String getNote();
 
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 32f0b6470a84..e1b97738e10e 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
@@ -163,6 +163,15 @@ public interface ManagedRouteMBean extends 
ManagedPerformanceCounterMBean {
     @ManagedOperation(description = "Dumps the route with mappings between 
node ids and their source location/line-number (currently only XML and YAML 
routes supported) as XML")
     String dumpRouteSourceLocationsAsXml() throws Exception;
 
+    @ManagedOperation(description = "Dumps the structure of the route as XML")
+    String dumpStructureRouteAsXml() throws Exception;
+
+    @ManagedOperation(description = "Dumps the structure of the route as YAML")
+    String dumpStructureRouteAsYaml() throws Exception;
+
+    @ManagedOperation(description = "Dumps the structure of the route as text")
+    String dumpStructureRouteAsText(boolean brief) throws Exception;
+
     @ManagedOperation(description = "Reset counters")
     void reset(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 3ba1d21bdf8e..b6d599785962 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
@@ -585,6 +585,55 @@ public class ManagedCamelContext extends 
ManagedPerformanceCounter implements Ti
         return 
PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, 
resolvePlaceholders, generatedIds);
     }
 
+    @Override
+    public String dumpStructureRoutesAsYaml() throws Exception {
+        List<RouteDefinition> routes = 
context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinitions();
+        if (routes.isEmpty()) {
+            return null;
+        }
+
+        // use routes definition to dump the routes
+        RoutesDefinition def = new RoutesDefinition();
+        def.setRoutes(routes);
+
+        return 
PluginHelper.getModelToYAMLDumper(context).dumpStructureModelAsYaml(context, 
def);
+    }
+
+    @Override
+    public String dumpStructureRoutesAsXml() throws Exception {
+        List<RouteDefinition> routes = 
context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinitions();
+        if (routes.isEmpty()) {
+            return null;
+        }
+
+        // use routes definition to dump the routes
+        RoutesDefinition def = new RoutesDefinition();
+        def.setRoutes(routes);
+
+        return 
PluginHelper.getModelToXMLDumper(context).dumpStructureModelAsXml(context, def);
+    }
+
+    @Override
+    public String dumpStructureRoutesAsText(boolean brief) throws Exception {
+        StringBuilder sb = new StringBuilder();
+        MBeanServer server = 
getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
+        if (server != null) {
+            // gather all the routes for this CamelContext, which requires JMX
+            String prefix = 
getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() 
? "*/" : "";
+            ObjectName query = ObjectName
+                    .getInstance(jmxDomain + ":context=" + prefix + 
getContext().getManagementName() + ",type=routes,*");
+            Set<ObjectName> routes = server.queryNames(query, null);
+            for (ObjectName on : routes) {
+                ManagedRouteMBean route
+                        = 
context.getManagementStrategy().getManagementAgent().newProxyClient(on, 
ManagedRouteMBean.class);
+                String dump = route.dumpStructureRouteAsText(brief);
+                sb.append(dump);
+                sb.append("\n");
+            }
+        }
+        return sb.toString();
+    }
+
     @Override
     public String dumpRoutesAsYaml() throws Exception {
         return dumpRoutesAsYaml(false, false);
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java
index b96adf2e4dec..d0da58e84190 100644
--- 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java
+++ 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java
@@ -205,6 +205,11 @@ public class ManagedProcessor extends 
ManagedPerformanceCounter
         return definition.getDescription();
     }
 
+    @Override
+    public String getModelLabel() {
+        return definition.getLabel();
+    }
+
     @Override
     public String getNote() {
         return definition.getNote();
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 eecd4a03a659..37b177277ef6 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
@@ -64,6 +64,7 @@ import org.apache.camel.spi.ManagementStrategy;
 import org.apache.camel.spi.RoutePolicy;
 import org.apache.camel.support.PluginHelper;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.json.JsonArray;
 import org.apache.camel.util.json.JsonObject;
 import org.apache.camel.xml.LwModelHelper;
@@ -459,6 +460,74 @@ public class ManagedRoute extends 
ManagedPerformanceCounter implements TimerList
         return null;
     }
 
+    @Override
+    public String dumpStructureRouteAsXml() throws Exception {
+        String id = route.getId();
+        RouteDefinition def = 
context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinition(id);
+        if (def != null) {
+            return 
PluginHelper.getModelToXMLDumper(context).dumpStructureModelAsXml(context, def);
+        }
+
+        return null;
+    }
+
+    @Override
+    public String dumpStructureRouteAsYaml() throws Exception {
+        String id = route.getId();
+        RouteDefinition def = 
context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinition(id);
+        if (def != null) {
+            return 
PluginHelper.getModelToYAMLDumper(context).dumpStructureModelAsYaml(context, 
def);
+        }
+
+        return null;
+    }
+
+    @Override
+    public String dumpStructureRouteAsText(boolean brief) throws Exception {
+        StringBuilder sb = new StringBuilder();
+        sb.append("route[").append(route.getRouteId()).append("]\n");
+        if (brief) {
+            sb.append("  
from[").append(route.getEndpoint().getEndpointBaseUri()).append("]\n");
+        } else {
+            sb.append("  from[").append(route.getEndpoint()).append("]\n");
+        }
+
+        MBeanServer server = 
getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
+        if (server != null) {
+            // get all the processor mbeans and sort them accordingly to their 
index
+            String prefix = 
getContext().getManagementStrategy().getManagementAgent().getIncludeHostName() 
? "*/" : "";
+            ObjectName query = ObjectName.getInstance(
+                    jmxDomain + ":context=" + prefix + 
getContext().getManagementName() + ",type=processors,*");
+            Set<ObjectName> names = server.queryNames(query, null);
+            List<ManagedProcessorMBean> mps = new ArrayList<>();
+            for (ObjectName on : names) {
+                ManagedProcessorMBean processor = 
context.getManagementStrategy().getManagementAgent().newProxyClient(on,
+                        ManagedProcessorMBean.class);
+                // the processor must belong to this route
+                if (getRouteId().equals(processor.getRouteId())) {
+                    mps.add(processor);
+                }
+            }
+            // sort by index
+            mps.sort(new OrderProcessorMBeans());
+
+            // dump in text format padded by level
+            for (ManagedProcessorMBean processor : mps) {
+                int index = processor.getLevel() + 1;
+                String pad = StringHelper.padString(index);
+                sb.append(pad);
+                if (brief) {
+                    sb.append(processor.getProcessorName());
+                } else {
+                    sb.append(processor.getModelLabel());
+                }
+                sb.append("\n");
+            }
+        }
+
+        return sb.toString();
+    }
+
     @Override
     public String dumpRouteAsYaml() throws Exception {
         return dumpRouteAsYaml(false, false);
diff --git 
a/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRouteStructureAsTextTest.java
 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRouteStructureAsTextTest.java
new file mode 100644
index 000000000000..a6ccb0502629
--- /dev/null
+++ 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRouteStructureAsTextTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.management;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisabledOnOs(OS.AIX)
+public class ManagedCamelContextDumpRouteStructureAsTextTest extends 
ManagementTestSupport {
+
+    @Test
+    public void testDumpAsText() throws Exception {
+        MBeanServer mbeanServer = getMBeanServer();
+
+        ObjectName on = getContextObjectName();
+
+        String text = (String) mbeanServer.invoke(on, 
"dumpStructureRoutesAsText", new Object[] { false },
+                new String[] { "boolean" });
+        assertNotNull(text);
+        log.info(text);
+
+        assertTrue(text.contains("route[myRoute]"));
+        assertTrue(text.contains("to[mock:result]"));
+        assertTrue(text.contains("filter[header{bar}]"));
+    }
+
+    @Test
+    public void testDumpAsTextBrief() throws Exception {
+        MBeanServer mbeanServer = getMBeanServer();
+
+        ObjectName on = getContextObjectName();
+
+        String text = (String) mbeanServer.invoke(on, 
"dumpStructureRoutesAsText", new Object[] { true },
+                new String[] { "boolean" });
+        assertNotNull(text);
+        log.info(text);
+
+        assertTrue(text.contains("route[myRoute]"));
+        assertFalse(text.contains("to[mock:result]"));
+        assertTrue(text.contains("to"));
+        assertFalse(text.contains("filter[header{bar}]"));
+        assertTrue(text.contains("filter"));
+    }
+
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                context.setDebugging(true);
+
+                from("direct:start").routeId("myRoute")
+                        .log("Got ${body}")
+                        .to("mock:result");
+
+                
from("seda:bar?size=1234&multipleConsumers=true").routeId("myOtherRoute")
+                        .filter().header("bar")
+                        .to("mock:bar")
+                        .end();
+            }
+        };
+    }
+
+}
diff --git 
a/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRouteStructureAsXmlTest.java
 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRouteStructureAsXmlTest.java
new file mode 100644
index 000000000000..7d56a419b9d4
--- /dev/null
+++ 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRouteStructureAsXmlTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.management;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.xml.jaxb.JaxbModelToXMLDumper;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisabledOnOs(OS.AIX)
+public class ManagedCamelContextDumpRouteStructureAsXmlTest extends 
ManagementTestSupport {
+
+    @Test
+    public void testDumpAsXml() throws Exception {
+        MBeanServer mbeanServer = getMBeanServer();
+
+        ObjectName on = getContextObjectName();
+
+        String xml = (String) mbeanServer.invoke(on, 
"dumpStructureRoutesAsXml", null, null);
+        assertNotNull(xml);
+        log.info(xml);
+
+        assertTrue(xml.contains("route"));
+        assertTrue(xml.contains("myRoute"));
+        assertTrue(xml.contains("myOtherRoute"));
+        assertTrue(xml.contains("direct:start"));
+        assertTrue(xml.contains("mock:result"));
+        
assertTrue(xml.contains("seda:bar?size=1234&amp;multipleConsumers=true"));
+        assertTrue(xml.contains("mock:bar"));
+        assertTrue(xml.contains("message"));
+        assertTrue(xml.contains("sourceLineNumber"));
+        assertTrue(xml.contains("sourceLocation"));
+        assertFalse(xml.contains("<header>"));
+    }
+
+    @Test
+    public void testDumpAsXmlUsingJaxb() {
+        JaxbModelToXMLDumper dumper = new JaxbModelToXMLDumper();
+        RoutesDefinition def = new RoutesDefinition();
+        def.setRoutes(context.getRouteDefinitions());
+        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
+            dumper.dumpStructureModelAsXml(context, def);
+        });
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                context.setDebugging(true);
+
+                from("direct:start").routeId("myRoute")
+                        .log("Got ${body}")
+                        .to("mock:result");
+
+                
from("seda:bar?size=1234&multipleConsumers=true").routeId("myOtherRoute")
+                        .filter().header("bar")
+                        .to("mock:bar")
+                        .end();
+            }
+        };
+    }
+
+}
diff --git 
a/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRouteStructureAsYamlTest.java
 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRouteStructureAsYamlTest.java
new file mode 100644
index 000000000000..c21a79a9b8f9
--- /dev/null
+++ 
b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextDumpRouteStructureAsYamlTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.management;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisabledOnOs(OS.AIX)
+public class ManagedCamelContextDumpRouteStructureAsYamlTest extends 
ManagementTestSupport {
+
+    @Test
+    public void testDumpAsYaml() throws Exception {
+        MBeanServer mbeanServer = getMBeanServer();
+
+        ObjectName on = getContextObjectName();
+
+        String yaml = (String) mbeanServer.invoke(on, 
"dumpStructureRoutesAsYaml", null, null);
+        assertNotNull(yaml);
+        log.info(yaml);
+
+        assertTrue(yaml.contains("route"));
+        assertTrue(yaml.contains("myRoute"));
+        assertTrue(yaml.contains("myOtherRoute"));
+        assertTrue(yaml.contains("direct:start"));
+        assertTrue(yaml.contains("mock:result"));
+        assertTrue(yaml.contains("seda:bar?size=1234&multipleConsumers=true"));
+        assertTrue(yaml.contains("mock:bar"));
+        assertTrue(yaml.contains("message"));
+        assertTrue(yaml.contains("sourceLineNumber"));
+        assertTrue(yaml.contains("sourceLocation"));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                context.setDebugging(true);
+
+                from("direct:start").routeId("myRoute")
+                        .log("Got ${body}")
+                        .to("mock:result");
+
+                
from("seda:bar?size=1234&multipleConsumers=true").routeId("myOtherRoute")
+                        .filter().header("bar")
+                        .to("mock:bar")
+                        .end();
+            }
+        };
+    }
+
+}
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 fcda4f7985e0..a66d776a16eb 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
@@ -472,4 +472,52 @@ public class LwModelToXMLDumper implements 
ModelToXMLDumper {
         }
     }
 
+    @Override
+    public String dumpStructureModelAsXml(CamelContext context, NamedNode 
definition) throws Exception {
+        StringWriter buffer = new StringWriter();
+        ModelWriter writer = new ModelWriter(buffer, 
BaseWriter.DEFAULT_NAMESPACE) {
+            @Override
+            protected void 
doWriteOptionalIdentifiedDefinitionAttributes(OptionalIdentifiedDefinition<?> 
def)
+                    throws IOException {
+
+                if (Boolean.TRUE.equals(def.getCustomId())) {
+                    // write custom id
+                    doWriteAttribute("id", def.getId());
+                }
+                // write location information
+                if (context.isDebugging()) {
+                    String loc = (def instanceof RouteDefinition ? 
((RouteDefinition) def).getInput() : def).getLocation();
+                    int line = (def instanceof RouteDefinition ? 
((RouteDefinition) def).getInput() : def).getLineNumber();
+                    if (line != -1) {
+                        writer.addAttribute("sourceLineNumber", 
Integer.toString(line));
+                        writer.addAttribute("sourceLocation", loc);
+                    }
+                }
+            }
+
+            protected void doWriteExpressionNodeElements(ExpressionNode def) 
throws IOException {
+                // do not include expressions in brief mode
+            }
+
+            @Override
+            protected void doWriteValue(String value) throws IOException {
+                if (value != null && !value.isEmpty()) {
+                    super.doWriteValue(value);
+                }
+            }
+
+            @Override
+            protected void attribute(String name, Object value) throws 
IOException {
+                // limit what we want to see in brief mode
+                if ("id".equals(name) || "uri".equals(name) || 
"message".equals(name)) {
+                    super.attribute(name, value);
+                }
+            }
+        };
+
+        
writer.writeOptionalIdentifiedDefinitionRef((OptionalIdentifiedDefinition) 
definition);
+
+        return buffer.toString();
+    }
+
 }
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 f7c64e45eb47..cadc02810729 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
@@ -442,4 +442,9 @@ public class JaxbModelToXMLDumper implements 
ModelToXMLDumper {
         }
     }
 
+    @Override
+    public String dumpStructureModelAsXml(CamelContext context, NamedNode 
definition) throws Exception {
+        throw new UnsupportedOperationException(
+                "dumpStructureModelAsXml is not supported by camel-xml-jaxb. 
Use camel-xml-io instead.");
+    }
 }
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 f5a24b09900b..b9b4f172912b 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
@@ -448,4 +448,59 @@ public class LwModelToYAMLDumper implements 
ModelToYAMLDumper {
         }
     }
 
+    @Override
+    public String dumpStructureModelAsYaml(CamelContext context, NamedNode 
definition) throws Exception {
+        StringWriter buffer = new StringWriter();
+        ModelWriter writer = new ModelWriter(buffer) {
+            @Override
+            protected void 
doWriteOptionalIdentifiedDefinitionAttributes(OptionalIdentifiedDefinition<?> 
def)
+                    throws IOException {
+
+                if (Boolean.TRUE.equals(def.getCustomId())) {
+                    // write custom id
+                    doWriteAttribute("id", def.getId());
+                }
+                // write location information
+                if (context.isDebugging()) {
+                    String loc = (def instanceof RouteDefinition ? 
((RouteDefinition) def).getInput() : def).getLocation();
+                    int line = (def instanceof RouteDefinition ? 
((RouteDefinition) def).getInput() : def).getLineNumber();
+                    if (line != -1) {
+                        writer.addAttribute("sourceLineNumber", 
Integer.toString(line));
+                        writer.addAttribute("sourceLocation", loc);
+                    }
+                }
+            }
+
+            protected void doWriteExpressionNodeElements(ExpressionNode def) 
throws IOException {
+                // do not include expressions in brief mode
+            }
+
+            @Override
+            protected void doWriteValue(String value) throws IOException {
+                if (value != null && !value.isEmpty()) {
+                    super.doWriteValue(value);
+                }
+            }
+
+            @Override
+            protected void attribute(String name, Object value) throws 
IOException {
+                // limit what we want to see in brief mode
+                if ("id".equals(name) || "uri".equals(name) || 
"message".equals(name)) {
+                    super.attribute(name, value);
+                }
+            }
+        };
+
+        writer.setUriAsParameters(false);
+        writer.setCamelContext(context);
+        writer.start();
+        try {
+            
writer.writeOptionalIdentifiedDefinitionRef((OptionalIdentifiedDefinition) 
definition);
+        } finally {
+            writer.stop();
+        }
+
+        return buffer.toString();
+    }
+
 }
diff --git 
a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
 
b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
index 64b8c7352ab3..4230f7194055 100644
--- 
a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
+++ 
b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
@@ -608,10 +608,11 @@ public class LocalCliConnector extends ServiceSupport 
implements CliConnector, C
         if (dc != null) {
             String filter = root.getString("filter");
             String format = root.getString("format");
+            String brief = root.getString("brief");
             String uriAsParameters = root.getString("uriAsParameters");
             JsonObject json
                     = (JsonObject) dc.call(DevConsole.MediaType.JSON,
-                            Map.of("filter", filter, "format", format, 
"uriAsParameters", uriAsParameters));
+                            Map.of("filter", filter, "format", format, 
"uriAsParameters", uriAsParameters, "brief", brief));
             LOG.trace("Updating output file: {}", outputFile);
             IOHelper.writeText(json.toJson(), outputFile);
         } else {
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java
index 7d1a204bb1a2..b4ba37902e94 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java
@@ -51,24 +51,40 @@ public class CamelRouteDumpAction extends ActionBaseCommand 
{
 
     }
 
+    public static class FormatCompletionCandidates implements Iterable<String> 
{
+
+        public FormatCompletionCandidates() {
+        }
+
+        @Override
+        public Iterator<String> iterator() {
+            return List.of("yaml", "xml", "text").iterator();
+        }
+
+    }
+
     @CommandLine.Parameters(description = "Name or pid of running Camel 
integration", arity = "0..1")
     String name = "*";
 
-    @CommandLine.Option(names = { "--format" },
-                        description = "Output format (xml or yaml)", 
defaultValue = "yaml")
+    @CommandLine.Option(names = { "--format" }, completionCandidates = 
FormatCompletionCandidates.class,
+                        description = "Output format (xml, yaml, or text)", 
defaultValue = "yaml")
     String format;
 
     @CommandLine.Option(names = { "--raw" },
                         description = "To output raw without metadata")
     boolean raw;
 
+    @CommandLine.Option(names = { "--brief" },
+                        description = "To output route structure only (without 
options) and only applicable for xml or yaml format")
+    boolean brief;
+
     @CommandLine.Option(names = { "--uri-as-parameters" },
                         description = "Whether to expand URIs into separated 
key/value parameters (only in use for YAML format)",
                         defaultValue = "true")
     boolean uriAsParameters;
 
     @CommandLine.Option(names = { "--filter" },
-                        description = "Filter route by filename (multiple 
names can be separated by comma)")
+                        description = "Filter route by filename or route id 
(multiple names can be separated by comma)")
     String filter;
 
     @CommandLine.Option(names = { "--sort" }, completionCandidates = 
NameIdCompletionCandidates.class,
@@ -104,6 +120,7 @@ public class CamelRouteDumpAction extends ActionBaseCommand 
{
         root.put("action", "route-dump");
         root.put("filter", "*");
         root.put("format", format);
+        root.put("brief", brief);
         root.put("uriAsParameters", uriAsParameters);
         Path file = getActionFile(Long.toString(pid));
         try {
@@ -141,7 +158,8 @@ public class CamelRouteDumpAction extends ActionBaseCommand 
{
                         if (!f.endsWith("*")) {
                             f += "*";
                         }
-                        boolean match = 
PatternHelper.matchPattern(row.location, f);
+                        boolean match
+                                = PatternHelper.matchPattern(row.location, f) 
|| PatternHelper.matchPattern(row.routeId, f);
                         if (negate) {
                             match = !match;
                         }

Reply via email to