This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new ef288e71825e camel-java-io - Java DSL dump includes sourceLineNumber
comments for TUI node selection
ef288e71825e is described below
commit ef288e71825e340b1feaf7fd5e3f31d4f4f81e63
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jul 24 15:02:38 2026 +0200
camel-java-io - Java DSL dump includes sourceLineNumber comments for TUI
node selection
camel-jbang - Fix TUI action file IPC race condition and use background
thread pool
Use a dedicated cached thread pool (backgroundExecutor) instead of the
single-threaded TUI scheduler for background tasks, preventing animation
freezes during data loading. Serialize action file IPC with per-PID locks
to prevent concurrent background threads from overwriting each other's
action/output files. Centralize IPC in MonitorContext.executeAction() and
fireAction() methods used by all 18+ tab/popup classes.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---
.../org/apache/camel/spi/ModelToJavaDumper.java | 18 ++++++
.../camel/impl/console/RouteDumpDevConsole.java | 13 ++++-
.../org/apache/camel/java/LwModelToJavaDumper.java | 29 +++++++++-
.../camel/java/out/JavaDslModelWriterSupport.java | 34 ++++++++++-
.../api/management/mbean/ManagedRouteMBean.java | 3 +
.../camel/management/mbean/ManagedRoute.java | 8 ++-
.../dsl/jbang/core/commands/tui/ActionsPopup.java | 8 +--
.../dsl/jbang/core/commands/tui/BeansTab.java | 13 +----
.../dsl/jbang/core/commands/tui/BrowseTab.java | 24 ++------
.../dsl/jbang/core/commands/tui/CamelMonitor.java | 14 ++---
.../dsl/jbang/core/commands/tui/CatalogTab.java | 10 +---
.../dsl/jbang/core/commands/tui/ClasspathTab.java | 13 +----
.../dsl/jbang/core/commands/tui/CveAuditTab.java | 2 +-
.../core/commands/tui/DataRefreshService.java | 13 +----
.../jbang/core/commands/tui/DiagramSupport.java | 27 +--------
.../dsl/jbang/core/commands/tui/DiagramTab.java | 17 +-----
.../jbang/core/commands/tui/DocViewerPopup.java | 7 +--
.../dsl/jbang/core/commands/tui/ErrorsTab.java | 2 +-
.../jbang/core/commands/tui/HeapHistogramTab.java | 22 +-------
.../dsl/jbang/core/commands/tui/HistoryTab.java | 2 +-
.../camel/dsl/jbang/core/commands/tui/HttpTab.java | 14 +----
.../camel/dsl/jbang/core/commands/tui/LogTab.java | 3 +-
.../core/commands/tui/MavenDependenciesTab.java | 4 +-
.../dsl/jbang/core/commands/tui/McpFacade.java | 22 +-------
.../dsl/jbang/core/commands/tui/MemoryLeakTab.java | 65 +++-------------------
.../dsl/jbang/core/commands/tui/MemoryTab.java | 5 +-
.../dsl/jbang/core/commands/tui/MetricsTab.java | 2 +-
.../jbang/core/commands/tui/MonitorContext.java | 35 ++++++++++++
.../dsl/jbang/core/commands/tui/RoutesTab.java | 20 ++-----
.../jbang/core/commands/tui/SendMessagePopup.java | 19 ++-----
.../dsl/jbang/core/commands/tui/SourceViewer.java | 25 ++-------
.../dsl/jbang/core/commands/tui/SqlQueryTab.java | 24 ++------
.../dsl/jbang/core/commands/tui/StartupTab.java | 13 +----
.../dsl/jbang/core/commands/tui/ThreadsTab.java | 13 +----
.../dsl/jbang/core/commands/tui/TuiHelper.java | 8 +--
35 files changed, 208 insertions(+), 343 deletions(-)
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToJavaDumper.java
b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToJavaDumper.java
index 3d76721f7217..7622bdb7de05 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ModelToJavaDumper.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToJavaDumper.java
@@ -68,4 +68,22 @@ public interface ModelToJavaDumper {
boolean resolvePlaceholders, boolean generatedIds)
throws Exception;
+ /**
+ * Dumps the definition as Java DSL
+ *
+ * @param context the CamelContext
+ * @param definition the definition, such as a {@link NamedNode}
+ * @param resolvePlaceholders whether to resolve property placeholders in
the dumped Java DSL
+ * @param generatedIds whether to include auto generated IDs
+ * @param sourceLocation whether to include source location
information as comments
+ * @return the output in Java DSL (is formatted)
+ * @throws Exception is throw if error marshalling to Java DSL
+ */
+ default String dumpModelAsJava(
+ CamelContext context, NamedNode definition,
+ boolean resolvePlaceholders, boolean generatedIds, boolean
sourceLocation)
+ throws Exception {
+ return dumpModelAsJava(context, definition, resolvePlaceholders,
generatedIds);
+ }
+
}
diff --git
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
index 3d4447d9b4cf..fb42ea5e9ea7 100644
---
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
+++
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
@@ -132,7 +132,7 @@ public class RouteDumpDevConsole extends AbstractDevConsole
{
dump = mrb.dumpRouteAsYaml(true, uriAsParameters, false,
true);
} else if ("java".equals(format)) {
jo.put("format", "java");
- dump = mrb.dumpRouteAsJava(true, false);
+ dump = mrb.dumpRouteAsJava(true, false, true);
}
if (dump != null) {
JsonArray code;
@@ -261,6 +261,17 @@ public class RouteDumpDevConsole extends
AbstractDevConsole {
// ignore
}
+ // merge trailing ; with previous code line (sourceLineNumber comments
may have separated them)
+ if (code.size() > 1) {
+ JsonObject last = (JsonObject) code.get(code.size() - 1);
+ String lastCode = Jsoner.unescape(last.getString("code")).trim();
+ if (";".equals(lastCode)) {
+ code.remove(code.size() - 1);
+ JsonObject prev = (JsonObject) code.get(code.size() - 1);
+ prev.put("code", prev.getString("code") + ";");
+ }
+ }
+
return code.isEmpty() ? null : code;
}
diff --git
a/core/camel-java-io/src/main/java/org/apache/camel/java/LwModelToJavaDumper.java
b/core/camel-java-io/src/main/java/org/apache/camel/java/LwModelToJavaDumper.java
index e2e4131f829d..2ca544b1c848 100644
---
a/core/camel-java-io/src/main/java/org/apache/camel/java/LwModelToJavaDumper.java
+++
b/core/camel-java-io/src/main/java/org/apache/camel/java/LwModelToJavaDumper.java
@@ -62,6 +62,14 @@ public class LwModelToJavaDumper implements
ModelToJavaDumper {
CamelContext context, NamedNode definition,
boolean resolvePlaceholders, boolean generatedIds)
throws Exception {
+ return dumpModelAsJava(context, definition, resolvePlaceholders,
generatedIds, false);
+ }
+
+ @Override
+ public String dumpModelAsJava(
+ CamelContext context, NamedNode definition,
+ boolean resolvePlaceholders, boolean generatedIds, boolean
sourceLocation)
+ throws Exception {
Properties properties = new Properties();
List<Runnable> restorers = new ArrayList<>();
@@ -79,7 +87,9 @@ public class LwModelToJavaDumper implements ModelToJavaDumper
{
restorers.add(resolveEndpointDslUris(route));
}
- org.apache.camel.java.out.JavaDslModelWriter writer = new
org.apache.camel.java.out.JavaDslModelWriter();
+ org.apache.camel.java.out.JavaDslModelWriter writer =
createWriter(sourceLocation);
+ writer.setGeneratedIds(generatedIds);
+ writer.setSourceLocation(sourceLocation);
StringBuilder sb = new StringBuilder();
try {
@@ -148,6 +158,23 @@ public class LwModelToJavaDumper implements
ModelToJavaDumper {
return result;
}
+ private static org.apache.camel.java.out.JavaDslModelWriter
createWriter(boolean sourceLocation) {
+ if (!sourceLocation) {
+ return new org.apache.camel.java.out.JavaDslModelWriter();
+ }
+ return new org.apache.camel.java.out.JavaDslModelWriter() {
+ @Override
+ protected void doWriteOptionalIdentifiedDefinitionAttributes(
+ StringBuilder sb,
org.apache.camel.model.OptionalIdentifiedDefinition<?> def) {
+ int line = (def instanceof RouteDefinition rd ? rd.getInput()
: def).getLineNumber();
+ if (line != -1) {
+ sb.append("\n// sourceLineNumber: ").append(line);
+ }
+ super.doWriteOptionalIdentifiedDefinitionAttributes(sb, def);
+ }
+ };
+ }
+
private static void collectTemplateProperties(RouteTemplateDefinition
template, Properties properties) {
if (Boolean.TRUE.equals(template.getRoute().isTemplate())) {
java.util.Map<String, Object> parameters =
template.getRoute().getTemplateParameters();
diff --git
a/core/camel-java-io/src/main/java/org/apache/camel/java/out/JavaDslModelWriterSupport.java
b/core/camel-java-io/src/main/java/org/apache/camel/java/out/JavaDslModelWriterSupport.java
index 57b6a51df69a..11ab52312bec 100644
---
a/core/camel-java-io/src/main/java/org/apache/camel/java/out/JavaDslModelWriterSupport.java
+++
b/core/camel-java-io/src/main/java/org/apache/camel/java/out/JavaDslModelWriterSupport.java
@@ -152,10 +152,25 @@ public abstract class JavaDslModelWriterSupport {
private boolean inDataFormatBuilder;
private boolean inSubBuilder;
private boolean inRestParam;
+ private boolean generatedIds;
+ private boolean sourceLocation;
+ private boolean currentNodeCustomId;
protected int indentLevel = 1;
protected final Set<String> handledAttributes = new HashSet<>();
+ public void setGeneratedIds(boolean generatedIds) {
+ this.generatedIds = generatedIds;
+ }
+
+ public void setSourceLocation(boolean sourceLocation) {
+ this.sourceLocation = sourceLocation;
+ }
+
+ public boolean isSourceLocation() {
+ return sourceLocation;
+ }
+
protected void resetState() {
indentLevel = 1;
handledAttributes.clear();
@@ -186,13 +201,19 @@ public abstract class JavaDslModelWriterSupport {
if (def.getInput() != null) {
sb.append("from(").append(quote(def.getInput().getUri())).append(")");
+ if (sourceLocation) {
+ int line = def.getInput().getLineNumber();
+ if (line != -1) {
+ sb.append(NL).append("// sourceLineNumber: ").append(line);
+ }
+ }
}
handledAttributes.add("input");
handledAttributes.add("uri");
- if (def.getId() != null) {
+ if (def.getId() != null && (generatedIds ||
Boolean.TRUE.equals(def.getCustomId()))) {
sb.append(NL).append(indent()).append(".routeId(").append(quote(def.getId())).append(")");
- handledAttributes.add("id");
}
+ handledAttributes.add("id");
handledAttributes.add("customId");
if (def.getRouteProperties() != null) {
for (PropertyDefinition prop : def.getRouteProperties()) {
@@ -206,6 +227,9 @@ public abstract class JavaDslModelWriterSupport {
indentLevel--;
doWriteRouteDefinition(sb, def);
indentLevel++;
+ if (sourceLocation) {
+ sb.append(NL);
+ }
sb.append(";");
}
@@ -482,6 +506,12 @@ public abstract class JavaDslModelWriterSupport {
protected void doWriteAttribute(StringBuilder sb, String key, String
value, String defaultValue) {
if (value == null || handledAttributes.contains(key) ||
SKIP_ATTRIBUTES.contains(key)) {
+ if ("customId".equals(key)) {
+ currentNodeCustomId = "true".equals(value);
+ }
+ return;
+ }
+ if ("id".equals(key) && !generatedIds && !currentNodeCustomId) {
return;
}
if (defaultValue != null && defaultValue.equals(value)) {
diff --git
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
index 90473b64a932..aced2e336c66 100644
---
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
+++
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
@@ -161,6 +161,9 @@ public interface ManagedRouteMBean extends
ManagedPerformanceCounterMBean {
@ManagedOperation(description = "Dumps the route as Java DSL")
String dumpRouteAsJava(boolean resolvePlaceholders, boolean generatedIds)
throws Exception;
+ @ManagedOperation(description = "Dumps the route as Java DSL")
+ String dumpRouteAsJava(boolean resolvePlaceholders, boolean generatedIds,
boolean sourceLocation) throws Exception;
+
@ManagedOperation(description = "Dumps the route stats as XML")
String dumpRouteStatsAsXml(boolean fullStats, boolean includeProcessors)
throws Exception;
diff --git
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
index e64d74cd4882..49775a6e3976 100644
---
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
+++
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
@@ -496,11 +496,17 @@ public class ManagedRoute extends
ManagedPerformanceCounter implements ManagedRo
@Override
public String dumpRouteAsJava(boolean resolvePlaceholders, boolean
generatedIds) throws Exception {
+ return dumpRouteAsJava(resolvePlaceholders, generatedIds, false);
+ }
+
+ @Override
+ public String dumpRouteAsJava(boolean resolvePlaceholders, boolean
generatedIds, boolean sourceLocation)
+ throws Exception {
String id = route.getId();
RouteDefinition def =
context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinition(id);
if (def != null) {
return
PluginHelper.getModelToJavaDumper(context).dumpModelAsJava(context, def,
resolvePlaceholders,
- generatedIds);
+ generatedIds, sourceLocation);
}
return null;
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
index 06005dc5b830..dc4a1e8d4c79 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
@@ -20,7 +20,6 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.ScheduledExecutorService;
import java.util.function.BiConsumer;
import java.util.function.IntPredicate;
import java.util.function.Supplier;
@@ -130,7 +129,6 @@ class ActionsPopup {
private final SendMessagePopup sendMessagePopup = new SendMessagePopup();
private final StopAllPopup stopAllPopup;
private final CaptionOverlay captionOverlay;
- private ScheduledExecutorService scheduler;
private final LaunchManager launchManager;
private BiConsumer<String, Boolean> notificationCallback;
@@ -176,10 +174,6 @@ class ActionsPopup {
return launchManager;
}
- void setScheduler(ScheduledExecutorService scheduler) {
- this.scheduler = scheduler;
- }
-
void setPreSelectedRouteId(String routeId) {
this.preSelectedRouteId = routeId;
}
@@ -487,7 +481,7 @@ class ActionsPopup {
boolean handleKeyEvent(KeyEvent ke) {
if (sendMessagePopup.isVisible()) {
if (ke.isKey(KeyCode.F5) && !sendFileBrowser.isVisible()) {
- sendMessagePopup.doSend(ctx, scheduler);
+ sendMessagePopup.doSend(ctx, ctx.backgroundExecutor);
} else {
sendMessagePopup.handleKeyEvent(ke);
}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BeansTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BeansTab.java
index 39248fcdfd19..6ff0dde6a8c4 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BeansTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BeansTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -41,7 +40,6 @@ import dev.tamboui.widgets.paragraph.Paragraph;
import dev.tamboui.widgets.table.Cell;
import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -390,7 +388,7 @@ class BeansTab extends AbstractTableTab {
return;
}
String pid = ctx.selectedPid;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
loadBeansInBackground(pid);
} finally {
@@ -400,20 +398,13 @@ class BeansTab extends AbstractTableTab {
}
private void loadBeansInBackground(String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "bean");
root.put("properties", true);
root.put("nulls", true);
root.put("internal", true);
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
return;
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BrowseTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BrowseTab.java
index cd1d621c246c..52ba8db3713f 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BrowseTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/BrowseTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
@@ -49,7 +48,6 @@ import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
import dev.tamboui.widgets.table.TableState;
import org.apache.camel.dsl.jbang.core.common.CamelCommandHelper;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -534,7 +532,7 @@ class BrowseTab extends AbstractTab {
return;
}
String pid = ctx.selectedPid;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
loadEndpointsInBackground(pid);
} finally {
@@ -544,20 +542,13 @@ class BrowseTab extends AbstractTab {
}
private void loadEndpointsInBackground(String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "browse");
root.put("filter", "*");
root.put("limit", 100);
root.put("dump", false);
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
return;
@@ -595,7 +586,7 @@ class BrowseTab extends AbstractTab {
return;
}
String pid = ctx.selectedPid;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
loadMessagesInBackground(pid, endpointUri);
} finally {
@@ -605,9 +596,6 @@ class BrowseTab extends AbstractTab {
}
private void loadMessagesInBackground(String pid, String endpointUri) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "browse");
root.put("filter", endpointUri);
@@ -615,11 +603,7 @@ class BrowseTab extends AbstractTab {
root.put("dump", true);
root.put("includeBody", true);
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
return;
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
index 7dc8be3d826c..7d4477a05f3a 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
@@ -500,7 +500,6 @@ public class CamelMonitor extends CamelCommand {
this.runner = tui;
aiPanel.setExitCallbackForTestingOrRuntime(tui::quit);
ctx.runner = tui;
- actionsPopup.setScheduler(tui.scheduler());
actionsPopup.setResetScreenAction(() -> tui.terminal().clear());
actionsPopup.setThemeRefreshAction(() -> tui.terminal().clear());
actionsPopup.setClearScreenAction(() -> tui.terminal().clear());
@@ -521,6 +520,7 @@ public class CamelMonitor extends CamelCommand {
} finally {
shellPanel.destroy();
aiPanel.destroy();
+ ctx.backgroundExecutor.shutdownNow();
if (mcpServer != null) {
mcpServer.stop();
}
@@ -1759,9 +1759,11 @@ public class CamelMonitor extends CamelCommand {
ph.destroy();
setNotification("Restarting: " + name, false);
- // re-launch in background after process terminates
+ // re-launch in background after process terminates (use the
background executor
+ // instead of runner.scheduler() — the scheduler is single-threaded
and generates
+ // tick events; blocking it would freeze the notification wave
animation)
if (runner != null) {
- runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
// wait for termination (max 10 seconds, then force kill)
CompletableFuture<ProcessHandle> exitFuture =
ph.onExit().toCompletableFuture();
@@ -1851,8 +1853,7 @@ public class CamelMonitor extends CamelCommand {
String pid = info.pid;
JsonObject root = new JsonObject();
root.put("action", "reset-stats");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
+ ctx.fireAction(pid, root);
dataService.metrics().resetStats(pid);
info.activity = List.of();
@@ -1898,8 +1899,7 @@ public class CamelMonitor extends CamelCommand {
root.put("action", "route");
root.put("id", routeId);
root.put("command", command);
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
+ ctx.fireAction(pid, root);
}
private void renderFooter(Frame frame, Rect area) {
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
index 6c34acfb0ed6..9b412effeec8 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CatalogTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -44,7 +43,6 @@ import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.dsl.jbang.core.common.CatalogLoader;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.tooling.model.ArtifactModel;
import org.apache.camel.tooling.model.EipModel;
import org.apache.camel.util.json.JsonArray;
@@ -462,7 +460,7 @@ class CatalogTab extends AbstractTableTab {
}
boolean full = fullCatalog;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
Set<String> appArtifacts = null;
if (!full) {
@@ -554,18 +552,14 @@ class CatalogTab extends AbstractTableTab {
eipNames = new HashSet<>(catalog.findModelNames());
} else {
eipNames = new HashSet<>();
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
JsonObject root = new JsonObject();
root.put("action", "route-structure");
root.put("filter", "*");
root.put("brief", true);
root.put("metric", false);
- PathUtils.writeTextSafely(root.toJson(),
ctx.getActionFile(pid));
- JsonObject jo = TuiHelper.pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
return;
}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java
index 1df66be3e012..43bee09c26db 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ClasspathTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -43,7 +42,6 @@ import dev.tamboui.widgets.list.ScrollMode;
import dev.tamboui.widgets.paragraph.Paragraph;
import dev.tamboui.widgets.scrollbar.Scrollbar;
import dev.tamboui.widgets.scrollbar.ScrollbarState;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -302,19 +300,12 @@ class ClasspathTab extends AbstractTab {
}
String pid = ctx.selectedPid;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject action = new JsonObject();
action.put("action", "jvm");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(action.toJson(), actionFile);
-
- JsonObject response = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject response = ctx.executeAction(pid, action, 5000);
if (response == null) {
applyResult(Collections.emptyList(), "No response from
integration");
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
index 201bbaac1b4d..9e4bc931196e 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CveAuditTab.java
@@ -384,7 +384,7 @@ class CveAuditTab extends AbstractTableTab {
return;
}
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
DependencyLoader.LoadResult loadResult =
DependencyLoader.loadDependencies(info);
if (loadResult.error() != null &&
loadResult.entries().isEmpty()) {
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java
index b4396dbec667..bb635f6b27ad 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DataRefreshService.java
@@ -35,7 +35,6 @@ import java.util.stream.Collectors;
import dev.tamboui.tui.TuiRunner;
import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
import org.apache.camel.util.json.Jsoner;
@@ -186,7 +185,7 @@ class DataRefreshService {
return;
}
lastRefresh = System.currentTimeMillis();
- runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
refreshSync(logRefresher, conditionalRefresher);
} finally {
@@ -564,19 +563,12 @@ class DataRefreshService {
return;
}
try {
- // Send action to request span data
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject action = new JsonObject();
action.put("action", "span");
action.put("dump", "true");
action.put("limit", "500");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(action.toJson(), actionFile);
- // Poll for response
- JsonObject response = TuiHelper.pollJsonResponse(outputFile, 3000);
+ JsonObject response = ctx.executeAction(pid, action, 3000);
if (response != null) {
Boolean enabled = response.getBoolean("enabled");
if (enabled != null && enabled) {
@@ -590,7 +582,6 @@ class DataRefreshService {
otelSpans.set(entries);
}
}
- PathUtils.deleteFile(outputFile);
}
} catch (Exception e) {
// ignore
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 fa384ed5fd64..1bfb200729fc 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
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
@@ -59,7 +58,6 @@ import
org.apache.camel.diagram.TopologyLayoutEngine.TopologyLayoutEdge;
import org.apache.camel.diagram.TopologyLayoutEngine.TopologyLayoutNode;
import org.apache.camel.diagram.TopologyLayoutEngine.TopologyLayoutResult;
import org.apache.camel.diagram.TopologyLayoutEngine.TopologyNodeInfo;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -547,7 +545,7 @@ class DiagramSupport {
}
preloading = true;
if (ctx.runner != null) {
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
setTopologyMode(true);
loadAllDiagramsInBackground(ctx, pid, false, 0);
@@ -2029,42 +2027,23 @@ class DiagramSupport {
}
private JsonObject requestRouteTopology(MonitorContext ctx, String pid,
boolean external, boolean routes) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "route-topology");
root.put("metric", "true");
- // Always request external endpoints so route diagrams can show dashed
borders
root.put("external", "true");
if (routes) {
root.put("routes", "true");
}
-
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
- return jo;
+ return ctx.executeAction(pid, root, 5000);
}
private JsonObject requestRouteStructure(MonitorContext ctx, String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "route-structure");
root.put("filter", "*");
root.put("brief", false);
root.put("metric", true);
-
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
- return jo;
+ return ctx.executeAction(pid, root, 5000);
}
static void addParentNodes(List<RouteDiagramLayoutEngine.NodeInfo> nodes,
Set<String> nodeIds) {
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java
index eb1220176bf6..b2c69a82ce18 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java
@@ -17,7 +17,6 @@
package org.apache.camel.dsl.jbang.core.commands.tui;
import java.net.URISyntaxException;
-import java.nio.file.Path;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
@@ -49,7 +48,6 @@ import dev.tamboui.widgets.block.Borders;
import dev.tamboui.widgets.paragraph.Paragraph;
import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.dsl.jbang.core.common.CatalogLoader;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.tooling.model.BaseOptionModel;
import org.apache.camel.tooling.model.ComponentModel;
import org.apache.camel.tooling.model.EipModel;
@@ -901,7 +899,7 @@ class DiagramTab extends AbstractTab {
diagram.setLoadingPlaceholder();
}
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
diagram.setTopologyMode(topologyMode);
diagram.loadAllDiagramsInBackground(ctx, pid, showMetrics,
external);
@@ -1206,7 +1204,7 @@ class DiagramTab extends AbstractTab {
detailLoading = true;
String rid = drillDownRouteId;
if (ctx.runner != null) {
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
JsonObject result = requestRouteProcessorDetail(rid);
cachedRouteDetail = result;
cachedRouteDetailId = rid;
@@ -1413,19 +1411,10 @@ class DiagramTab extends AbstractTab {
return null;
}
try {
- Path outputFile = ctx.getOutputFile(ctx.selectedPid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "processor-detail");
root.put("routeId", routeId);
-
- Path actionFile = ctx.getActionFile(ctx.selectedPid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
- return jo;
+ return ctx.executeAction(ctx.selectedPid, root, 5000);
} catch (Exception e) {
return null;
}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocViewerPopup.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocViewerPopup.java
index 5d339be97f73..c1b472d2c9c4 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocViewerPopup.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DocViewerPopup.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
@@ -48,7 +47,6 @@ import dev.tamboui.widgets.list.ScrollMode;
import dev.tamboui.widgets.paragraph.Paragraph;
import dev.tamboui.widgets.scrollbar.Scrollbar;
import dev.tamboui.widgets.scrollbar.ScrollbarState;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint;
import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast;
@@ -334,12 +332,9 @@ class DocViewerPopup {
docLines = null;
showPicker = false;
try {
- Path outputFile = ctx.getOutputFile(info.pid);
- Files.deleteIfExists(outputFile);
org.apache.camel.util.json.JsonObject action = new
org.apache.camel.util.json.JsonObject();
action.put("action", "readme");
- PathUtils.writeTextSafely(action.toJson(),
ctx.getActionFile(info.pid));
- org.apache.camel.util.json.JsonObject response =
TuiHelper.pollJsonResponse(outputFile, 5000);
+ org.apache.camel.util.json.JsonObject response =
ctx.executeAction(info.pid, action, 5000);
if (response != null && response.getString("content") != null) {
String raw = response.getString("content");
String file = response.getStringOrDefault("file", "README");
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ErrorsTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ErrorsTab.java
index e24414dbca4a..32df7513bfd1 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ErrorsTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ErrorsTab.java
@@ -761,7 +761,7 @@ class ErrorsTab extends AbstractTableTab {
diagram.setLoadingPlaceholder();
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
diagram.loadHighlightedNativeDiagramInBackground(ctx, pid,
messageHistory, true, -1);
} finally {
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HeapHistogramTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HeapHistogramTab.java
index d5be3b8d700c..469129041b64 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HeapHistogramTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HeapHistogramTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -39,7 +38,6 @@ import dev.tamboui.widgets.paragraph.Paragraph;
import dev.tamboui.widgets.table.Cell;
import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -476,7 +474,7 @@ class HeapHistogramTab extends AbstractTableTab {
return;
}
String pid = ctx.selectedPid;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
loadHeapHistogramInBackground(pid);
} finally {
@@ -486,17 +484,10 @@ class HeapHistogramTab extends AbstractTableTab {
}
private void loadHeapHistogramInBackground(String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "heap-histogram");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
return;
@@ -540,17 +531,10 @@ class HeapHistogramTab extends AbstractTableTab {
}
private List<ClasspathTab.JarEntry> loadClasspathEntries(String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject action = new JsonObject();
action.put("action", "jvm");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(action.toJson(), actionFile);
-
- JsonObject response = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject response = ctx.executeAction(pid, action, 5000);
if (response == null) {
return Collections.emptyList();
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 68a38dcf5d75..fbe5f491ae11 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
@@ -1124,7 +1124,7 @@ class HistoryTab extends AbstractTab {
boolean isFailed = failed;
int step = initialStep;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
diagram.loadHighlightedNativeDiagramInBackground(ctx, pid,
messageHistory, isFailed, step);
} finally {
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HttpTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HttpTab.java
index b2117c1e134a..d6327c8d8b1d 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HttpTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/HttpTab.java
@@ -56,7 +56,6 @@ import dev.tamboui.widgets.table.Cell;
import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
import org.apache.camel.dsl.jbang.core.common.CamelCommandHelper;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -708,7 +707,7 @@ class HttpTab extends AbstractTableTab {
}
List<FormHelper.HeaderEntry> hdrs = headerSnapshot;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
doProbeRequestInBackground(baseUrl, method, path, sendBody,
hdrs);
} finally {
@@ -1429,7 +1428,7 @@ class HttpTab extends AbstractTableTab {
String specUri = ep.specificationUri;
String operationId = ep.operationId;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
loadSpecInBackground(pid, specUri, operationId);
} finally {
@@ -1439,18 +1438,11 @@ class HttpTab extends AbstractTableTab {
}
private void loadSpecInBackground(String pid, String specUri, String
operationId) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "rest-spec");
root.put("filter", specUri);
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
applySpecResult(specUri, List.of("(No response from
integration)"), 0);
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LogTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LogTab.java
index 0f919da3e7ac..c09af0e382c3 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LogTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/LogTab.java
@@ -478,8 +478,7 @@ class LogTab extends AbstractTab {
root.put("command", "set-logging-level");
root.put("logger-name", "root");
root.put("logging-level", level);
- Path actionFile = ctx.getActionFile(pid);
-
org.apache.camel.dsl.jbang.core.common.PathUtils.writeTextSafely(root.toJson(),
actionFile);
+ ctx.fireAction(pid, root);
}
boolean isSearchInputActive() {
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MavenDependenciesTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MavenDependenciesTab.java
index b365db6d3f12..27feb4d7e24a 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MavenDependenciesTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MavenDependenciesTab.java
@@ -351,7 +351,7 @@ class MavenDependenciesTab extends AbstractTableTab {
return;
}
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
DependencyLoader.LoadResult result =
DependencyLoader.loadDependencies(info);
applyResult(result.entries(), result.source(), result.error());
@@ -368,7 +368,7 @@ class MavenDependenciesTab extends AbstractTableTab {
return;
}
transitiveLoading = true;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
List<DependencyLoader.DepEntry> entries =
DependencyLoader.resolveTransitives(allEntries);
applyTransitiveResult(entries);
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java
index 90941b7fdedd..1aef9c262ee7 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/McpFacade.java
@@ -35,7 +35,6 @@ import dev.tamboui.tui.event.KeyCode;
import dev.tamboui.tui.event.KeyEvent;
import dev.tamboui.tui.event.KeyModifiers;
import dev.tamboui.widgets.tabs.TabsState;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.dsl.jbang.core.common.RuntimeHelper;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -463,19 +462,13 @@ class McpFacade {
return err;
}
try {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject action = new JsonObject();
action.put("action", "span");
action.put("dump", "true");
action.put("limit", String.valueOf(limit));
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(action.toJson(), actionFile);
- JsonObject response = TuiHelper.pollJsonResponse(outputFile, 3000);
+ JsonObject response = ctx.executeAction(pid, action, 3000);
if (response != null) {
- PathUtils.deleteFile(outputFile);
Boolean enabled = response.getBoolean("enabled");
if (enabled == null || !enabled) {
JsonObject err = new JsonObject();
@@ -516,17 +509,11 @@ class McpFacade {
return err;
}
try {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject action = new JsonObject();
action.put("action", "processor-detail");
action.put("routeId", routeId != null ? routeId : "*");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(action.toJson(), actionFile);
- JsonObject response = TuiHelper.pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject response = ctx.executeAction(pid, action, 5000);
return response;
} catch (Exception e) {
JsonObject err = new JsonObject();
@@ -720,12 +707,9 @@ class McpFacade {
return null;
}
try {
- Path outputFile = ctx.getOutputFile(target.pid);
- Files.deleteIfExists(outputFile);
JsonObject action = new JsonObject();
action.put("action", "readme");
- PathUtils.writeTextSafely(action.toJson(),
ctx.getActionFile(target.pid));
- return TuiHelper.pollJsonResponse(outputFile, 5000);
+ return ctx.executeAction(target.pid, action, 5000);
} catch (Exception e) {
return null;
}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryLeakTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryLeakTab.java
index 7362a523d83b..4db816e7dde2 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryLeakTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryLeakTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -43,7 +42,6 @@ import dev.tamboui.widgets.table.Cell;
import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
import dev.tamboui.widgets.table.TableState;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -1504,19 +1502,12 @@ class MemoryLeakTab extends AbstractTab {
}
private void sendStartCommand(String pid, int dur) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "jfr-memory-leak");
root.put("command", "start");
root.put("duration", String.valueOf(dur));
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 15000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 15000);
if (jo != null && "recording".equals(jo.getString("status"))) {
if (ctx.runner != null) {
@@ -1584,19 +1575,12 @@ class MemoryLeakTab extends AbstractTab {
}
private boolean sendStopAndLoadResults(String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "jfr-memory-leak");
root.put("command", "stop");
root.put("stacktrace", "true");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 30000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 30000);
if (jo != null && "completed".equals(jo.getString("status"))) {
List<SampleEntry> result = parseSamples(jo);
@@ -1709,35 +1693,21 @@ class MemoryLeakTab extends AbstractTab {
}
private boolean isRecordingActive(String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "jfr-memory-leak");
root.put("command", "status");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
return jo == null || "recording".equals(jo.getString("status"));
}
private void sendStatusCommand(String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "jfr-memory-leak");
root.put("command", "status");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
return;
@@ -1769,19 +1739,12 @@ class MemoryLeakTab extends AbstractTab {
}
private void loadQueryResults(String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "jfr-memory-leak");
root.put("command", "query");
root.put("stacktrace", "true");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 10000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 10000);
if (jo != null && "completed".equals(jo.getString("status"))) {
List<SampleEntry> result = parseSamples(jo);
@@ -1815,19 +1778,12 @@ class MemoryLeakTab extends AbstractTab {
private void sendStopAndLoadComparison(String pid) {
// stop the second recording
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "jfr-memory-leak");
root.put("command", "stop");
root.put("stacktrace", "true");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 30000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 30000);
if (jo == null || !"completed".equals(jo.getString("status"))) {
if (ctx.runner != null) {
@@ -1841,19 +1797,12 @@ class MemoryLeakTab extends AbstractTab {
}
private void loadComparisonResults(String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject cmpRoot = new JsonObject();
cmpRoot.put("action", "jfr-memory-leak");
cmpRoot.put("command", "compare");
cmpRoot.put("stacktrace", "true");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(cmpRoot.toJson(), actionFile);
-
- JsonObject cmpResult = pollJsonResponse(outputFile, 10000);
- PathUtils.deleteFile(outputFile);
+ JsonObject cmpResult = ctx.executeAction(pid, cmpRoot, 10000);
if (cmpResult != null &&
"compared".equals(cmpResult.getString("status"))) {
List<ComparisonEntry> entries = parseComparisons(cmpResult);
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryTab.java
index e683310ecfa4..f100067731c6 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MemoryTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -37,7 +36,6 @@ import dev.tamboui.widgets.block.Block;
import dev.tamboui.widgets.block.BorderType;
import dev.tamboui.widgets.block.Borders;
import dev.tamboui.widgets.paragraph.Paragraph;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.TimeUtils;
import org.apache.camel.util.json.JsonObject;
@@ -459,8 +457,7 @@ class MemoryTab extends AbstractTab {
}
JsonObject root = new JsonObject();
root.put("action", "gc");
- Path actionFile = ctx.getActionFile(info.pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
+ ctx.fireAction(info.pid, root);
}
@Override
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MetricsTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MetricsTab.java
index a2ee8cd1db6e..4ef4cd0da358 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MetricsTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MetricsTab.java
@@ -576,7 +576,7 @@ class MetricsTab extends AbstractTableTab {
}
rawTitle = url;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5))
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContext.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContext.java
index 78a42873521e..2b200b23ddb0 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContext.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/MonitorContext.java
@@ -18,12 +18,17 @@ package org.apache.camel.dsl.jbang.core.commands.tui;
import java.nio.file.Path;
import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import dev.tamboui.tui.TuiRunner;
import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
+import org.apache.camel.dsl.jbang.core.common.PathUtils;
+import org.apache.camel.util.json.JsonObject;
/**
* Shared state accessible to all {@link MonitorTab} implementations.
@@ -33,6 +38,11 @@ class MonitorContext {
final AtomicReference<List<IntegrationInfo>> data;
final AtomicReference<List<InfraInfo>> infraData;
TuiRunner runner;
+ final ExecutorService backgroundExecutor = Executors.newCachedThreadPool(r
-> {
+ Thread t = new Thread(r, "camel-tui-bg");
+ t.setDaemon(true);
+ return t;
+ });
volatile String selectedPid;
volatile String lastSelectedName;
@@ -94,6 +104,31 @@ class MonitorContext {
return "?";
}
+ private final ConcurrentHashMap<String, Object> actionLocks = new
ConcurrentHashMap<>();
+
+ void fireAction(String pid, JsonObject request) {
+ Object lock = actionLocks.computeIfAbsent(pid, k -> new Object());
+ synchronized (lock) {
+ Path actionFile = getActionFile(pid);
+ PathUtils.writeTextSafely(request.toJson(), actionFile);
+ }
+ }
+
+ JsonObject executeAction(String pid, JsonObject request, long timeoutMs) {
+ Object lock = actionLocks.computeIfAbsent(pid, k -> new Object());
+ synchronized (lock) {
+ Path outputFile = getOutputFile(pid);
+ PathUtils.deleteFile(outputFile);
+ Path actionFile = getActionFile(pid);
+ PathUtils.writeTextSafely(request.toJson(), actionFile);
+ try {
+ return TuiHelper.pollJsonResponse(outputFile, timeoutMs);
+ } finally {
+ PathUtils.deleteFile(outputFile);
+ }
+ }
+ }
+
Path getActionFile(String pid) {
return CommandLineHelper.getCamelDir().resolve(pid + "-action.json");
}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RoutesTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RoutesTab.java
index f05948ea43b4..a284cf16c034 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RoutesTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RoutesTab.java
@@ -17,7 +17,6 @@
package org.apache.camel.dsl.jbang.core.commands.tui;
import java.net.URISyntaxException;
-import java.nio.file.Path;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
@@ -54,7 +53,6 @@ import dev.tamboui.widgets.table.Table;
import dev.tamboui.widgets.table.TableState;
import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.dsl.jbang.core.common.CatalogLoader;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.tooling.model.BaseOptionModel;
import org.apache.camel.tooling.model.ComponentModel;
import org.apache.camel.tooling.model.EipModel;
@@ -1604,8 +1602,7 @@ class RoutesTab extends AbstractTab {
root.put("action", "route");
root.put("id", routeId);
root.put("command", command);
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
+ ctx.fireAction(pid, root);
}
// ---- Async loading ----
@@ -1626,7 +1623,7 @@ class RoutesTab extends AbstractTab {
diagram.setLoadingPlaceholder();
}
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
diagram.setTopologyMode(topologyMode);
diagram.loadAllDiagramsInBackground(ctx, pid, showMetrics,
external);
@@ -1816,7 +1813,7 @@ class RoutesTab extends AbstractTab {
detailLoading = true;
String rid = drillDownRouteId;
if (ctx.runner != null) {
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
JsonObject result = requestRouteProcessorDetail(rid);
cachedRouteDetail = result;
cachedRouteDetailId = rid;
@@ -2005,19 +2002,10 @@ class RoutesTab extends AbstractTab {
return null;
}
try {
- Path outputFile = ctx.getOutputFile(ctx.selectedPid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "processor-detail");
root.put("routeId", routeId);
-
- Path actionFile = ctx.getActionFile(ctx.selectedPid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = TuiHelper.pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
- return jo;
+ return ctx.executeAction(ctx.selectedPid, root, 5000);
} catch (Exception e) {
return null;
}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SendMessagePopup.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SendMessagePopup.java
index b08ca2f5d675..3125e4c6cc7e 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SendMessagePopup.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SendMessagePopup.java
@@ -17,12 +17,11 @@
package org.apache.camel.dsl.jbang.core.commands.tui;
import java.io.File;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ExecutorService;
import dev.tamboui.layout.Constraint;
import dev.tamboui.layout.Layout;
@@ -46,7 +45,6 @@ import dev.tamboui.widgets.input.TextInput;
import dev.tamboui.widgets.input.TextInputState;
import dev.tamboui.widgets.paragraph.Paragraph;
import org.apache.camel.dsl.jbang.core.common.CamelCommandHelper;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
import org.apache.camel.util.json.Jsoner;
@@ -484,8 +482,8 @@ class SendMessagePopup {
}
}
- void doSend(MonitorContext ctx, ScheduledExecutorService scheduler) {
- if (!visible || sending || ctx == null || scheduler == null) {
+ void doSend(MonitorContext ctx, ExecutorService executor) {
+ if (!visible || sending || ctx == null || executor == null) {
return;
}
sending = true;
@@ -509,11 +507,8 @@ class SendMessagePopup {
List<FormHelper.HeaderEntry> hdrs = headers != null ? new
ArrayList<>(headers) : null;
String routeId = route.routeId;
- scheduler.execute(() -> {
+ executor.execute(() -> {
try {
- Path outputFile = ctx.getOutputFile(targetPid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "send");
root.put("endpoint", endpoint);
@@ -539,11 +534,7 @@ class SendMessagePopup {
}
}
- Path actionFile = ctx.getActionFile(targetPid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject response = TuiHelper.pollJsonResponse(outputFile,
25000);
- PathUtils.deleteFile(outputFile);
+ JsonObject response = ctx.executeAction(targetPid, root,
25000);
if (response == null) {
applyResult(routeId, sendBody, hdrs, captureInOut,
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
index 505b3dc39a5f..4985cc301b3f 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SourceViewer.java
@@ -46,15 +46,12 @@ import dev.tamboui.widgets.block.Title;
import dev.tamboui.widgets.paragraph.Paragraph;
import dev.tamboui.widgets.scrollbar.Scrollbar;
import dev.tamboui.widgets.scrollbar.ScrollbarState;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.support.LoggerHelper;
import org.apache.camel.util.FileUtil;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
import org.apache.camel.util.json.Jsoner;
-import static
org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.pollJsonResponse;
-
/**
* Reusable source code viewer with syntax highlighting, scrolling, and
line-number display. Can be used by any tab that
* needs to show route source code.
@@ -512,7 +509,7 @@ class SourceViewer {
scrollX = 0;
visible = true;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
loadInBackground(ctx, pid, routeId, targetLine);
} finally {
@@ -561,18 +558,11 @@ class SourceViewer {
}
private void loadInBackground(MonitorContext ctx, String pid, String
routeId, int targetLine) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "source");
root.put("filter", routeId);
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
applyResult(ctx, routeId, null, List.of("(No response from
integration)"), Collections.emptyList(), 0, -1);
@@ -760,7 +750,7 @@ class SourceViewer {
MonitorContext ctx = currentCtx;
String pid = currentPid;
String routeId = currentRouteId;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
if (format.equals(originalFormat)) {
loadInBackground(ctx, pid, routeId, 0);
@@ -774,20 +764,13 @@ class SourceViewer {
}
private void loadFormatInBackground(MonitorContext ctx, String pid, String
routeId, String format) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "route-dump");
root.put("filter", routeId);
root.put("format", format);
root.put("uriAsParameters", "yaml".equals(format) ? "true" : "false");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
applyFormatResult(ctx, format, List.of("(No response from
integration)"), Collections.emptyList());
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlQueryTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlQueryTab.java
index 1f6f8e273e93..8bea8e086eb7 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlQueryTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SqlQueryTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -47,7 +46,6 @@ import dev.tamboui.widgets.table.Cell;
import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
import dev.tamboui.widgets.table.TableState;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -675,11 +673,8 @@ class SqlQueryTab extends AbstractTab {
String savedSql = lastSql;
String savedDs = lastDsName;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
- Path outputFile = ctx.getOutputFile(ctx.selectedPid);
- PathUtils.deleteFile(outputFile);
-
JsonObject action = new JsonObject();
action.put("action", "sql-update-row");
action.put("table", tableName);
@@ -689,11 +684,7 @@ class SqlQueryTab extends AbstractTab {
action.put("primaryKeyValues", pkJson);
action.put("columnValues", colJson);
- Path actionFile = ctx.getActionFile(ctx.selectedPid);
- PathUtils.writeTextSafely(action.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 15000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(ctx.selectedPid, action,
15000);
if (jo == null) {
if (ctx.runner != null) {
@@ -973,7 +964,7 @@ class SqlQueryTab extends AbstractTab {
lastSql = sql;
lastDsName = dsName;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
executeInBackground(pid, sql, dsName);
} finally {
@@ -983,9 +974,6 @@ class SqlQueryTab extends AbstractTab {
}
private void executeInBackground(String pid, String sql, String dsName) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "sql-query");
root.put("sql", sql);
@@ -995,11 +983,7 @@ class SqlQueryTab extends AbstractTab {
root.put("maxRows", 100);
root.put("queryTimeout", 30);
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 35000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 35000);
if (jo == null) {
if (ctx.runner != null) {
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StartupTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StartupTab.java
index 0df04c613750..60d04399d968 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StartupTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/StartupTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -40,7 +39,6 @@ import dev.tamboui.widgets.block.Borders;
import dev.tamboui.widgets.paragraph.Paragraph;
import dev.tamboui.widgets.scrollbar.Scrollbar;
import dev.tamboui.widgets.scrollbar.ScrollbarState;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -270,19 +268,12 @@ class StartupTab extends AbstractTab {
}
String pid = ctx.selectedPid;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "startup-recorder");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
applyResult(Collections.emptyList(), "No response from
integration");
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThreadsTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThreadsTab.java
index 68f087f0d01d..a3333a65d253 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThreadsTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThreadsTab.java
@@ -16,7 +16,6 @@
*/
package org.apache.camel.dsl.jbang.core.commands.tui;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -40,7 +39,6 @@ import dev.tamboui.widgets.paragraph.Paragraph;
import dev.tamboui.widgets.table.Cell;
import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
@@ -331,7 +329,7 @@ class ThreadsTab extends AbstractTableTab {
return;
}
String pid = ctx.selectedPid;
- ctx.runner.scheduler().execute(() -> {
+ ctx.backgroundExecutor.execute(() -> {
try {
loadThreadsInBackground(pid);
} finally {
@@ -341,17 +339,10 @@ class ThreadsTab extends AbstractTableTab {
}
private void loadThreadsInBackground(String pid) {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
-
JsonObject root = new JsonObject();
root.put("action", "thread-dump");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
-
- JsonObject jo = pollJsonResponse(outputFile, 5000);
- PathUtils.deleteFile(outputFile);
+ JsonObject jo = ctx.executeAction(pid, root, 5000);
if (jo == null) {
return;
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java
index 04b6d60337f4..16c5a4c624c4 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiHelper.java
@@ -34,7 +34,6 @@ import dev.tamboui.text.CharWidth;
import dev.tamboui.text.Line;
import dev.tamboui.text.Span;
import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
-import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.dsl.jbang.core.common.ProcessHelper;
import org.apache.camel.support.PatternHelper;
import org.apache.camel.util.FileUtil;
@@ -934,13 +933,9 @@ final class TuiHelper {
notifyCallback.accept("Writing heap dump...", false);
String pid = info.pid;
Thread t = new Thread(() -> {
- Path outputFile = ctx.getOutputFile(pid);
- PathUtils.deleteFile(outputFile);
JsonObject root = new JsonObject();
root.put("action", "heap-dump");
- Path actionFile = ctx.getActionFile(pid);
- PathUtils.writeTextSafely(root.toJson(), actionFile);
- JsonObject jo = pollJsonResponse(outputFile, 60000);
+ JsonObject jo = ctx.executeAction(pid, root, 60000);
if (jo != null) {
String error = jo.getString("error");
if (error != null) {
@@ -953,7 +948,6 @@ final class TuiHelper {
} else {
notifyCallback.accept("Heap dump: no response within 60s",
true);
}
- PathUtils.deleteFile(outputFile);
});
t.setDaemon(true);
t.setName("heap-dump-" + pid);