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 3954f5c5d6c CAMEL-20474: camel-platform-http-main - Add /q/info to
show some basic details
3954f5c5d6c is described below
commit 3954f5c5d6cfdde7204d3b837616c3181768cf3a
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Feb 29 13:59:01 2024 +0100
CAMEL-20474: camel-platform-http-main - Add /q/info to show some basic
details
---
.../main/camel-main-configuration-metadata.json | 1 +
.../http/main/DefaultMainHttpServerFactory.java | 1 +
.../platform/http/main/MainHttpServer.java | 129 +++++++++++++++++++++
...ttpServerConfigurationPropertiesConfigurer.java | 6 +
.../camel-main-configuration-metadata.json | 1 +
core/camel-main/src/main/docs/main.adoc | 3 +-
.../main/HttpServerConfigurationProperties.java | 20 ++++
.../modules/ROOT/pages/camel-jbang.adoc | 3 +
.../java/org/apache/camel/main/KameletMain.java | 6 +
9 files changed, 169 insertions(+), 1 deletion(-)
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 f2f63e72a4a..387d0a54077 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
@@ -253,6 +253,7 @@
{ "name": "camel.server.enabled", "description": "Whether embedded HTTP
server is enabled. By default, the server is not enabled.", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.healthCheckEnabled", "description": "Whether to
enable health-check console. If enabled then you can access health-check status
on context-path: \/q\/health", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.host", "description": "Hostname to use for binding
embedded HTTP server", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "string",
"javaType": "java.lang.String", "defaultValue": "0.0.0.0" },
+ { "name": "camel.server.infoEnabled", "description": "Whether to enable
info console. If enabled then you can see some basic Camel information at
\/q\/info", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.jolokiaEnabled", "description": "Whether to enable
jolokia. If enabled then you can access jolokia api on context-path:
\/q\/jolokia", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.maxBodySize", "description": "Maximum HTTP body
size the embedded HTTP server can accept.", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "integer",
"javaType": "java.lang.Long" },
{ "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" },
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 52e769b7b18..6e49fd94303 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
@@ -51,6 +51,7 @@ public class DefaultMainHttpServerFactory implements
CamelContextAware, MainHttp
server.setMaxBodySize(configuration.getMaxBodySize());
}
server.setUseGlobalSslContextParameters(configuration.isUseGlobalSslContextParameters());
+ server.setInfoEnabled(configuration.isInfoEnabled());
server.setDevConsoleEnabled(configuration.isDevConsoleEnabled());
server.setHealthCheckEnabled(configuration.isHealthCheckEnabled());
server.setJolokiaEnabled(configuration.isJolokiaEnabled());
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 a3311f307a7..b0e1b1b5390 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
@@ -20,8 +20,11 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -45,7 +48,9 @@ import org.apache.camel.Exchange;
import org.apache.camel.StartupListener;
import org.apache.camel.StaticService;
import org.apache.camel.api.management.ManagedAttribute;
+import org.apache.camel.api.management.ManagedCamelContext;
import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.api.management.mbean.ManagedCamelContextMBean;
import org.apache.camel.component.platform.http.HttpEndpointModel;
import org.apache.camel.component.platform.http.PlatformHttpComponent;
import
org.apache.camel.component.platform.http.plugin.JolokiaPlatformHttpPlugin;
@@ -59,6 +64,8 @@ import org.apache.camel.health.HealthCheck;
import org.apache.camel.health.HealthCheckHelper;
import org.apache.camel.health.HealthCheckRegistry;
import org.apache.camel.spi.CamelEvent;
+import org.apache.camel.spi.ReloadStrategy;
+import org.apache.camel.support.CamelContextHelper;
import org.apache.camel.support.ResolverHelper;
import org.apache.camel.support.SimpleEventNotifierSupport;
import org.apache.camel.support.jsse.SSLContextParameters;
@@ -69,6 +76,7 @@ import org.apache.camel.util.FileUtil;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.TimeUtils;
import org.apache.camel.util.json.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -87,6 +95,7 @@ public class MainHttpServer extends ServiceSupport implements
CamelContextAware,
private JolokiaPlatformHttpPlugin jolokiaPlugin;
private VertxPlatformHttpServerConfiguration configuration = new
VertxPlatformHttpServerConfiguration();
+ private boolean infoEnabled;
private boolean devConsoleEnabled;
private boolean healthCheckEnabled;
private boolean jolokiaEnabled;
@@ -112,6 +121,15 @@ public class MainHttpServer extends ServiceSupport
implements CamelContextAware,
this.configuration = configuration;
}
+ @ManagedAttribute(description = "Whether info is enabled (/q/info)")
+ public boolean isInfoEnabled() {
+ return infoEnabled;
+ }
+
+ public void setInfoEnabled(boolean infoEnabled) {
+ this.infoEnabled = infoEnabled;
+ }
+
@ManagedAttribute(description = "Whether dev console is enabled (/q/dev)")
public boolean isDevConsoleEnabled() {
return devConsoleEnabled;
@@ -295,6 +313,9 @@ public class MainHttpServer extends ServiceSupport
implements CamelContextAware,
}
protected void setupConsoles() {
+ if (infoEnabled) {
+ setupInfo();
+ }
if (devConsoleEnabled) {
setupDevConsole();
}
@@ -393,6 +414,114 @@ public class MainHttpServer extends ServiceSupport
implements CamelContextAware,
});
}
+ protected void setupInfo() {
+ final Route info = router.route("/q/info");
+ info.method(HttpMethod.GET);
+ info.produces("application/json");
+
+ Handler<RoutingContext> handler = new Handler<RoutingContext>() {
+
+ private String extractState(int status) {
+ if (status <= 4) {
+ return "Starting";
+ } else if (status == 5) {
+ return "Running";
+ } else if (status == 6) {
+ return "Suspending";
+ } else if (status == 7) {
+ return "Suspended";
+ } else if (status == 8) {
+ return "Terminating";
+ } else if (status == 9) {
+ return "Terminated";
+ } else {
+ return "Terminated";
+ }
+ }
+
+ @Override
+ public void handle(RoutingContext ctx) {
+ ctx.response().putHeader("content-type", "application/json");
+
+ JsonObject root = new JsonObject();
+ JsonObject jo = new JsonObject();
+ root.put("java", jo);
+
+ RuntimeMXBean rmb = ManagementFactory.getRuntimeMXBean();
+ if (rmb != null) {
+ jo.put("pid", rmb.getPid());
+ jo.put("vendor", rmb.getVmVendor());
+ jo.put("name", rmb.getVmName());
+ jo.put("version", String.format("%s",
System.getProperty("java.version")));
+ jo.put("user", System.getProperty("user.name"));
+ jo.put("dir", System.getProperty("user.dir"));
+ }
+
+ jo = new JsonObject();
+ root.put("camel", jo);
+
+ jo.put("name", camelContext.getName());
+ jo.put("version", camelContext.getVersion());
+ Collection<HealthCheck.Result> results =
HealthCheckHelper.invoke(getCamelContext());
+ boolean up = results.stream().allMatch(h ->
HealthCheck.State.UP.equals(h.getState()));
+ jo.put("ready", up ? "1/1" : "0/1");
+ jo.put("status",
extractState(getCamelContext().getCamelContextExtension().getStatusPhase()));
+ int reloaded = 0;
+ Set<ReloadStrategy> rs =
getCamelContext().hasServices(ReloadStrategy.class);
+ for (ReloadStrategy r : rs) {
+ reloaded += r.getReloadCounter();
+ }
+ jo.put("reload", reloaded);
+ jo.put("age", CamelContextHelper.getUptime(camelContext));
+
+ ManagedCamelContext mcc
+ =
getCamelContext().getCamelContextExtension().getContextPlugin(ManagedCamelContext.class);
+ if (mcc != null) {
+ ManagedCamelContextMBean mb = mcc.getManagedCamelContext();
+
+ long total = camelContext.getRoutes().stream()
+ .filter(r -> !r.isCreatedByRestDsl() &&
!r.isCreatedByKamelet()).count();
+ long started = camelContext.getRoutes().stream()
+ .filter(r -> !r.isCreatedByRestDsl() &&
!r.isCreatedByKamelet())
+ .filter(ServiceHelper::isStarted).count();
+ jo.put("routes", started + "/" + total);
+ String thp = mb.getThroughput();
+ thp = thp.replace(',', '.');
+ if (!thp.isEmpty()) {
+ jo.put("exchangesThroughput", thp + "/s");
+ }
+ jo.put("exchangesTotal", mb.getExchangesTotal());
+ jo.put("exchangesFailed", mb.getExchangesFailed());
+ jo.put("exchangesInflight", mb.getExchangesInflight());
+ if (mb.getExchangesTotal() > 0) {
+ jo.put("lastProcessingTime",
mb.getLastProcessingTime());
+ jo.put("deltaProcessingTime",
mb.getDeltaProcessingTime());
+ }
+ Date last = mb.getLastExchangeCreatedTimestamp();
+ if (last != null) {
+ jo.put("sinceLastExchangeCreated",
TimeUtils.printSince(last.getTime()));
+ }
+ last = mb.getLastExchangeFailureTimestamp();
+ if (last != null) {
+ jo.put("sinceLastExchangeFailed",
TimeUtils.printSince(last.getTime()));
+ }
+ last = mb.getLastExchangeCompletedTimestamp();
+ if (last != null) {
+ jo.put("sinceLastExchangeCompleted",
TimeUtils.printSince(last.getTime()));
+ }
+ }
+
+ ctx.end(root.toJson());
+ }
+ };
+
+ // use blocking handler as the task can take longer time to complete
+ info.handler(new BlockingHandlerDecorator(handler, true));
+
+ platformHttpComponent.addHttpEndpoint("/q/info", null, null,
+ "application/json", null);
+ }
+
protected void setupHealthCheckConsole() {
final Route health = router.route("/q/health");
health.method(HttpMethod.GET);
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 badbe6fed5c..278d864875d 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
@@ -29,6 +29,8 @@ public class HttpServerConfigurationPropertiesConfigurer
extends org.apache.came
case "HealthCheckEnabled":
target.setHealthCheckEnabled(property(camelContext, boolean.class, value));
return true;
case "host":
case "Host": target.setHost(property(camelContext,
java.lang.String.class, value)); return true;
+ case "infoenabled":
+ case "InfoEnabled": target.setInfoEnabled(property(camelContext,
boolean.class, value)); return true;
case "jolokiaenabled":
case "JolokiaEnabled": target.setJolokiaEnabled(property(camelContext,
boolean.class, value)); return true;
case "maxbodysize":
@@ -60,6 +62,8 @@ public class HttpServerConfigurationPropertiesConfigurer
extends org.apache.came
case "HealthCheckEnabled": return boolean.class;
case "host":
case "Host": return java.lang.String.class;
+ case "infoenabled":
+ case "InfoEnabled": return boolean.class;
case "jolokiaenabled":
case "JolokiaEnabled": return boolean.class;
case "maxbodysize":
@@ -92,6 +96,8 @@ public class HttpServerConfigurationPropertiesConfigurer
extends org.apache.came
case "HealthCheckEnabled": return target.isHealthCheckEnabled();
case "host":
case "Host": return target.getHost();
+ case "infoenabled":
+ case "InfoEnabled": return target.isInfoEnabled();
case "jolokiaenabled":
case "JolokiaEnabled": return target.isJolokiaEnabled();
case "maxbodysize":
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 f2f63e72a4a..387d0a54077 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
@@ -253,6 +253,7 @@
{ "name": "camel.server.enabled", "description": "Whether embedded HTTP
server is enabled. By default, the server is not enabled.", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.healthCheckEnabled", "description": "Whether to
enable health-check console. If enabled then you can access health-check status
on context-path: \/q\/health", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.host", "description": "Hostname to use for binding
embedded HTTP server", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "string",
"javaType": "java.lang.String", "defaultValue": "0.0.0.0" },
+ { "name": "camel.server.infoEnabled", "description": "Whether to enable
info console. If enabled then you can see some basic Camel information at
\/q\/info", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.jolokiaEnabled", "description": "Whether to enable
jolokia. If enabled then you can access jolokia api on context-path:
\/q\/jolokia", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": "false" },
{ "name": "camel.server.maxBodySize", "description": "Maximum HTTP body
size the embedded HTTP server can accept.", "sourceType":
"org.apache.camel.main.HttpServerConfigurationProperties", "type": "integer",
"javaType": "java.lang.Long" },
{ "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" },
diff --git a/core/camel-main/src/main/docs/main.adoc
b/core/camel-main/src/main/docs/main.adoc
index f95c98836b2..a6326e2fdb7 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -168,7 +168,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 12 options, which are listed below.
+The camel.server supports 13 options, which are listed below.
[width="100%",cols="2,5,^1,2",options="header"]
|===
@@ -177,6 +177,7 @@ The camel.server supports 12 options, which are listed
below.
| *camel.server.enabled* | Whether embedded HTTP server is enabled. By
default, the server is not enabled. | false | boolean
| *camel.server.healthCheck{zwsp}Enabled* | Whether to enable health-check
console. If enabled then you can access health-check status on context-path:
/q/health | false | boolean
| *camel.server.host* | Hostname to use for binding embedded HTTP server |
0.0.0.0 | String
+| *camel.server.infoEnabled* | Whether to enable info console. If enabled then
you can see some basic Camel information at /q/info | false | boolean
| *camel.server.jolokiaEnabled* | Whether to enable jolokia. If enabled then
you can access jolokia api on context-path: /q/jolokia | false | boolean
| *camel.server.maxBodySize* | Maximum HTTP body size the embedded HTTP server
can accept. | | Long
| *camel.server.metricsEnabled* | Whether to enable metrics. If enabled then
you can access metrics on context-path: /q/metrics | 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 93fff2e5e26..c9f2d63cc2c 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
@@ -39,6 +39,7 @@ public class HttpServerConfigurationProperties implements
BootstrapCloseable {
private Long maxBodySize;
private boolean useGlobalSslContextParameters;
+ private boolean infoEnabled;
private boolean devConsoleEnabled;
private boolean healthCheckEnabled;
private boolean jolokiaEnabled;
@@ -125,6 +126,17 @@ public class HttpServerConfigurationProperties implements
BootstrapCloseable {
this.useGlobalSslContextParameters = useGlobalSslContextParameters;
}
+ public boolean isInfoEnabled() {
+ return infoEnabled;
+ }
+
+ /**
+ * Whether to enable info console. If enabled then you can see some basic
Camel information at /q/info
+ */
+ public void setInfoEnabled(boolean infoEnabled) {
+ this.infoEnabled = infoEnabled;
+ }
+
public boolean isDevConsoleEnabled() {
return devConsoleEnabled;
}
@@ -246,6 +258,14 @@ public class HttpServerConfigurationProperties implements
BootstrapCloseable {
return this;
}
+ /**
+ * Whether to enable info console. If enabled then you can see some basic
Camel information at /q/info
+ */
+ public HttpServerConfigurationProperties withInfoEnabled(boolean
infoEnabled) {
+ this.infoEnabled = infoEnabled;
+ return this;
+ }
+
/**
* Whether to enable developer console (not intended for production use).
Dev console must also be enabled on
* CamelContext. For example by setting camel.context.dev-console=true in
application.properties, or via code
diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
index ae3e4ae6f8a..68218bc20bb 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
@@ -3403,6 +3403,9 @@ The follow options related to _exporting_, can be
configured in `application.pro
|`camel.jbang.console`
| Developer console at /q/dev on local HTTP server (port 8080 by default) when
running standalone Camel
+|`camel.jbang.info`
+| Info console at /q/info on local HTTP server (port 8080 by default) when
running standalone Camel
+
|`camel.jbang.health`
| Health check at /q/health on local HTTP server (port 8080 by default) when
running standalone Camel
diff --git
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index e25118d6e36..8035e6cabd8 100644
---
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -452,6 +452,7 @@ public class KameletMain extends MainCommandLineSupport {
boolean console =
"true".equals(getInitialProperties().get("camel.jbang.console"));
if (console) {
configure().httpServer().withEnabled(true);
+ configure().httpServer().withInfoEnabled(true); // also enable
info if console is enabled
configure().httpServer().withDevConsoleEnabled(true);
}
@@ -474,6 +475,11 @@ public class KameletMain extends MainCommandLineSupport {
if (tracing) {
configure().withBacklogTracing(true);
}
+ boolean infoConsole =
"true".equals(getInitialProperties().get("camel.jbang.info"));
+ if (infoConsole) {
+ configure().httpServer().withEnabled(true);
+ configure().httpServer().withInfoEnabled(true);
+ }
boolean health =
"true".equals(getInitialProperties().get("camel.jbang.health"));
if (health) {
configure().health().withEnabled(true);