This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch obs3 in repository https://gitbox.apache.org/repos/asf/camel.git
commit c8a25cf0ded1d0b6f46b7d1dc67fb3401d3acd3c Author: Claus Ibsen <[email protected]> AuthorDate: Sat May 30 11:17:10 2026 +0200 CAMEL-23648: camel-jbang - TUI consumers tab show schedule info and update cron-log example Co-Authored-By: Claude <[email protected]> --- .../src/main/resources/examples/cron-log/README.md | 2 +- .../examples/cron-log/application.properties | 2 - .../examples/cron-log/cron-log.camel.yaml | 11 ++- .../dsl/jbang/core/commands/tui/ConsumersTab.java | 91 +++++++++++++++++++--- 4 files changed, 89 insertions(+), 17 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/README.md b/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/README.md index cd926f1f9b8f..6bf8e7b5681f 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/README.md +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/README.md @@ -1,6 +1,6 @@ # Cron Log -This example shows a scheduled task that logs the current time every 5 seconds. +This example shows a scheduled task using a cron expression that logs the current time every 5 seconds. ## How to run diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/application.properties b/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/application.properties index a60bfaac62a6..9194b486f064 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/application.properties +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/application.properties @@ -14,7 +14,5 @@ ## See the License for the specific language governing permissions and ## limitations under the License. ## --------------------------------------------------------------------------- -# Timer period in milliseconds -cron.period=5000 # Log message prefix cron.message=Scheduled task running at diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/cron-log.camel.yaml b/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/cron-log.camel.yaml index 2ccc3b93c7c9..b2ad3ff59b74 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/cron-log.camel.yaml +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/examples/cron-log/cron-log.camel.yaml @@ -18,10 +18,13 @@ - route: id: cron-log from: - uri: timer:cron + uri: cron:tab parameters: - period: "{{cron.period}}" + schedule: "0/5 * * * * ?" steps: - setBody: - simple: "{{cron.message}} ${date:now:HH:mm:ss}" - - log: "${body}" + expression: + simple: + expression: "{{cron.message}} ${date:now:HH:mm:ss}" + - log: + message: "${body}" diff --git a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConsumersTab.java b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConsumersTab.java index fc2ea985d452..2dc2071ab825 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConsumersTab.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConsumersTab.java @@ -16,6 +16,8 @@ */ package org.apache.camel.dsl.jbang.core.commands.tui; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -100,7 +102,7 @@ class ConsumersTab implements MonitorTab { : Style.EMPTY.fg(Color.LIGHT_RED)); String statusText = healthDown ? "⚠ " + status : status; String type = consumerType(ci); - String period = consumerPeriod(ci); + String schedule = consumerSchedule(ci); String sinceLast = consumerSinceLast(ci); String uri = healthDown && hc.message != null ? hc.message @@ -112,7 +114,7 @@ class ConsumersTab implements MonitorTab { Cell.from(type), rightCell(String.valueOf(ci.inflight), 8), rightCell(ci.totalCounter != null ? String.valueOf(ci.totalCounter) : "", 8), - rightCell(period, 10), + Cell.from(schedule), Cell.from(sinceLast), Cell.from(Span.styled(uri, healthDown ? Style.EMPTY.fg(Color.LIGHT_RED) : Style.EMPTY)))); } @@ -132,16 +134,16 @@ class ConsumersTab implements MonitorTab { Cell.from(Span.styled(sortLabel("TYPE", "type"), sortStyle("type"))), rightCell(sortLabel("INFLIGHT", "inflight"), 8, sortStyle("inflight")), rightCell(sortLabel("POLLS", "polls"), 8, sortStyle("polls")), - rightCell("PERIOD", 10, Style.EMPTY.bold()), + Cell.from(Span.styled("SCHEDULE", Style.EMPTY.bold())), Cell.from(Span.styled("SINCE-LAST", Style.EMPTY.bold())), Cell.from(Span.styled(sortLabel("URI", "uri"), sortStyle("uri"))))) .widths( Constraint.length(20), Constraint.length(10), - Constraint.length(20), + Constraint.length(16), Constraint.length(8), Constraint.length(8), - Constraint.length(10), + Constraint.length(22), Constraint.length(22), Constraint.fill()) .block(Block.builder().borderType(BorderType.ROUNDED) @@ -230,15 +232,84 @@ class ConsumersTab implements MonitorTab { return null; } - private static String consumerPeriod(ConsumerInfo ci) { - if (ci.period != null) { - return ci.period + "ms"; - } else if (ci.delay != null) { - return ci.delay + "ms"; + static String consumerSchedule(ConsumerInfo ci) { + // Try to extract cron expression from URI for cron/quartz components + String cron = extractCronFromUri(ci.uri); + if (cron != null) { + return cron; + } + // Fall back to period/delay for timer and poll consumers + if (ci.period != null && ci.period > 0) { + return "every " + humanDuration(ci.period); + } else if (ci.delay != null && ci.delay > 0) { + return "every " + humanDuration(ci.delay); } return ""; } + private static String extractCronFromUri(String uri) { + if (uri == null) { + return null; + } + // cron:name?schedule=0/5+*+*+*+*+? + if (uri.startsWith("cron:")) { + String expr = extractParam(uri, "schedule"); + if (expr != null) { + return decodeCron(expr); + } + } + // quartz:group/name?cron=0/5+*+*+*+*+? + if (uri.startsWith("quartz:")) { + String expr = extractParam(uri, "cron"); + if (expr != null) { + return decodeCron(expr); + } + String trigger = extractParam(uri, "trigger.repeatInterval"); + if (trigger != null) { + try { + return "every " + humanDuration(Long.parseLong(trigger)); + } catch (NumberFormatException e) { + // ignore + } + } + } + return null; + } + + private static String extractParam(String uri, String param) { + int q = uri.indexOf('?'); + if (q < 0) { + return null; + } + String query = uri.substring(q + 1); + for (String part : query.split("&")) { + if (part.startsWith(param + "=")) { + return part.substring(param.length() + 1); + } + } + return null; + } + + private static String decodeCron(String encoded) { + try { + return URLDecoder.decode(encoded, StandardCharsets.UTF_8); + } catch (Exception e) { + return encoded.replace('+', ' '); + } + } + + private static String humanDuration(long ms) { + if (ms >= 60000 && ms % 60000 == 0) { + long min = ms / 60000; + return min + (min == 1 ? "min" : "min"); + } + if (ms >= 1000 && ms % 1000 == 0) { + long sec = ms / 1000; + return sec + "s"; + } + return ms + "ms"; + } + private static String consumerSinceLast(ConsumerInfo ci) { String s1 = ci.sinceLastStarted != null ? ci.sinceLastStarted : "-"; String s2 = ci.sinceLastCompleted != null ? ci.sinceLastCompleted : "-";
