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 2e8a5babdb2 CAMEL-21136: Add /q/send to camel-main/camel-jbang for 
sending messages to Camel via HTTP (#15451)
2e8a5babdb2 is described below

commit 2e8a5babdb265751b20f29d3255a9b993733c32c
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Sep 5 13:31:08 2024 +0200

    CAMEL-21136: Add /q/send to camel-main/camel-jbang for sending messages to 
Camel via HTTP (#15451)
    
    CAMEL-21136: Add /q/send to camel-main/camel-jbang for sending messages to 
Camel via HTTP
---
 .../main/camel-main-configuration-metadata.json    |   1 +
 .../base}/HttpProtocolHeaderFilterStrategy.java    |   2 +-
 .../common/HttpProtocolHeaderFilterStrategy.java   |  56 +-----
 .../src/main/docs/platform-http-main.adoc          |  18 ++
 .../http/main/DefaultMainHttpServerFactory.java    |   1 +
 .../platform/http/main/MainHttpServer.java         | 212 ++++++++++++++++++++-
 ...ttpServerConfigurationPropertiesConfigurer.java |   6 +
 .../camel-main-configuration-metadata.json         |   1 +
 core/camel-main/src/main/docs/main.adoc            |   3 +-
 .../main/HttpServerConfigurationProperties.java    |  22 +++
 10 files changed, 262 insertions(+), 60 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index 6870397226c..e169a45d9a5 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -276,6 +276,7 @@
     { "name": "camel.server.metricsEnabled", "description": "Whether to enable 
metrics. If enabled then you can access metrics on context-path: \/q\/metrics", 
"sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", 
"type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.server.path", "description": "Context-path to use for 
embedded HTTP server", "sourceType": 
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "defaultValue": "\/" },
     { "name": "camel.server.port", "description": "Port to use for binding 
embedded HTTP server", "sourceType": 
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "integer", 
"javaType": "int", "defaultValue": 8080 },
+    { "name": "camel.server.sendEnabled", "description": "Whether to enable 
sending messages to Camel via HTTP. This makes it possible to use Camel to send 
messages to Camel endpoint URIs via HTTP.", "sourceType": 
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.server.staticContextPath", "description": "The 
context-path to use for serving static content. By default, the root path is 
used. And if there is an index.html page then this is automatically loaded.", 
"sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", 
"type": "string", "javaType": "java.lang.String", "defaultValue": "\/" },
     { "name": "camel.server.staticEnabled", "description": "Whether serving 
static files is enabled. If enabled then Camel can host html\/js and other web 
files that makes it possible to include small web applications.", "sourceType": 
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.server.uploadEnabled", "description": "Whether to enable 
file upload via HTTP (not intended for production use). This functionality is 
for development to be able to reload Camel routes and code with source changes 
(if reload is enabled). If enabled then you can upload\/delete files via HTTP 
PUT\/DELETE on context-path: \/q\/upload\/{name}. You must also configure the 
uploadSourceDir option.", "sourceType": 
"org.apache.camel.main.HttpServerConfigurationProperties", "t [...]
diff --git 
a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java
 
b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java
similarity index 98%
copy from 
components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java
copy to 
components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java
index dad15351231..d3a0db4f500 100644
--- 
a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java
+++ 
b/components/camel-http-base/src/main/java/org/apache/camel/http/base/HttpProtocolHeaderFilterStrategy.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.http.common;
+package org.apache.camel.http.base;
 
 import org.apache.camel.support.DefaultHeaderFilterStrategy;
 import org.apache.camel.support.http.HttpUtil;
diff --git 
a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java
 
b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java
index dad15351231..54f8f95c3e3 100644
--- 
a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java
+++ 
b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpProtocolHeaderFilterStrategy.java
@@ -16,59 +16,5 @@
  */
 package org.apache.camel.http.common;
 
-import org.apache.camel.support.DefaultHeaderFilterStrategy;
-import org.apache.camel.support.http.HttpUtil;
-
-public class HttpProtocolHeaderFilterStrategy extends 
DefaultHeaderFilterStrategy {
-
-    public HttpProtocolHeaderFilterStrategy() {
-        initialize();
-    }
-
-    // Just add the http headers here
-    protected void initialize() {
-
-        getInFilter().add("content-encoding");
-        getInFilter().add("content-language");
-        getInFilter().add("content-location");
-        getInFilter().add("content-md5");
-        getInFilter().add("content-range");
-
-        getInFilter().add("dav");
-        getInFilter().add("depth");
-        getInFilter().add("destination");
-        getInFilter().add("etag");
-        getInFilter().add("expect");
-        getInFilter().add("expires");
-        getInFilter().add("from");
-        getInFilter().add("if");
-        getInFilter().add("if-match");
-        getInFilter().add("if-modified-since");
-        getInFilter().add("if-none-match");
-        getInFilter().add("if-range");
-        getInFilter().add("if-unmodified-since");
-        getInFilter().add("last-modified");
-        getInFilter().add("location");
-        getInFilter().add("lock-token");
-        getInFilter().add("max-forwards");
-        getInFilter().add("overwrite");
-        getInFilter().add("proxy-authenticate");
-        getInFilter().add("proxy-authorization");
-        getInFilter().add("range");
-        getInFilter().add("referer");
-        getInFilter().add("retry-after");
-        getInFilter().add("server");
-        getInFilter().add("status-uri");
-        getInFilter().add("te");
-        getInFilter().add("timeout");
-
-        getInFilter().add("user-agent");
-        getInFilter().add("vary");
-
-        getInFilter().add("www-authenticate");
-
-        HttpUtil.addCommonFilters(getInFilter());
-
-        setLowerCase(true);
-    }
+public class HttpProtocolHeaderFilterStrategy extends 
org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy {
 }
diff --git 
a/components/camel-platform-http-main/src/main/docs/platform-http-main.adoc 
b/components/camel-platform-http-main/src/main/docs/platform-http-main.adoc
index e99e970bf95..02c3d32f86e 100644
--- a/components/camel-platform-http-main/src/main/docs/platform-http-main.adoc
+++ b/components/camel-platform-http-main/src/main/docs/platform-http-main.adoc
@@ -23,6 +23,24 @@ by setting `camel.server.enabled=true` in 
application.properties.
 To use this implementation all you need to do is to add the 
`camel-platform-http-main` dependency to the classpath.
 Then, the platform http component should auto-detect this.
 
+== Uploading and downloading files
+
+The embedded HTTP server comes with a set of features out of the box, that can 
be enabled.
+
+These features are as follows:
+
+- `/q/info` - Report basic information about Camel
+- `/dev/console` - Developer console that provides a lot of statistics and 
information
+- `/q/health` - Health checks
+- `/q/jolokia` - To use Jolokia to expose JMX over HTTP REST
+- `/q/metrics` - To provide otel metrics in prometheus format
+- `/q/upload` - Uploading source files, to allow hot reloading.
+- `/q/download` - Downloading source files, to allow inspecting
+- `/q/send` - Sending messages to the Camel application via HTTP
+- `/` - Serving static content such as html, javascript, css, and images to 
make it easy to embed very small web applications.
+
+You configure these features in the `application.properties` file using the 
`camel.server.xxx` options.
+
 == See More
 
 - xref:platform-http-vertx.adoc[Platform HTTP Vert.x]
diff --git 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
index e1da6e422de..894b8b71761 100644
--- 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
+++ 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/DefaultMainHttpServerFactory.java
@@ -64,6 +64,7 @@ public class DefaultMainHttpServerFactory implements 
CamelContextAware, MainHttp
         server.setUploadEnabled(configuration.isUploadEnabled());
         server.setUploadSourceDir(configuration.getUploadSourceDir());
         server.setDownloadEnabled(configuration.isDownloadEnabled());
+        server.setSendEnabled(configuration.isSendEnabled());
 
         if (configuration.isAuthenticationEnabled()) {
             configureAuthentication(server, configuration);
diff --git 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
index 86ad9cb221e..fcf9ac76969 100644
--- 
a/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
+++ 
b/components/camel-platform-http-main/src/main/java/org/apache/camel/component/platform/http/main/MainHttpServer.java
@@ -29,6 +29,7 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -47,7 +48,11 @@ import io.vertx.ext.web.handler.BodyHandler;
 import io.vertx.ext.web.impl.BlockingHandlerDecorator;
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
+import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.NoSuchEndpointException;
+import org.apache.camel.ProducerTemplate;
 import org.apache.camel.StartupListener;
 import org.apache.camel.StaticService;
 import org.apache.camel.api.management.ManagedAttribute;
@@ -66,14 +71,18 @@ import org.apache.camel.console.DevConsoleRegistry;
 import org.apache.camel.health.HealthCheck;
 import org.apache.camel.health.HealthCheckHelper;
 import org.apache.camel.health.HealthCheckRegistry;
+import org.apache.camel.http.base.HttpProtocolHeaderFilterStrategy;
 import org.apache.camel.spi.CamelEvent;
+import org.apache.camel.spi.HeaderFilterStrategy;
 import org.apache.camel.spi.PackageScanResourceResolver;
 import org.apache.camel.spi.ReloadStrategy;
 import org.apache.camel.spi.Resource;
 import org.apache.camel.spi.ResourceLoader;
 import org.apache.camel.support.CamelContextHelper;
+import org.apache.camel.support.EndpointHelper;
 import org.apache.camel.support.ExceptionHelper;
 import org.apache.camel.support.LoggerHelper;
+import org.apache.camel.support.MessageHelper;
 import org.apache.camel.support.PluginHelper;
 import org.apache.camel.support.ResolverHelper;
 import org.apache.camel.support.SimpleEventNotifierSupport;
@@ -84,6 +93,7 @@ import org.apache.camel.util.AntPathMatcher;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StopWatch;
 import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.TimeUtils;
 import org.apache.camel.util.json.JsonObject;
@@ -94,6 +104,10 @@ import org.slf4j.LoggerFactory;
 public class MainHttpServer extends ServiceSupport implements 
CamelContextAware, StaticService {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(MainHttpServer.class);
+    private static final int BODY_MAX_CHARS = 128 * 1024;
+
+    private final HeaderFilterStrategy filter = new 
HttpProtocolHeaderFilterStrategy();
+    private ProducerTemplate producer;
 
     private VertxPlatformHttpServer server;
     private VertxPlatformHttpRouter router;
@@ -114,6 +128,7 @@ public class MainHttpServer extends ServiceSupport 
implements CamelContextAware,
     private boolean uploadEnabled;
     private String uploadSourceDir;
     private boolean downloadEnabled;
+    private boolean sendEnabled;
 
     @Override
     public CamelContext getCamelContext() {
@@ -249,6 +264,19 @@ public class MainHttpServer extends ServiceSupport 
implements CamelContextAware,
         this.downloadEnabled = downloadEnabled;
     }
 
+    @ManagedAttribute(description = "Whether send message is enabled  
(q/send)")
+    public boolean isSendEnabled() {
+        return sendEnabled;
+    }
+
+    /**
+     * Whether to enable sending messages to Camel via HTTP. This makes it 
possible to use Camel to send messages to
+     * Camel endpoint URIs via HTTP.
+     */
+    public void setSendEnabled(boolean sendEnabled) {
+        this.sendEnabled = sendEnabled;
+    }
+
     @ManagedAttribute(description = "HTTP server port number")
     public int getPort() {
         return configuration.getBindPort();
@@ -326,6 +354,10 @@ public class MainHttpServer extends ServiceSupport 
implements CamelContextAware,
     protected void doInit() throws Exception {
         ObjectHelper.notNull(camelContext, "CamelContext");
 
+        if (sendEnabled && producer == null) {
+            producer = camelContext.createProducerTemplate();
+        }
+
         server = new VertxPlatformHttpServer(configuration);
         // adding server to camel-context which will manage shutdown the 
server, so we should not do this here
         camelContext.addService(server);
@@ -336,14 +368,14 @@ public class MainHttpServer extends ServiceSupport 
implements CamelContextAware,
             pluginRegistry.setCamelContext(getCamelContext());
             
getCamelContext().getCamelContextExtension().addContextPlugin(PlatformHttpPluginRegistry.class,
 pluginRegistry);
         }
-        ServiceHelper.initService(pluginRegistry);
+        ServiceHelper.initService(pluginRegistry, producer);
     }
 
     @Override
     protected void doStart() throws Exception {
         ObjectHelper.notNull(camelContext, "CamelContext");
 
-        ServiceHelper.startService(server, pluginRegistry);
+        ServiceHelper.startService(server, pluginRegistry, producer);
         router = VertxPlatformHttpRouter.lookup(camelContext);
         platformHttpComponent = camelContext.getComponent("platform-http", 
PlatformHttpComponent.class);
 
@@ -353,7 +385,7 @@ public class MainHttpServer extends ServiceSupport 
implements CamelContextAware,
 
     @Override
     protected void doShutdown() throws Exception {
-        ServiceHelper.stopAndShutdownService(pluginRegistry);
+        ServiceHelper.stopAndShutdownServices(pluginRegistry, producer);
     }
 
     private boolean pluginsEnabled() {
@@ -385,6 +417,9 @@ public class MainHttpServer extends ServiceSupport 
implements CamelContextAware,
         if (downloadEnabled) {
             setupDownloadConsole();
         }
+        if (sendEnabled) {
+            setupSendConsole();
+        }
         // metrics will be setup in camel-micrometer-prometheus
     }
 
@@ -1165,4 +1200,175 @@ public class MainHttpServer extends ServiceSupport 
implements CamelContextAware,
                 null, "text/plain,application/octet-stream", null);
     }
 
+    protected void setupSendConsole() {
+        final Route send = router.route("/q/send/")
+                .produces("application/json")
+                .method(HttpMethod.GET).method(HttpMethod.POST)
+                // need body handler to have access to the body
+                .handler(BodyHandler.create(false));
+
+        Handler<RoutingContext> handler = new Handler<RoutingContext>() {
+            @Override
+            public void handle(RoutingContext ctx) {
+                try {
+                    doSend(ctx);
+                } catch (Exception e) {
+                    LOG.warn("Error sending Camel message due to: " + 
e.getMessage(), e);
+                    if (!ctx.response().ended()) {
+                        ctx.response().setStatusCode(500);
+                        ctx.end();
+                    }
+                }
+            }
+        };
+        // use blocking handler as the task can take longer time to complete
+        send.handler(new BlockingHandlerDecorator(handler, true));
+
+        platformHttpComponent.addHttpEndpoint("/q/send", "GET,POST",
+                null, "application/json", null);
+    }
+
+    protected void doSend(RoutingContext ctx) {
+        StopWatch watch = new StopWatch();
+        long timestamp = System.currentTimeMillis();
+
+        String endpoint = ctx.request().getHeader("endpoint");
+        String exchangePattern = ctx.request().getHeader("exchangePattern");
+        String resultType = ctx.request().getHeader("resultType");
+        final Map<String, Object> headers = new LinkedHashMap<>();
+        for (var entry : ctx.request().headers()) {
+            String k = entry.getKey();
+            boolean exclude
+                    = "endpoint".equals(k) || "exchangePattern".equals(k) || 
"resultType".equals(k) || "Accept".equals(k)
+                            || 
filter.applyFilterToExternalHeaders(entry.getKey(), entry.getValue(), null);
+            if (!exclude) {
+                headers.put(entry.getKey(), entry.getValue());
+            }
+        }
+        final String body = ctx.body().asString();
+
+        Exchange out = null;
+        Endpoint target = null;
+        if (endpoint == null) {
+            List<org.apache.camel.Route> routes = camelContext.getRoutes();
+            if (!routes.isEmpty()) {
+                // grab endpoint from 1st route
+                target = routes.get(0).getEndpoint();
+            }
+        } else {
+            // is the endpoint a pattern or route id
+            boolean scheme = endpoint.contains(":");
+            boolean pattern = endpoint.endsWith("*");
+            if (!scheme || pattern) {
+                if (!scheme) {
+                    endpoint = endpoint + "*";
+                }
+                for (org.apache.camel.Route route : camelContext.getRoutes()) {
+                    Endpoint e = route.getEndpoint();
+                    if (EndpointHelper.matchEndpoint(camelContext, 
e.getEndpointUri(), endpoint)) {
+                        target = e;
+                        break;
+                    }
+                }
+                if (target == null) {
+                    // okay it may refer to a route id
+                    for (org.apache.camel.Route route : 
camelContext.getRoutes()) {
+                        String id = route.getRouteId();
+                        Endpoint e = route.getEndpoint();
+                        if (EndpointHelper.matchEndpoint(camelContext, id, 
endpoint)) {
+                            target = e;
+                            break;
+                        }
+                    }
+                }
+            } else {
+                target = camelContext.getEndpoint(endpoint);
+            }
+        }
+
+        JsonObject jo = new JsonObject();
+        if (target != null) {
+            Class<?> clazz = null;
+            try {
+                if (resultType != null) {
+                    clazz = 
camelContext.getClassResolver().resolveMandatoryClass(resultType);
+                    // we want the result as a specific type then make sure to 
use InOut
+                    if (exchangePattern == null) {
+                        exchangePattern = "InOut";
+                    }
+                }
+                if (exchangePattern == null) {
+                    exchangePattern = "InOnly"; // use in-only by default
+                }
+                final ExchangePattern mep = 
ExchangePattern.valueOf(exchangePattern);
+                out = producer.send(target, exchange -> {
+                    exchange.setPattern(mep);
+                    exchange.getMessage().setBody(body);
+                    if (!headers.isEmpty()) {
+                        exchange.getMessage().setHeaders(headers);
+                    }
+                });
+                if (clazz != null) {
+                    Object b = out.getMessage().getBody(clazz);
+                    out.getMessage().setBody(b);
+                }
+            } catch (ClassNotFoundException e) {
+                jo.put("endpoint", target.getEndpointUri());
+                jo.put("exchangePattern", exchangePattern);
+                jo.put("timestamp", timestamp);
+                jo.put("elapsed", watch.taken());
+                jo.put("status", "failed");
+                jo.put("exception",
+                        
MessageHelper.dumpExceptionAsJSonObject(e).getMap("exception"));
+            }
+            if (out != null && out.getException() != null) {
+                jo.put("endpoint", target.getEndpointUri());
+                jo.put("exchangeId", out.getExchangeId());
+                jo.put("exchangePattern", exchangePattern);
+                jo.put("timestamp", timestamp);
+                jo.put("elapsed", watch.taken());
+                jo.put("status", "failed");
+                // avoid double wrap
+                jo.put("exception",
+                        
MessageHelper.dumpExceptionAsJSonObject(out.getException()).getMap("exception"));
+            } else if (out != null && "InOut".equals(exchangePattern)) {
+                jo.put("endpoint", target.getEndpointUri());
+                jo.put("exchangeId", out.getExchangeId());
+                jo.put("exchangePattern", exchangePattern);
+                jo.put("timestamp", timestamp);
+                jo.put("elapsed", watch.taken());
+                jo.put("status", "success");
+                // dump response and remove unwanted data
+                JsonObject msg = 
MessageHelper.dumpAsJSonObject(out.getMessage(), false, false, true, true, 
true, true,
+                        BODY_MAX_CHARS).getMap("message");
+                msg.remove("exchangeId");
+                msg.remove("exchangePattern");
+                msg.remove("exchangeType");
+                msg.remove("messageType");
+                jo.put("message", msg);
+            } else if (out != null) {
+                jo.put("endpoint", target.getEndpointUri());
+                jo.put("exchangeId", out.getExchangeId());
+                jo.put("exchangePattern", exchangePattern);
+                jo.put("timestamp", timestamp);
+                jo.put("elapsed", watch.taken());
+                jo.put("status", "success");
+            }
+        } else {
+            // there is no valid endpoint
+            ctx.response().setStatusCode(400);
+            jo.put("endpoint", endpoint);
+            jo.put("exchangeId", "");
+            jo.put("exchangePattern", exchangePattern);
+            jo.put("timestamp", timestamp);
+            jo.put("elapsed", watch.taken());
+            jo.put("status", "failed");
+            // avoid double wrap
+            jo.put("exception",
+                    MessageHelper.dumpExceptionAsJSonObject(new 
NoSuchEndpointException(endpoint))
+                            .getMap("exception"));
+        }
+        ctx.end(jo.toJson());
+    }
+
 }
diff --git 
a/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
 
b/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
index af40d20036f..d7cc0cc53cd 100644
--- 
a/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
+++ 
b/core/camel-main/src/generated/java/org/apache/camel/main/HttpServerConfigurationPropertiesConfigurer.java
@@ -53,6 +53,8 @@ public class HttpServerConfigurationPropertiesConfigurer 
extends org.apache.came
         case "metricsEnabled": target.setMetricsEnabled(property(camelContext, 
boolean.class, value)); return true;
         case "path": target.setPath(property(camelContext, 
java.lang.String.class, value)); return true;
         case "port": target.setPort(property(camelContext, int.class, value)); 
return true;
+        case "sendenabled":
+        case "sendEnabled": target.setSendEnabled(property(camelContext, 
boolean.class, value)); return true;
         case "staticcontextpath":
         case "staticContextPath": 
target.setStaticContextPath(property(camelContext, java.lang.String.class, 
value)); return true;
         case "staticenabled":
@@ -100,6 +102,8 @@ public class HttpServerConfigurationPropertiesConfigurer 
extends org.apache.came
         case "metricsEnabled": return boolean.class;
         case "path": return java.lang.String.class;
         case "port": return int.class;
+        case "sendenabled":
+        case "sendEnabled": return boolean.class;
         case "staticcontextpath":
         case "staticContextPath": return java.lang.String.class;
         case "staticenabled":
@@ -148,6 +152,8 @@ public class HttpServerConfigurationPropertiesConfigurer 
extends org.apache.came
         case "metricsEnabled": return target.isMetricsEnabled();
         case "path": return target.getPath();
         case "port": return target.getPort();
+        case "sendenabled":
+        case "sendEnabled": return target.isSendEnabled();
         case "staticcontextpath":
         case "staticContextPath": return target.getStaticContextPath();
         case "staticenabled":
diff --git 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 6870397226c..e169a45d9a5 100644
--- 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -276,6 +276,7 @@
     { "name": "camel.server.metricsEnabled", "description": "Whether to enable 
metrics. If enabled then you can access metrics on context-path: \/q\/metrics", 
"sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", 
"type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.server.path", "description": "Context-path to use for 
embedded HTTP server", "sourceType": 
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "defaultValue": "\/" },
     { "name": "camel.server.port", "description": "Port to use for binding 
embedded HTTP server", "sourceType": 
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "integer", 
"javaType": "int", "defaultValue": 8080 },
+    { "name": "camel.server.sendEnabled", "description": "Whether to enable 
sending messages to Camel via HTTP. This makes it possible to use Camel to send 
messages to Camel endpoint URIs via HTTP.", "sourceType": 
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.server.staticContextPath", "description": "The 
context-path to use for serving static content. By default, the root path is 
used. And if there is an index.html page then this is automatically loaded.", 
"sourceType": "org.apache.camel.main.HttpServerConfigurationProperties", 
"type": "string", "javaType": "java.lang.String", "defaultValue": "\/" },
     { "name": "camel.server.staticEnabled", "description": "Whether serving 
static files is enabled. If enabled then Camel can host html\/js and other web 
files that makes it possible to include small web applications.", "sourceType": 
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.server.uploadEnabled", "description": "Whether to enable 
file upload via HTTP (not intended for production use). This functionality is 
for development to be able to reload Camel routes and code with source changes 
(if reload is enabled). If enabled then you can upload\/delete files via HTTP 
PUT\/DELETE on context-path: \/q\/upload\/{name}. You must also configure the 
uploadSourceDir option.", "sourceType": 
"org.apache.camel.main.HttpServerConfigurationProperties", "t [...]
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index 0f95836ea0d..1ae7acb68a4 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -170,7 +170,7 @@ The camel.routecontroller supports 12 options, which are 
listed below.
 
 
 === Camel Embedded HTTP Server (only for standalone; not Spring Boot or 
Quarkus) configurations
-The camel.server supports 22 options, which are listed below.
+The camel.server supports 23 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -192,6 +192,7 @@ The camel.server supports 22 options, which are listed 
below.
 | *camel.server.metricsEnabled* | Whether to enable metrics. If enabled then 
you can access metrics on context-path: /q/metrics | false | boolean
 | *camel.server.path* | Context-path to use for embedded HTTP server | / | 
String
 | *camel.server.port* | Port to use for binding embedded HTTP server | 8080 | 
int
+| *camel.server.sendEnabled* | Whether to enable sending messages to Camel via 
HTTP. This makes it possible to use Camel to send messages to Camel endpoint 
URIs via HTTP. | false | boolean
 | *camel.server.staticContextPath* | The context-path to use for serving 
static content. By default, the root path is used. And if there is an 
index.html page then this is automatically loaded. | / | String
 | *camel.server.staticEnabled* | Whether serving static files is enabled. If 
enabled then Camel can host html/js and other web files that makes it possible 
to include small web applications. | false | boolean
 | *camel.server.uploadEnabled* | Whether to enable file upload via HTTP (not 
intended for production use). This functionality is for development to be able 
to reload Camel routes and code with source changes (if reload is enabled). If 
enabled then you can upload/delete files via HTTP PUT/DELETE on context-path: 
/q/upload/\{name}. You must also configure the uploadSourceDir option. | false 
| boolean
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
index 96d5e0128b6..a9bb82c78d7 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/HttpServerConfigurationProperties.java
@@ -50,6 +50,7 @@ public class HttpServerConfigurationProperties implements 
BootstrapCloseable {
     private boolean uploadEnabled;
     private String uploadSourceDir;
     private boolean downloadEnabled;
+    private boolean sendEnabled;
 
     @Metadata(label = "security")
     private boolean authenticationEnabled;
@@ -264,6 +265,18 @@ public class HttpServerConfigurationProperties implements 
BootstrapCloseable {
         this.downloadEnabled = downloadEnabled;
     }
 
+    public boolean isSendEnabled() {
+        return sendEnabled;
+    }
+
+    /**
+     * Whether to enable sending messages to Camel via HTTP. This makes it 
possible to use Camel to send messages to
+     * Camel endpoint URIs via HTTP.
+     */
+    public void setSendEnabled(boolean sendEnabled) {
+        this.sendEnabled = sendEnabled;
+    }
+
     public boolean isAuthenticationEnabled() {
         return authenticationEnabled;
     }
@@ -470,6 +483,15 @@ public class HttpServerConfigurationProperties implements 
BootstrapCloseable {
         return this;
     }
 
+    /**
+     * Whether to enable sending messages to Camel via HTTP. This makes it 
possible to use Camel to send messages to
+     * Camel endpoint URIs via HTTP.
+     */
+    public HttpServerConfigurationProperties withSendEnabled(boolean 
sendEnabled) {
+        this.sendEnabled = sendEnabled;
+        return this;
+    }
+
     /**
      * Whether to enable HTTP authentication for embedded server (for 
standalone applications; not Spring Boot or
      * Quarkus).

Reply via email to