This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch CAMEL-26691-timeline-tui
in repository https://gitbox.apache.org/repos/asf/camel.git

commit bc9ffaa6bcc32ded95cf6538e6e9edbc50e79631
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Nov 6 23:31:50 2026 +0100

    CAMEL-26691: timeline - a route down between two samples, and the 
screenshot in the docs
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../modules/ROOT/images/jbang/camel-tui-timeline.png   | Bin 0 -> 323915 bytes
 .../camel/dsl/jbang/core/commands/tui/Timeline.java    |  12 ++++++++++++
 .../dsl/jbang/core/commands/tui/TimelineTest.java      |  17 +++++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/docs/user-manual/modules/ROOT/images/jbang/camel-tui-timeline.png 
b/docs/user-manual/modules/ROOT/images/jbang/camel-tui-timeline.png
new file mode 100644
index 000000000000..c929b511a7bb
Binary files /dev/null and 
b/docs/user-manual/modules/ROOT/images/jbang/camel-tui-timeline.png differ
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Timeline.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Timeline.java
index 6b1f4c5e65d9..a0fb3ce06fca 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Timeline.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Timeline.java
@@ -147,6 +147,18 @@ final class Timeline {
         }
         if (!down.isEmpty()) {
             rec.down.put(second, down);
+            // a route down at the last sample too was down in the seconds 
between (a status not written each second)
+            Map.Entry<Long, Set<String>> before = rec.down.lowerEntry(second);
+            if (before != null && second - before.getKey() <= SPREAD && 
rec.routes.lowerKey(second) != null
+                    && rec.routes.lowerKey(second) <= before.getKey()) {
+                for (long s = before.getKey() + 1; s < second; s++) {
+                    for (String route : down) {
+                        if (before.getValue().contains(route)) {
+                            rec.down.computeIfAbsent(s, x -> new 
LinkedHashSet<>()).add(route);
+                        }
+                    }
+                }
+            }
         } else {
             rec.down.remove(second);
         }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/TimelineTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/TimelineTest.java
index bbaf0e7cc8c4..ca94a641994f 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/TimelineTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/TimelineTest.java
@@ -149,6 +149,23 @@ class TimelineTest {
         assertThat(timeline.routes("1234", List.of("orders"), S0, 
60)).isEmpty();
     }
 
+    @Test
+    void aRouteDownAtTwoSamplesWasDownInTheSecondsBetween() throws Exception {
+        IntegrationInfo info = info(0, 0, 0, 0, 0);
+        info.chaos = ChaosInfo.parse((JsonObject) Jsoner.deserialize("""
+                {"enabled": true,
+                 "rules": [{"id": "r3", "version": 1, "state": "active", 
"rule": "route=orders stall duration=20s",
+                            "matches": 1, "fired": {"lifecycle": 1},
+                            "lifecycle": {"action": "suspend", "route": 
"orders", "state": "down"}}],
+                 "report": {"verdict": "PASS", "routes": [], "recentFaults": 
[]}}
+                """));
+        timeline.record(info, T0);
+        // the status was not written for two seconds
+        timeline.record(info, T0 + 3000);
+
+        assertThat(orders(S0 + 3, 4).down()).containsExactly(1, 1, 1, 1);
+    }
+
     private static ErrorInfo error(String route, String node, String message, 
long repeat, long timestamp) {
         ErrorInfo e = new ErrorInfo();
         e.routeId = route;

Reply via email to