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 106943cc3dc0 CAMEL-22605: camel-jbang - Route dump in YAML should have 
precise line numbers (#19748)
106943cc3dc0 is described below

commit 106943cc3dc0e3e62a670a56beab72619ca800dd
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Oct 29 11:21:44 2025 +0100

    CAMEL-22605: camel-jbang - Route dump in YAML should have precise line 
numbers (#19748)
---
 .../org/apache/camel/spi/ModelToYAMLDumper.java    |  4 +-
 .../camel/impl/console/RouteDumpDevConsole.java    | 57 +++++++++++++++++++---
 .../camel/impl/DefaultDumpRoutesStrategy.java      |  2 +-
 .../util/DumpModelAsYamlSourceLocationTest.java    | 19 ++++++--
 .../util/DumpModelAsYamlTransformRouteTest.java    |  2 +-
 .../util/DumpModelAsYamlUriAsParametersTest.java   |  4 +-
 .../management/mbean/ManagedCamelContextMBean.java |  4 ++
 .../api/management/mbean/ManagedRouteMBean.java    |  3 +-
 .../management/mbean/ManagedCamelContext.java      |  9 +++-
 .../camel/management/mbean/ManagedRoute.java       | 10 ++--
 .../org/apache/camel/yaml/LwModelToYAMLDumper.java |  8 +--
 .../ROOT/pages/camel-4x-upgrade-guide-4_16.adoc    |  3 ++
 12 files changed, 100 insertions(+), 25 deletions(-)

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..5878bf7aa519 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
@@ -50,12 +50,14 @@ public interface ModelToYAMLDumper {
      * @param  resolvePlaceholders whether to resolve property placeholders in 
the dumped YAML
      * @param  uriAsParameters     whether to expand uri into a key/value 
parameters
      * @param  generatedIds        whether to include auto generated IDs
+     * @param  sourceLocation      whether to include source location:line
      * @return                     the output in YAML (is formatted)
      * @throws Exception           is throw if error marshalling to YAML
      */
     String dumpModelAsYaml(
             CamelContext context, NamedNode definition,
-            boolean resolvePlaceholders, boolean uriAsParameters, boolean 
generatedIds)
+            boolean resolvePlaceholders, boolean uriAsParameters, boolean 
generatedIds,
+            boolean sourceLocation)
             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 605a64d27f8f..438290e81c14 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
@@ -43,8 +43,8 @@ import org.apache.camel.util.json.Jsoner;
 @DevConsole(name = "route-dump", description = "Dump route in XML or YAML 
format")
 public class RouteDumpDevConsole extends AbstractDevConsole {
 
-    private static final Pattern SOURCE_LOCATION_PATTERN = 
Pattern.compile("(\\ssourceLocation=\"(.*?)\")");
-    private static final Pattern SOURCE_LINE_PATTERN = 
Pattern.compile("(\\ssourceLineNumber=\"(.*?)\")");
+    private static final Pattern XML_SOURCE_LOCATION_PATTERN = 
Pattern.compile("(\\ssourceLocation=\"(.*?)\")");
+    private static final Pattern XML_SOURCE_LINE_PATTERN = 
Pattern.compile("(\\ssourceLineNumber=\"(.*?)\")");
 
     /**
      * To output in either xml, yaml, or text format
@@ -131,10 +131,15 @@ public class RouteDumpDevConsole extends 
AbstractDevConsole {
                     dump = mrb.dumpRouteAsXml(true, false, true);
                 } else if ("yaml".equals(format)) {
                     jo.put("format", "yaml");
-                    dump = mrb.dumpRouteAsYaml(true, 
"true".equals(uriAsParameters));
+                    dump = mrb.dumpRouteAsYaml(true, 
"true".equals(uriAsParameters), false, true);
                 }
                 if (dump != null) {
-                    List<JsonObject> code = loadSourceAsJson(new 
StringReader(dump));
+                    List<JsonObject> code;
+                    if (format == null || "xml".equals(format)) {
+                        code = xmlLoadSourceAsJson(new StringReader(dump));
+                    } else {
+                        code = yamlLoadSourceAsJson(new StringReader(dump));
+                    }
                     if (code != null) {
                         jo.put("code", code);
                     }
@@ -188,7 +193,7 @@ public class RouteDumpDevConsole extends AbstractDevConsole 
{
         return o1.getRouteId().compareTo(o2.getRouteId());
     }
 
-    private static List<JsonObject> loadSourceAsJson(Reader reader) {
+    private static List<JsonObject> xmlLoadSourceAsJson(Reader reader) {
         List<JsonObject> code = new ArrayList<>();
         try {
             LineNumberReader lnr = new LineNumberReader(reader);
@@ -198,11 +203,11 @@ public class RouteDumpDevConsole extends 
AbstractDevConsole {
                 if (t != null) {
                     // extra source location from code line
                     String idx = null;
-                    Matcher m = SOURCE_LOCATION_PATTERN.matcher(t);
+                    Matcher m = XML_SOURCE_LOCATION_PATTERN.matcher(t);
                     if (m.find()) {
                         t = m.replaceFirst("");
                     }
-                    m = SOURCE_LINE_PATTERN.matcher(t);
+                    m = XML_SOURCE_LINE_PATTERN.matcher(t);
                     if (m.find()) {
                         idx = m.group(2);
                         t = m.replaceFirst("");
@@ -221,4 +226,42 @@ public class RouteDumpDevConsole extends 
AbstractDevConsole {
         return code.isEmpty() ? null : code;
     }
 
+    private static List<JsonObject> yamlLoadSourceAsJson(Reader reader) {
+        List<JsonObject> code = new ArrayList<>();
+        try {
+            LineNumberReader lnr = new LineNumberReader(reader);
+            String t;
+            do {
+                t = lnr.readLine();
+                if (t != null) {
+                    // extra source location from code line
+                    if (t.contains("sourceLocation: ")) {
+                        // skip this line
+                    } else if (t.contains("sourceLineNumber: ")) {
+                        String idx = StringHelper.after(t, "sourceLineNumber: 
").trim();
+                        if (!code.isEmpty()) {
+                            // assign line number to previous code line
+                            JsonObject c = code.get(code.size() - 1);
+                            try {
+                                c.put("line", Integer.parseInt(idx));
+                            } catch (NumberFormatException e) {
+                                // ignore
+                            }
+                        }
+                    } else {
+                        JsonObject c = new JsonObject();
+                        c.put("code", Jsoner.escape(t));
+                        c.put("line", -1);
+                        code.add(c);
+                    }
+                }
+            } while (t != null);
+            IOHelper.close(lnr);
+        } catch (Exception e) {
+            // ignore
+        }
+
+        return code.isEmpty() ? null : code;
+    }
+
 }
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 ea11890c84bc..6649ea853beb 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
@@ -350,7 +350,7 @@ public class DefaultDumpRoutesStrategy extends 
ServiceSupport implements DumpRou
             CamelContext camelContext, NamedNode def, Resource resource,
             ModelToYAMLDumper dumper, String kind, StringBuilder sbLocal, 
StringBuilder sbLog) {
         try {
-            String dump = dumper.dumpModelAsYaml(camelContext, def, 
resolvePlaceholders, uriAsParameters, generatedIds);
+            String dump = dumper.dumpModelAsYaml(camelContext, def, 
resolvePlaceholders, uriAsParameters, generatedIds, false);
             sbLocal.append(dump);
             appendLogDump(resource, dump, sbLog);
         } catch (Exception e) {
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlSourceLocationTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlSourceLocationTest.java
index 432b5bc93e0b..0acc2beebad6 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlSourceLocationTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlSourceLocationTest.java
@@ -40,9 +40,9 @@ public class DumpModelAsYamlSourceLocationTest extends 
DumpModelAsYamlTestSuppor
         assertNotNull(yaml);
         log.info(yaml);
 
-        Assertions.assertTrue(yaml.contains("sourceLineNumber: 67"));
-        Assertions.assertTrue(yaml.contains("sourceLineNumber: 68"));
-        Assertions.assertTrue(yaml.contains("sourceLineNumber: 69"));
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 80"));
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 81"));
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 82"));
         Assertions.assertTrue(yaml.contains("sourceLocation: 
DumpModelAsYamlSourceLocationTest.java"));
     }
 
@@ -58,6 +58,19 @@ public class DumpModelAsYamlSourceLocationTest extends 
DumpModelAsYamlTestSuppor
         Assertions.assertTrue(yaml.contains("sourceLocation: 
MyCoolRoute.java"));
     }
 
+    @Test
+    public void testDumpModelAsYamlSourceLocation() throws Exception {
+        String yaml = 
PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, 
context.getRouteDefinition("cool"),
+                true, true, false, true);
+        assertNotNull(yaml);
+        log.info(yaml);
+
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 25"));
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 26"));
+        Assertions.assertTrue(yaml.contains("sourceLineNumber: 27"));
+        Assertions.assertTrue(yaml.contains("sourceLocation: 
MyCoolRoute.java"));
+    }
+
     @Override
     protected RouteBuilder[] createRouteBuilders() {
         return new RouteBuilder[] {
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlTransformRouteTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlTransformRouteTest.java
index 8c72267fb518..a666bd1f0897 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlTransformRouteTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlTransformRouteTest.java
@@ -41,7 +41,7 @@ public class DumpModelAsYamlTransformRouteTest extends 
DumpModelAsYamlTestSuppor
     @Test
     public void testDumpModelAsYamlUriAsParameters() throws Exception {
         String out = 
PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, 
context.getRouteDefinition("myRoute"),
-                true, true, true);
+                true, true, true, false);
         assertNotNull(out);
         log.info(out);
 
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlUriAsParametersTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlUriAsParametersTest.java
index 4019de4d133b..07533f9f2902 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlUriAsParametersTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/util/DumpModelAsYamlUriAsParametersTest.java
@@ -30,7 +30,7 @@ public class DumpModelAsYamlUriAsParametersTest extends 
DumpModelAsYamlTestSuppo
     @Test
     public void testDumpModelAsYaml() throws Exception {
         String out = 
PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, 
context.getRouteDefinition("myRoute"),
-                true, true, true);
+                true, true, true, false);
         assertNotNull(out);
         log.info(out);
 
@@ -43,7 +43,7 @@ public class DumpModelAsYamlUriAsParametersTest extends 
DumpModelAsYamlTestSuppo
     @Test
     public void testDumpModelAsYamlGeneratedIds() throws Exception {
         String out = 
PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, 
context.getRouteDefinition("myRoute"),
-                true, true, false);
+                true, true, false, false);
         assertNotNull(out);
         log.info(out);
 
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 eb7a038ca81f..592918eccd0f 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
@@ -252,6 +252,10 @@ public interface ManagedCamelContextMBean extends 
ManagedPerformanceCounterMBean
     @ManagedOperation(description = "Dumps the routes as YAML")
     String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean 
uriAsParameters, boolean generatedIds) throws Exception;
 
+    @ManagedOperation(description = "Dumps the routes as YAML")
+    String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean 
uriAsParameters, boolean generatedIds, boolean sourceLocation)
+            throws Exception;
+
     /**
      * Creates the endpoint by the given uri
      *
diff --git 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
index 3df614777a29..cfc54f8118ec 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
@@ -152,7 +152,8 @@ public interface ManagedRouteMBean extends 
ManagedPerformanceCounterMBean {
     String dumpRouteAsYaml(boolean resolvePlaceholders, boolean 
uriAsParameters) throws Exception;
 
     @ManagedOperation(description = "Dumps the route as YAML")
-    String dumpRouteAsYaml(boolean resolvePlaceholders, boolean 
uriAsParameters, boolean generatedIds) throws Exception;
+    String dumpRouteAsYaml(boolean resolvePlaceholders, boolean 
uriAsParameters, boolean generatedIds, boolean sourceLocation)
+            throws Exception;
 
     @ManagedOperation(description = "Dumps the route stats as XML")
     String dumpRouteStatsAsXml(boolean fullStats, boolean includeProcessors) 
throws Exception;
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index c58d1c4151e7..6b88d05205a0 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
@@ -609,6 +609,13 @@ public class ManagedCamelContext extends 
ManagedPerformanceCounter implements Ti
     @Override
     public String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean 
uriAsParameters, boolean generatedIds)
             throws Exception {
+        return dumpRoutesAsYaml(resolvePlaceholders, uriAsParameters, true, 
false);
+    }
+
+    @Override
+    public String dumpRoutesAsYaml(
+            boolean resolvePlaceholders, boolean uriAsParameters, boolean 
generatedIds, boolean sourceLocation)
+            throws Exception {
         List<RouteDefinition> routes = 
context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinitions();
         if (routes.isEmpty()) {
             return null;
@@ -624,7 +631,7 @@ public class ManagedCamelContext extends 
ManagedPerformanceCounter implements Ti
         }
 
         return 
PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, def, 
resolvePlaceholders, uriAsParameters,
-                generatedIds);
+                generatedIds, sourceLocation);
     }
 
     @Override
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
index 1833b27128c7..6117035dbca5 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
@@ -472,21 +472,23 @@ public class ManagedRoute extends 
ManagedPerformanceCounter implements TimerList
 
     @Override
     public String dumpRouteAsYaml(boolean resolvePlaceholders) throws 
Exception {
-        return dumpRouteAsYaml(resolvePlaceholders, false, true);
+        return dumpRouteAsYaml(resolvePlaceholders, false);
     }
 
     @Override
     public String dumpRouteAsYaml(boolean resolvePlaceholders, boolean 
uriAsParameters) throws Exception {
-        return dumpRouteAsYaml(resolvePlaceholders, uriAsParameters, true);
+        return dumpRouteAsYaml(resolvePlaceholders, uriAsParameters, true, 
false);
     }
 
     @Override
-    public String dumpRouteAsYaml(boolean resolvePlaceholders, boolean 
uriAsParameters, boolean generatedIds) throws Exception {
+    public String dumpRouteAsYaml(
+            boolean resolvePlaceholders, boolean uriAsParameters, boolean 
generatedIds, boolean sourceLocation)
+            throws Exception {
         String id = route.getId();
         RouteDefinition def = 
context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinition(id);
         if (def != null) {
             return 
PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, def, 
resolvePlaceholders,
-                    uriAsParameters, generatedIds);
+                    uriAsParameters, generatedIds, sourceLocation);
         }
 
         return null;
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..5ac6e9f880a8 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
@@ -61,20 +61,20 @@ public class LwModelToYAMLDumper implements 
ModelToYAMLDumper {
 
     @Override
     public String dumpModelAsYaml(CamelContext context, NamedNode definition) 
throws Exception {
-        return dumpModelAsYaml(context, definition, false, false, true);
+        return dumpModelAsYaml(context, definition, false, false, true, false);
     }
 
     @Override
     public String dumpModelAsYaml(
             CamelContext context, NamedNode definition, boolean 
resolvePlaceholders,
-            boolean uriAsParameters, boolean generatedIds)
+            boolean uriAsParameters, boolean generatedIds, boolean 
sourceLocation)
             throws Exception {
         Properties properties = new Properties();
         Map<String, String> namespaces = new LinkedHashMap<>();
         Map<String, KeyValueHolder<Integer, String>> locations = new 
HashMap<>();
         Consumer<RouteDefinition> extractor = route -> {
             extractNamespaces(route, namespaces);
-            if (context.isDebugging()) {
+            if (sourceLocation || context.isDebugging()) {
                 extractSourceLocations(route, locations);
             }
             resolveEndpointDslUris(route);
@@ -97,7 +97,7 @@ public class LwModelToYAMLDumper implements ModelToYAMLDumper 
{
                     doWriteAttribute("id", def.getId());
                 }
                 // write location information
-                if (context.isDebugging()) {
+                if (sourceLocation || 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) {
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_16.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_16.adoc
index 6bfd67ca7d16..dab3621d792a 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_16.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_16.adoc
@@ -18,6 +18,9 @@ See the xref:camel-upgrade-recipes-tool.adoc[documentation] 
page for details.
 The `tryConvertTo` method in Camel type converters will no longer in case of 
no converter suitable,
 mark this as a _miss_ for any same future converter attempts to immediately be 
identified as a _miss_.
 
+The `ModelToYAMLDumper` and `ModelToXMLDumper` has added `boolean 
sourceLocation` as parameter to the 2nd
+`dumpModelAsYaml` methods.
+
 === camel-kamelet
 
 The kamelet component is now parsing endpoint parameters using _raw mode_ to 
ensure when using sensitive parameters

Reply via email to