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 2026/07/27 14:15:11 UTC
(camel) 01/01: CAMEL-24274: camel-tui - Send Message uses HTTP for platform-http routes
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch fix/CAMEL-24274
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 6074326a7cdaf05e7a44625a772f36936a999256
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Jul 27 16:14:56 2026 +0200
CAMEL-24274: camel-tui - Send Message uses HTTP for platform-http routes
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
Signed-off-by: Claus Ibsen <cl...@gmail.com>
---
.../dsl/jbang/core/commands/tui/ActionsPopup.java | 2 +-
.../jbang/core/commands/tui/SendMessagePopup.java | 136 ++++++++++++++++++++-
2 files changed, 135 insertions(+), 3 deletions(-)
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 c5aff66eb649..0319f66cafed 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
@@ -1180,7 +1180,7 @@ class ActionsPopup {
setNotification("No routes available", true);
return;
}
- sendMessagePopup.open(ctx, pid, info.name, info.routes, preSelectedRouteId, info.directory);
+ sendMessagePopup.open(ctx, pid, info.name, info.routes, preSelectedRouteId, info.directory, info.httpServer);
preSelectedRouteId = 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 3125e4c6cc7e..56ae976f99d9 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,9 +17,17 @@
package org.apache.camel.dsl.jbang.core.commands.tui;
import java.io.File;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
@@ -67,6 +75,7 @@ class SendMessagePopup {
private boolean sending;
private String pid;
private String integrationName;
+ private String httpServer;
private List<RouteInfo> routes;
private int selectedRouteIndex;
private final TextAreaState bodyState = new TextAreaState("");
@@ -104,17 +113,18 @@ class SendMessagePopup {
}
void open(MonitorContext ctx, String pid, String name, List<RouteInfo> routes, String preSelectRouteId) {
- open(ctx, pid, name, routes, preSelectRouteId, null);
+ open(ctx, pid, name, routes, preSelectRouteId, null, null);
}
void open(
MonitorContext ctx, String pid, String name, List<RouteInfo> routes,
- String preSelectRouteId, String sourceDirectory) {
+ String preSelectRouteId, String sourceDirectory, String httpServer) {
if (pid == null || routes == null || routes.isEmpty()) {
return;
}
this.pid = pid;
this.integrationName = name;
+ this.httpServer = httpServer;
this.routes = new ArrayList<>(routes);
this.selectedRouteIndex = findSmartDefault(preSelectRouteId);
this.bodyState.clear();
@@ -507,6 +517,18 @@ class SendMessagePopup {
List<FormHelper.HeaderEntry> hdrs = headers != null ? new ArrayList<>(headers) : null;
String routeId = route.routeId;
+ // platform-http routes are consumer-only so we send an HTTP request directly
+ if (route.from != null && route.from.startsWith("platform-http:") && httpServer != null) {
+ executor.execute(() -> {
+ try {
+ doSendHttp(route, sendBody, hdrs, captureInOut, routeId);
+ } finally {
+ sending = false;
+ }
+ });
+ return;
+ }
+
executor.execute(() -> {
try {
JsonObject root = new JsonObject();
@@ -627,6 +649,116 @@ class SendMessagePopup {
});
}
+ private void doSendHttp(
+ RouteInfo route, String body, List<FormHelper.HeaderEntry> hdrs,
+ boolean captureInOut, String routeId) {
+ try {
+ String path = extractPlatformHttpPath(route.from);
+ String baseUrl = httpServer.replace("0.0.0.0", "localhost");
+ String url = baseUrl + path;
+ String method = extractHttpMethod(route.from, body);
+
+ // read file content if body references a file
+ String sendBody = body;
+ if (sendBody != null && sendBody.startsWith("file:")) {
+ sendBody = Files.readString(Path.of(sendBody.substring(5)));
+ }
+
+ HttpClient client = HttpClient.newBuilder()
+ .connectTimeout(Duration.ofSeconds(10))
+ .build();
+
+ boolean hasBody = sendBody != null && !sendBody.isEmpty();
+ HttpRequest.BodyPublisher bodyPublisher = hasBody
+ ? HttpRequest.BodyPublishers.ofString(sendBody)
+ : HttpRequest.BodyPublishers.noBody();
+
+ HttpRequest.Builder reqBuilder = HttpRequest.newBuilder()
+ .uri(URI.create(url))
+ .timeout(Duration.ofSeconds(20))
+ .method(method, bodyPublisher);
+
+ if (hdrs != null) {
+ for (FormHelper.HeaderEntry he : hdrs) {
+ String k = he.keyInput().text().trim();
+ String v = he.valueInput().text();
+ if (!k.isEmpty()) {
+ reqBuilder.header(k, v);
+ }
+ }
+ }
+
+ long start = System.currentTimeMillis();
+ HttpResponse<String> response = client.send(reqBuilder.build(),
+ HttpResponse.BodyHandlers.ofString());
+ long elapsed = System.currentTimeMillis() - start;
+
+ int httpStatus = response.statusCode();
+ boolean error = httpStatus >= 400;
+
+ List<String> hdrLines = new ArrayList<>();
+ hdrLines.add("HTTP " + method + " " + url);
+ hdrLines.add("status: " + httpStatus);
+
+ if (captureInOut) {
+ for (Map.Entry<String, List<String>> entry : response.headers().map().entrySet()) {
+ String k = entry.getKey();
+ if (k == null || k.startsWith(":")) {
+ continue;
+ }
+ for (String v : entry.getValue()) {
+ hdrLines.add(k + ": " + v);
+ }
+ }
+ }
+
+ String rawBody = captureInOut ? response.body() : null;
+
+ applyResult(routeId, body, hdrs, captureInOut,
+ String.valueOf(httpStatus), elapsed, null, hdrLines, rawBody,
+ error, error ? "HTTP " + httpStatus : null);
+ } catch (Exception e) {
+ applyResult(routeId, body, hdrs, captureInOut,
+ null, 0, null, null, null,
+ true, "Error: " + e.getMessage());
+ }
+ }
+
+ private static String extractPlatformHttpPath(String fromUri) {
+ // platform-http:///path?opts or platform-http:/path?opts
+ String path = fromUri.substring("platform-http:".length());
+ // strip query parameters
+ int q = path.indexOf('?');
+ if (q >= 0) {
+ path = path.substring(0, q);
+ }
+ // strip leading slashes from scheme separator (platform-http:///path -> /path)
+ while (path.startsWith("//")) {
+ path = path.substring(1);
+ }
+ if (!path.startsWith("/")) {
+ path = "/" + path;
+ }
+ return path;
+ }
+
+ private static String extractHttpMethod(String fromUri, String body) {
+ int q = fromUri.indexOf('?');
+ if (q >= 0) {
+ String query = fromUri.substring(q + 1);
+ for (String param : query.split("&")) {
+ if (param.startsWith("httpMethodRestrict=")) {
+ String methods = param.substring("httpMethodRestrict=".length());
+ // take the first method if comma-separated
+ int comma = methods.indexOf(',');
+ return comma > 0 ? methods.substring(0, comma).trim() : methods.trim();
+ }
+ }
+ }
+ // default: POST if body is present, GET otherwise
+ return (body != null && !body.isEmpty()) ? "POST" : "GET";
+ }
+
private void applyResult(
String routeId, String body, List<FormHelper.HeaderEntry> hdrs, boolean wasInOut,
String status, long elapsed, String exchangeId,