This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch chore-inspect-breaker-steps in repository https://gitbox.apache.org/repos/asf/camel.git
commit ab6e0678d7731d727476ceda975dd79e210924dc Author: Claus Ibsen <[email protected]> AuthorDate: Mon Nov 9 16:22:54 2026 +0100 chore: camel-jbang - Inspect shows the steps inside a circuit breaker and the route it calls A circuit breaker runs its steps on a copy of the exchange. The history has them, under the copy's exchange id, but Inspect inlines another exchange only under the EIPs that run their steps on exchanges of their own (multicast, split, enrich ...), and the circuit breaker was not one of them: the exchange read from, circuitBreaker, log, with the call to the supplier route left out. Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../dsl/jbang/core/commands/tui/HistoryTab.java | 6 ++-- .../core/commands/tui/HistoryTabRenderTest.java | 36 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTab.java index faa24e5568e6..7732024ee4d0 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTab.java @@ -1907,7 +1907,7 @@ class HistoryTab extends AbstractTab { } } - private List<HistoryEntry> reorderHistoryDepthFirst(List<HistoryEntry> entries) { + List<HistoryEntry> reorderHistoryDepthFirst(List<HistoryEntry> entries) { if (entries.isEmpty()) { return entries; } @@ -1999,10 +1999,10 @@ class HistoryTab extends AbstractTab { } private static boolean isMulticastNode(String nodeShortName) { - if (nodeShortName != null) { + if (nodeShortName != null) { // the EIPs that run their steps on exchanges of their own (a breaker: a copy) return switch (nodeShortName) { case "multicast", "recipientList", "split", "routingSlip", "enrich", "pollEnrich", - "wireTap", "dynamicRouter" -> + "wireTap", "dynamicRouter", "circuitBreaker" -> true; default -> false; }; diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTabRenderTest.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTabRenderTest.java index 76305b44c6f6..8a3e1599ce4d 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTabRenderTest.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/HistoryTabRenderTest.java @@ -30,6 +30,7 @@ import dev.tamboui.text.Span; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -201,6 +202,41 @@ class HistoryTabRenderTest { assertTrue(title.contains("elapsed:17ms"), title); } + @Test + void theStepsOfACircuitBreakerAreUnderIt() { + // as the history of the circuit breaker example has it: the breaker runs its steps on a copy (131) of the + // exchange (130), and the copy calls the supplier route over direct + List<HistoryEntry> entries = List.of( + step("130", "stock-check", "from1", "from", "from[timer://stock]", true, false), + step("130", "stock-check", "circuitBreaker1", "circuitBreaker", "circuitBreaker", false, false), + step("131", "stock-check", "to1", "to", "to[direct:supplier]", false, false), + step("131", "supplier", "from2", "from", "from[direct://supplier]", true, false), + step("131", "supplier", "setBody3", "setBody", "setBody[simple{in stock}]", false, false), + step("131", "supplier", "from2", "from", "from[direct://supplier]", false, true), + step("130", "stock-check", "log1", "log", "log[Stock check]", false, false), + step("130", "stock-check", "from1", "from", "from[timer://stock]", false, true)); + + List<HistoryEntry> ordered = new HistoryTab(ctx, traces, new HashMap<>()).reorderHistoryDepthFirst(entries); + + assertEquals(List.of("from1", "circuitBreaker1", "to1", "from2", "setBody3", "from2", "log1", "from1"), + ordered.stream().map(e -> e.nodeId).toList()); + assertEquals(List.of(0, 0, 1, 1, 1, 1, 0, 0), ordered.stream().map(e -> e.inlineDepth).toList()); + } + + private static HistoryEntry step( + String exchangeId, String routeId, String nodeId, String shortName, String label, boolean first, + boolean last) { + HistoryEntry e = new HistoryEntry(); + e.exchangeId = exchangeId; + e.routeId = routeId; + e.nodeId = nodeId; + e.nodeShortName = shortName; + e.nodeLabel = label; + e.first = first; + e.last = last; + return e; + } + private static HistoryEntry historyEntry(String routeId, long elapsed, boolean last) { HistoryEntry e = new HistoryEntry(); e.routeId = routeId;
