This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch feature/CAMEL-23672-tui-diagram in repository https://gitbox.apache.org/repos/asf/camel.git
commit f045f778ddb58cc195245239be76544eb9951d75 Author: Claus Ibsen <[email protected]> AuthorDate: Wed Jun 3 22:13:53 2026 +0200 CAMEL-23672: camel-tui - Add uri field to ModelDumpLine and route structure JSON Enriched the dev console route-structure response with a dedicated uri field for endpoint-producing EIP nodes (from, to, toD, wireTap, etc). This replaces fragile parsing of the code[uri] format for route linking. Co-Authored-By: Claude Opus 4.6 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../apache/camel/diagram/RouteDiagramHelper.java | 4 +++ .../camel/diagram/RouteDiagramLayoutEngine.java | 1 + .../java/org/apache/camel/spi/ModelDumpLine.java | 3 +- .../impl/console/RouteStructureDevConsole.java | 3 ++ .../camel/impl/DefaultModelToStructureDumper.java | 19 +++++++++---- .../jbang/core/commands/tui/DiagramSupport.java | 32 ++++++---------------- .../commands/tui/diagram/RouteDiagramWidget.java | 16 ++++------- 7 files changed, 37 insertions(+), 41 deletions(-) diff --git a/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramHelper.java b/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramHelper.java index 5ad89d4b11e4..6024a5d8a814 100644 --- a/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramHelper.java +++ b/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramHelper.java @@ -70,6 +70,10 @@ public final class RouteDiagramHelper { node.type = line.getString("type"); node.id = line.getString("id"); node.code = Jsoner.unescape(line.getString("code")); + String uri = line.getString("uri"); + if (uri != null) { + node.uri = Jsoner.unescape(uri); + } node.description = line.getString("description"); Integer level = line.getInteger("level"); node.level = level != null ? level : 0; diff --git a/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramLayoutEngine.java b/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramLayoutEngine.java index 851a6ca65d56..2c7cb558a427 100644 --- a/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramLayoutEngine.java +++ b/components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramLayoutEngine.java @@ -154,6 +154,7 @@ public class RouteDiagramLayoutEngine { public String type; public String id; public String code; + public String uri; public String description; public int level; public StatInfo stat; diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/ModelDumpLine.java b/core/camel-api/src/main/java/org/apache/camel/spi/ModelDumpLine.java index 7f1e40646502..a5e0ba00eb7b 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/ModelDumpLine.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/ModelDumpLine.java @@ -27,8 +27,9 @@ import org.jspecify.annotations.Nullable; * @param level indent level of the EIP node * @param code EIP code such as label or short name that is human-readable or pseudocode * @param description optional description of the EIP node + * @param uri the raw endpoint URI for endpoint-producing EIP nodes (from, to, toD, wireTap, enrich, etc.) * @since 4.16 */ public record ModelDumpLine(@Nullable String location, String type, String id, int level, String code, - @Nullable String description) { + @Nullable String description, @Nullable String uri) { } diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteStructureDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteStructureDevConsole.java index a55dd747b06f..f8ab84fe6859 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteStructureDevConsole.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteStructureDevConsole.java @@ -202,6 +202,9 @@ public class RouteStructureDevConsole extends AbstractDevConsole { c.put("description", line.description()); } c.put("code", Jsoner.escape(line.code())); + if (line.uri() != null) { + c.put("uri", Jsoner.escape(line.uri())); + } if (metric && mcc != null) { if (counter <= 2) { diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModelToStructureDumper.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModelToStructureDumper.java index 3389e5bf6355..e980ced54f7d 100644 --- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModelToStructureDumper.java +++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModelToStructureDumper.java @@ -46,12 +46,15 @@ public class DefaultModelToStructureDumper implements ModelToStructureDumper { String loc = scheme + ":" + LoggerHelper.getLineNumberLoggerName(def); answer.add( - new ModelDumpLine(loc, "route", def.getRouteId(), 0, "route[" + def.getRouteId() + "]", def.getDescription())); + new ModelDumpLine( + loc, "route", def.getRouteId(), 0, "route[" + def.getRouteId() + "]", def.getDescription(), + null)); String uri = def.getInput().getLabel(); if (brief) { uri = StringHelper.before(uri, "?", uri); } - answer.add(new ModelDumpLine(loc, "from", routeId, 1, "from[" + uri + "]", def.getDescription())); + String fromUri = def.getInput().getEndpointUri(); + answer.add(new ModelDumpLine(loc, "from", routeId, 1, "from[" + uri + "]", def.getDescription(), fromUri)); dumpChildren(def, scheme, brief, 2, answer); @@ -69,11 +72,15 @@ public class DefaultModelToStructureDumper implements ModelToStructureDumper { String id = output.getId(); boolean choice = "choice".equals(kind); String code = choice || brief ? output.getShortName() : output.getLabel(); - if (brief && output instanceof EndpointRequiredDefinition erd) { - String uri = StringHelper.before(erd.getEndpointUri(), "?", erd.getEndpointUri()); - code = output.getShortName() + "[" + uri + "]"; + String endpointUri = null; + if (output instanceof EndpointRequiredDefinition erd) { + endpointUri = erd.getEndpointUri(); + if (brief) { + String uri = StringHelper.before(endpointUri, "?", endpointUri); + code = output.getShortName() + "[" + uri + "]"; + } } - answer.add(new ModelDumpLine(loc, kind, id, level, code, output.getDescription())); + answer.add(new ModelDumpLine(loc, kind, id, level, code, output.getDescription(), endpointUri)); } dumpChildren(child, scheme, brief, level + 1, answer); } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramSupport.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramSupport.java index 7c429eab91ca..8fd0464e085e 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramSupport.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramSupport.java @@ -594,7 +594,7 @@ class DiagramSupport { && !"from".equals(type)) { return null; } - String baseUri = extractBaseUri(box.layoutNode().treeNode.info.code); + String baseUri = stripQueryParams(box.layoutNode().treeNode.info.uri); if (baseUri == null || baseUri.isBlank()) { return null; } @@ -609,7 +609,7 @@ class DiagramSupport { } else { // "to" node: find route that consumes FROM this endpoint if (currentRouteId.equals(edge.from.routeId) && !currentRouteId.equals(edge.to.routeId)) { - String targetFrom = extractBaseUri(edge.to.from); + String targetFrom = stripQueryParams(edge.to.from); if (baseUri.equals(targetFrom)) { return edge.to.routeId; } @@ -617,7 +617,7 @@ class DiagramSupport { } } - // Fallback: match code against route "from" endpoints in routeLayouts + // Fallback: match uri against route "from" endpoints in routeLayouts if (!"from".equals(type)) { for (var entry : routeLayouts.entrySet()) { if (currentRouteId.equals(entry.getKey())) { @@ -627,7 +627,7 @@ class DiagramSupport { if (!lr.nodes.isEmpty()) { var firstNode = lr.nodes.get(0); if ("from".equals(firstNode.type) && firstNode.treeNode != null) { - String fromBaseUri = extractBaseUri(firstNode.treeNode.info.code); + String fromBaseUri = stripQueryParams(firstNode.treeNode.info.uri); if (baseUri.equals(fromBaseUri)) { return entry.getKey(); } @@ -638,24 +638,10 @@ class DiagramSupport { return null; } - /** - * Extracts the bare endpoint URI from a code field like "from[direct:foo?bar=baz]" or "to[kafka:topic]". Returns - * the base URI without query parameters. - */ - static String extractBaseUri(String code) { - if (code == null) { + static String stripQueryParams(String uri) { + if (uri == null) { return null; } - // Strip type[...] wrapper - int open = code.indexOf('['); - int close = code.lastIndexOf(']'); - String uri; - if (open >= 0 && close > open) { - uri = code.substring(open + 1, close); - } else { - uri = code; - } - // Strip query parameters int q = uri.indexOf('?'); return q >= 0 ? uri.substring(0, q) : uri; } @@ -765,7 +751,7 @@ class DiagramSupport { if (currentLayout != null && !currentLayout.nodes.isEmpty()) { var fromNode = currentLayout.nodes.get(0); if ("from".equals(fromNode.type) && fromNode.treeNode != null) { - currentFromUri = extractBaseUri(fromNode.treeNode.info.code); + currentFromUri = stripQueryParams(fromNode.treeNode.info.uri); } } @@ -778,7 +764,7 @@ class DiagramSupport { // Add "from" URIs of other routes (linkable from "to" nodes) var firstNode = lr.nodes.get(0); if ("from".equals(firstNode.type) && firstNode.treeNode != null) { - String uri = extractBaseUri(firstNode.treeNode.info.code); + String uri = stripQueryParams(firstNode.treeNode.info.uri); if (uri != null) { endpoints.add(uri); } @@ -789,7 +775,7 @@ class DiagramSupport { String type = node.type; if (("to".equals(type) || "toD".equals(type) || "wireTap".equals(type)) && node.treeNode != null) { - String uri = extractBaseUri(node.treeNode.info.code); + String uri = stripQueryParams(node.treeNode.info.uri); if (currentFromUri.equals(uri)) { endpoints.add(currentFromUri); } diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/diagram/RouteDiagramWidget.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/diagram/RouteDiagramWidget.java index 7d8cd4cb827d..8762935f9536 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/diagram/RouteDiagramWidget.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/diagram/RouteDiagramWidget.java @@ -429,19 +429,13 @@ public class RouteDiagramWidget implements Widget { && !"from".equals(type)) { return false; } - String baseUri = extractBaseUri(node.treeNode.info.code); - return baseUri != null && linkableEndpoints.contains(baseUri); - } - - private static String extractBaseUri(String code) { - if (code == null) { - return null; + String uri = node.treeNode.info.uri; + if (uri == null) { + return false; } - int open = code.indexOf('['); - int close = code.lastIndexOf(']'); - String uri = (open >= 0 && close > open) ? code.substring(open + 1, close) : code; int q = uri.indexOf('?'); - return q >= 0 ? uri.substring(0, q) : uri; + String baseUri = q >= 0 ? uri.substring(0, q) : uri; + return linkableEndpoints.contains(baseUri); } private int toRow(int pixelY) {
