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 8d336e72ef922b860c6f145484777d0a153dd9e3
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Jun 3 21:13:12 2026 +0200

    CAMEL-23672: camel-tui - Single IPC call for topology + route structure
    
    Add routes=true option to route-topology dev console that includes
    route structure data in the same response, eliminating a second IPC
    round-trip when loading the TUI diagram tab.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../impl/console/RouteTopologyDevConsole.java      | 20 +++++++++++
 .../camel/cli/connector/LocalCliConnector.java     |  4 ++-
 .../jbang/core/commands/tui/DiagramSupport.java    | 42 ++++++++++++----------
 3 files changed, 46 insertions(+), 20 deletions(-)

diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteTopologyDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteTopologyDevConsole.java
index 0caa74155434..2645d206ea9a 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteTopologyDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteTopologyDevConsole.java
@@ -23,6 +23,7 @@ import java.util.Map;
 import org.apache.camel.api.management.ManagedCamelContext;
 import org.apache.camel.api.management.mbean.ManagedRouteMBean;
 import org.apache.camel.api.management.mbean.ManagedSendProcessorMBean;
+import org.apache.camel.console.DevConsoleRegistry;
 import org.apache.camel.spi.RouteTopologyDumper;
 import org.apache.camel.spi.RouteTopologyDumper.TopologyEdge;
 import org.apache.camel.spi.RouteTopologyDumper.TopologyExternalEndpoint;
