You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2025/01/21 09:57:07 UTC
(camel) branch ws created (now 350fa11f9c8)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a change to branch ws
in repository https://gitbox.apache.org/repos/asf/camel.git
at 350fa11f9c8 CAMEL-21637: camel-jbang - Commands in watch mode should wait for user input to exit which makes them also work in shell mode.
This branch includes the following new commits:
new 350fa11f9c8 CAMEL-21637: camel-jbang - Commands in watch mode should wait for user input to exit which makes them also work in shell mode.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(camel) 01/01: CAMEL-21637: camel-jbang - Commands in watch mode should wait for user input to exit which makes them also work in shell mode.
Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch ws
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 350fa11f9c8bdd0a23d8656df4a6185d0927c16f
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jan 21 10:56:48 2025 +0100
CAMEL-21637: camel-jbang - Commands in watch mode should wait for user input to exit which makes them also work in shell mode.
---
.../dsl/jbang/core/commands/CamelCommand.java | 2 +-
.../dsl/jbang/core/commands/CommandHelper.java | 25 +++++++++++++++++++---
.../camel/dsl/jbang/core/commands/Shell.java | 15 ++++++++-----
.../core/commands/action/ActionWatchCommand.java | 23 ++++++++++++++++++--
.../jbang/core/commands/action/CamelLogAction.java | 14 ++++++++++--
.../core/commands/action/CamelReceiveAction.java | 16 +++++++++++---
.../core/commands/action/CamelTraceAction.java | 14 ++++++++++--
.../core/commands/process/ProcessWatchCommand.java | 23 ++++++++++++++++++--
8 files changed, 112 insertions(+), 20 deletions(-)
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java
index 7667dbefc4b..188c9abd295 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelCommand.java
@@ -123,7 +123,7 @@ public abstract class CamelCommand implements Callable<Integer> {
protected Printer printer() {
var out = getMain().getOut();
- CommandHelper.SetPrinter(out);
+ CommandHelper.setPrinter(out);
return out;
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CommandHelper.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CommandHelper.java
index 464e2e9019a..c14cf3bfc24 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CommandHelper.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CommandHelper.java
@@ -23,16 +23,16 @@ import org.apache.camel.util.FileUtil;
public final class CommandHelper {
- private static ThreadLocal<Printer> printerAssociation = new ThreadLocal<>();
+ private static final ThreadLocal<Printer> printerAssociation = new ThreadLocal<>();
private CommandHelper() {
}
- public static Printer GetPrinter() {
+ public static Printer getPrinter() {
return printerAssociation.get();
}
- public static void SetPrinter(Printer out) {
+ public static void setPrinter(Printer out) {
printerAssociation.set(out);
}
@@ -53,4 +53,23 @@ public final class CommandHelper {
}
}
}
+
+ /**
+ * A background task that reads from console, and can be used to signal when user has entered or pressed ctrl + c /
+ * ctrl + d
+ */
+ public static class ReadConsoleTask implements Runnable {
+
+ private final Runnable listener;
+
+ public ReadConsoleTask(Runnable listener) {
+ this.listener = listener;
+ }
+
+ @Override
+ public void run() {
+ System.console().readLine();
+ listener.run();
+ }
+ }
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Shell.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Shell.java
index 9add8063153..f3c95a1563b 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Shell.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Shell.java
@@ -42,7 +42,7 @@ import picocli.shell.jline3.PicocliCommands;
@CommandLine.Command(name = "shell",
description = "Interactive Camel JBang shell. Hit @|magenta <TAB>|@ to see available commands.",
- footer = "Press Ctrl-D to exit.")
+ footer = "Press Ctrl-C to exit.")
public class Shell extends CamelCommand {
public Shell(CamelJBangMain main) {
@@ -86,17 +86,22 @@ public class Shell extends CamelCommand {
String prompt = "camel> ";
String rightPrompt = null;
- // start the shell and process input until the user quits with Ctrl-D
+ // start the shell and process input until the user quits with Ctrl-C or Ctrl-D
String line;
- while (true) {
+ boolean run = true;
+ while (run) {
try {
systemRegistry.cleanUp();
line = reader.readLine(prompt, rightPrompt, (MaskingCallback) null, null);
systemRegistry.execute(line);
+ } catch (SystemRegistryImpl.UnknownCommandException e) {
+ // ignore
} catch (UserInterruptException e) {
- // Ignore
+ // ctrl + c is pressed so exit
+ run = false;
} catch (EndOfFileException e) {
- break;
+ // ctrl + d is pressed so exit
+ run = false;
} catch (Exception e) {
systemRegistry.trace(e);
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionWatchCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionWatchCommand.java
index 0e979c4df96..ae1baebd033 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionWatchCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionWatchCommand.java
@@ -16,7 +16,11 @@
*/
package org.apache.camel.dsl.jbang.core.commands.action;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.commands.CommandHelper;
+import org.apache.camel.util.StopWatch;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.AnsiConsole;
import picocli.CommandLine;
@@ -27,6 +31,8 @@ abstract class ActionWatchCommand extends ActionBaseCommand {
description = "Execute periodically and showing output fullscreen")
boolean watch;
+ private CommandHelper.ReadConsoleTask waitUserTask;
+
public ActionWatchCommand(CamelJBangMain main) {
super(main);
}
@@ -34,14 +40,27 @@ abstract class ActionWatchCommand extends ActionBaseCommand {
@Override
public Integer doCall() throws Exception {
int exit;
+ final AtomicBoolean running = new AtomicBoolean(true);
if (watch) {
+ Thread t = new Thread(() -> {
+ waitUserTask = new CommandHelper.ReadConsoleTask(() -> running.set(false));
+ waitUserTask.run();
+ }, "WaitForUser");
+ t.start();
do {
exit = doWatchCall();
if (exit == 0) {
// use 2-sec delay in watch mode
- Thread.sleep(2000);
+ try {
+ StopWatch watch = new StopWatch();
+ while (running.get() && watch.taken() < 2000) {
+ Thread.sleep(100);
+ }
+ } catch (Exception e) {
+ running.set(false);
+ }
}
- } while (exit == 0);
+ } while (exit == 0 && running.get());
} else {
exit = doWatchCall();
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
index 31b282c6eef..e390af4cf48 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
@@ -34,10 +34,12 @@ import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import org.apache.camel.catalog.impl.TimePatternConverter;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.commands.CommandHelper;
import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
import org.apache.camel.dsl.jbang.core.common.ProcessHelper;
import org.apache.camel.util.StopWatch;
@@ -56,6 +58,8 @@ public class CamelLogAction extends ActionBaseCommand {
private static final String TIMESTAMP_MAIN = "yyyy-MM-dd HH:mm:ss.SSS";
+ private CommandHelper.ReadConsoleTask waitUserTask;
+
public static class PrefixCompletionCandidates implements Iterable<String> {
public PrefixCompletionCandidates() {
@@ -78,7 +82,7 @@ public class CamelLogAction extends ActionBaseCommand {
boolean timestamp = true;
@CommandLine.Option(names = { "--follow" }, defaultValue = "true",
- description = "Keep following and outputting new log lines (use ctrl + c to exit).")
+ description = "Keep following and outputting new log lines (press enter to exit).")
boolean follow = true;
@CommandLine.Option(names = { "--startup" }, defaultValue = "false",
@@ -165,6 +169,12 @@ public class CamelLogAction extends ActionBaseCommand {
if (follow) {
boolean waitMessage = true;
+ final AtomicBoolean running = new AtomicBoolean(true);
+ Thread t = new Thread(() -> {
+ waitUserTask = new CommandHelper.ReadConsoleTask(() -> running.set(false));
+ waitUserTask.run();
+ }, "WaitForUser");
+ t.start();
StopWatch watch = new StopWatch();
do {
if (rows.isEmpty()) {
@@ -188,7 +198,7 @@ public class CamelLogAction extends ActionBaseCommand {
Thread.sleep(100);
}
}
- } while (true);
+ } while (running.get());
}
return 0;
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java
index 237555fc1e2..3e1cb212840 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java
@@ -33,6 +33,7 @@ import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import com.github.freva.asciitable.AsciiTable;
@@ -41,6 +42,7 @@ import com.github.freva.asciitable.HorizontalAlign;
import com.github.freva.asciitable.OverflowBehaviour;
import org.apache.camel.catalog.impl.TimePatternConverter;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.commands.CommandHelper;
import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates;
import org.apache.camel.dsl.jbang.core.common.ProcessHelper;
import org.apache.camel.util.FileUtil;
@@ -63,6 +65,8 @@ public class CamelReceiveAction extends ActionBaseCommand {
private static final int NAME_MAX_WIDTH = 25;
private static final int NAME_MIN_WIDTH = 10;
+ private CommandHelper.ReadConsoleTask waitUserTask;
+
public static class PrefixCompletionCandidates implements Iterable<String> {
public PrefixCompletionCandidates() {
@@ -102,7 +106,7 @@ public class CamelReceiveAction extends ActionBaseCommand {
String sort;
@CommandLine.Option(names = { "--follow" }, defaultValue = "true",
- description = "Keep following and outputting new messages (use ctrl + c to exit).")
+ description = "Keep following and outputting new messages (press enter to exit).")
boolean follow = true;
@CommandLine.Option(names = { "--prefix" }, defaultValue = "auto",
@@ -393,9 +397,15 @@ public class CamelReceiveAction extends ActionBaseCommand {
if (follow) {
boolean waitMessage = true;
- StopWatch watch = new StopWatch();
+ final AtomicBoolean running = new AtomicBoolean(true);
+ Thread t = new Thread(() -> {
+ waitUserTask = new CommandHelper.ReadConsoleTask(() -> running.set(false));
+ waitUserTask.run();
+ }, "WaitForUser");
+ t.start();
boolean more = true;
boolean init = true;
+ StopWatch watch = new StopWatch();
do {
if (pids.isEmpty()) {
if (waitMessage) {
@@ -425,7 +435,7 @@ public class CamelReceiveAction extends ActionBaseCommand {
break;
}
}
- } while (more);
+ } while (more && running.get());
}
return 0;
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelTraceAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelTraceAction.java
index 61a08e4ef78..859efc1ce49 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelTraceAction.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelTraceAction.java
@@ -34,6 +34,7 @@ import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
import com.github.freva.asciitable.AsciiTable;
@@ -42,6 +43,7 @@ import com.github.freva.asciitable.HorizontalAlign;
import com.github.freva.asciitable.OverflowBehaviour;
import org.apache.camel.catalog.impl.TimePatternConverter;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.commands.CommandHelper;
import org.apache.camel.dsl.jbang.core.common.PidNameAgeCompletionCandidates;
import org.apache.camel.dsl.jbang.core.common.ProcessHelper;
import org.apache.camel.util.IOHelper;
@@ -64,6 +66,8 @@ public class CamelTraceAction extends ActionBaseCommand {
private static final int NAME_MAX_WIDTH = 25;
private static final int NAME_MIN_WIDTH = 10;
+ private CommandHelper.ReadConsoleTask waitUserTask;
+
public static class PrefixCompletionCandidates implements Iterable<String> {
public PrefixCompletionCandidates() {
@@ -107,7 +111,7 @@ public class CamelTraceAction extends ActionBaseCommand {
boolean ago;
@CommandLine.Option(names = { "--follow" }, defaultValue = "true",
- description = "Keep following and outputting new traces (use ctrl + c to exit).")
+ description = "Keep following and outputting new traces (press enter to exit).")
boolean follow = true;
@CommandLine.Option(names = { "--prefix" }, defaultValue = "auto", completionCandidates = PrefixCompletionCandidates.class,
@@ -376,7 +380,13 @@ public class CamelTraceAction extends ActionBaseCommand {
if (follow) {
boolean waitMessage = true;
+ final AtomicBoolean running = new AtomicBoolean(true);
StopWatch watch = new StopWatch();
+ Thread t = new Thread(() -> {
+ waitUserTask = new CommandHelper.ReadConsoleTask(() -> running.set(false));
+ waitUserTask.run();
+ }, "WaitForUser");
+ t.start();
boolean more = true;
do {
if (pids.isEmpty()) {
@@ -402,7 +412,7 @@ public class CamelTraceAction extends ActionBaseCommand {
break;
}
}
- } while (more);
+ } while (more && running.get());
}
return 0;
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessWatchCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessWatchCommand.java
index 5ac45dabdfd..d9559a9f5a1 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessWatchCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ProcessWatchCommand.java
@@ -16,7 +16,11 @@
*/
package org.apache.camel.dsl.jbang.core.commands.process;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.commands.CommandHelper;
+import org.apache.camel.util.StopWatch;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.AnsiConsole;
import picocli.CommandLine;
@@ -30,6 +34,8 @@ abstract class ProcessWatchCommand extends ProcessBaseCommand {
description = "Execute periodically and showing output fullscreen")
boolean watch;
+ private CommandHelper.ReadConsoleTask waitUserTask;
+
public ProcessWatchCommand(CamelJBangMain main) {
super(main);
}
@@ -37,15 +43,28 @@ abstract class ProcessWatchCommand extends ProcessBaseCommand {
@Override
public Integer doCall() throws Exception {
int exit;
+ final AtomicBoolean running = new AtomicBoolean(true);
if (watch) {
+ Thread t = new Thread(() -> {
+ waitUserTask = new CommandHelper.ReadConsoleTask(() -> running.set(false));
+ waitUserTask.run();
+ }, "WaitForUser");
+ t.start();
do {
autoClearScreen();
exit = doProcessWatchCall();
if (exit == 0) {
// use 2-sec delay in watch mode
- Thread.sleep(2000);
+ try {
+ StopWatch watch = new StopWatch();
+ while (running.get() && watch.taken() < 2000) {
+ Thread.sleep(100);
+ }
+ } catch (Exception e) {
+ running.set(false);
+ }
}
- } while (exit == 0);
+ } while (exit == 0 && running.get());
} else {
exit = doProcessWatchCall();
}