This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch lines3 in repository https://gitbox.apache.org/repos/asf/camel.git
commit 91d3e9dfab03e6e7ef5052f09c7b47f0c99fbff4 Author: Claus Ibsen <[email protected]> AuthorDate: Wed Oct 29 09:47:33 2025 +0100 CAMEL-22605: camel-jbang - Route dump in YAML should have precise line numbers --- .../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