@@ -40,6 +41,7 @@ public class RouteTopologyDevConsole extends 
AbstractDevConsole {
 
     private static final String METRIC = "metric";
     private static final String EXTERNAL = "external";
+    private static final String ROUTES = "routes";
 
     public RouteTopologyDevConsole() {
         super("camel", "route-topology", "Route Topology", "Route topology 
showing inter-route connections");
@@ -166,6 +168,24 @@ public class RouteTopologyDevConsole extends 
AbstractDevConsole {
             root.put("externalEndpoints", extArr);
         }
 
+        // Optionally include route structure data in the same response
+        if ("true".equals(options.get(ROUTES))) {
+            DevConsoleRegistry registry = 
getCamelContext().getCamelContextExtension()
+                    .getContextPlugin(DevConsoleRegistry.class);
+            if (registry != null) {
+                var structureConsole = registry.resolveById("route-structure");
+                if (structureConsole != null) {
+                    String metricStr = metric ? "true" : "false";
+                    JsonObject structureResult = (JsonObject) 
structureConsole.call(
+                            org.apache.camel.console.DevConsole.MediaType.JSON,
+                            Map.of("filter", "*", "brief", "false", "metric", 
metricStr));
+                    if (structureResult != null) {
+                        root.put("routes", structureResult.get("routes"));
+                    }
+                }
+            }
+        }
+
         return root;
     }
 
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 91296898a42a..dfe522aa3af9 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
@@ -756,8 +756,10 @@ public class LocalCliConnector extends ServiceSupport 
implements CliConnector, C
         if (dc != null) {
             String metric = root.getStringOrDefault("metric", "false");
             String external = root.getStringOrDefault("external", "false");
+            String routes = root.getStringOrDefault("routes", "false");
             JsonObject json
-                    = (JsonObject) dc.call(DevConsole.MediaType.JSON, 
Map.of("metric", metric, "external", external));
+                    = (JsonObject) dc.call(DevConsole.MediaType.JSON,
+                            Map.of("metric", metric, "external", external, 
"routes", routes));
             LOG.trace("Updating output file: {}", outputFile);
             IOHelper.writeText(json.toJson(), outputFile);
         } else {
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 14c76243390b..340dcc7a2ef1 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
@@ -788,10 +788,8 @@ class DiagramSupport {
 
     void loadAllDiagramsInBackground(
             MonitorContext ctx, String pid, boolean metrics, boolean external) 
{
-        // Fetch topology
-        JsonObject topoJson = requestRouteTopology(ctx, pid, external);
-        // Fetch all route structures
-        JsonObject routeJson = requestRouteStructure(ctx, pid);
+        // Single IPC call: topology + route structures
+        JsonObject topoJson = requestRouteTopology(ctx, pid, external, true);
 
         TopologyLayoutResult topoResult = null;
         int nodeW = 0;
@@ -813,20 +811,23 @@ class DiagramSupport {
             }
         }
 
+        // Route structure is included in the topology response (routes=true)
         java.util.Map<String, RouteDiagramLayoutEngine.LayoutRoute> routeMap = 
new java.util.LinkedHashMap<>();
-        if (routeJson != null) {
-            List<RouteDiagramLayoutEngine.RouteInfo> routes = 
RouteDiagramHelper.parseRoutes(routeJson);
-            RouteDiagramLayoutEngine.NodeLabelMode labelMode = showDescription
-                    ? RouteDiagramLayoutEngine.NodeLabelMode.DESCRIPTION
-                    : RouteDiagramLayoutEngine.NodeLabelMode.CODE;
-            RouteDiagramLayoutEngine engine = new RouteDiagramLayoutEngine(
-                    RouteDiagramLayoutEngine.DEFAULT_BOX_WIDTH, 
RouteDiagramLayoutEngine.DEFAULT_FONT_SIZE,
-                    labelMode);
-            int currentY = RouteDiagramLayoutEngine.PADDING;
-            for (RouteDiagramLayoutEngine.RouteInfo r : routes) {
-                RouteDiagramLayoutEngine.LayoutRoute lr = 
engine.layoutRoute(r, currentY);
-                routeMap.put(r.routeId, lr);
-                currentY = lr.maxY + RouteDiagramLayoutEngine.V_GAP;
+        if (topoJson != null) {
+            List<RouteDiagramLayoutEngine.RouteInfo> routes = 
RouteDiagramHelper.parseRoutes(topoJson);
+            if (!routes.isEmpty()) {
+                RouteDiagramLayoutEngine.NodeLabelMode labelMode = 
showDescription
+                        ? RouteDiagramLayoutEngine.NodeLabelMode.DESCRIPTION
+                        : RouteDiagramLayoutEngine.NodeLabelMode.CODE;
+                RouteDiagramLayoutEngine engine = new RouteDiagramLayoutEngine(
+                        RouteDiagramLayoutEngine.DEFAULT_BOX_WIDTH, 
RouteDiagramLayoutEngine.DEFAULT_FONT_SIZE,
+                        labelMode);
+                int currentY = RouteDiagramLayoutEngine.PADDING;
+                for (RouteDiagramLayoutEngine.RouteInfo r : routes) {
+                    RouteDiagramLayoutEngine.LayoutRoute lr = 
engine.layoutRoute(r, currentY);
+                    routeMap.put(r.routeId, lr);
+                    currentY = lr.maxY + RouteDiagramLayoutEngine.V_GAP;
+                }
             }
         }
 
@@ -902,7 +903,7 @@ class DiagramSupport {
 
     void loadTopologyDiagramInBackground(
             MonitorContext ctx, String pid, boolean textMode, boolean metrics, 
boolean external) {
-        JsonObject jo = requestRouteTopology(ctx, pid, external);
+        JsonObject jo = requestRouteTopology(ctx, pid, external, false);
         if (jo == null) {
             applyResult(ctx, List.of("(No response from integration)"), null, 
null, null);
             return;
@@ -987,7 +988,7 @@ class DiagramSupport {
         }
     }
 
-    private JsonObject requestRouteTopology(MonitorContext ctx, String pid, 
boolean external) {
+    private JsonObject requestRouteTopology(MonitorContext ctx, String pid, 
boolean external, boolean routes) {
         Path outputFile = ctx.getOutputFile(pid);
         PathUtils.deleteFile(outputFile);
 
@@ -997,6 +998,9 @@ class DiagramSupport {
         if (external) {
             root.put("external", "true");
         }
+        if (routes) {
+            root.put("routes", "true");
+        }
 
         Path actionFile = ctx.getActionFile(pid);
         PathUtils.writeTextSafely(root.toJson(), actionFile);

Reply via email to