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 c86657169b87 CAMEL-23771: Add Java DSL dump support to SPI, JMX,
DevConsole, CLI, and MCP (#24052)
c86657169b87 is described below
commit c86657169b87d010abb706be24450e6f165dd161
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Jun 16 17:50:07 2026 +0200
CAMEL-23771: Add Java DSL dump support to SPI, JMX, DevConsole, CLI, and
MCP (#24052)
Signed-off-by: Claus Ibsen <[email protected]>
Co-authored-by: Claude <[email protected]>
---
bom/camel-bom/pom.xml | 5 +
.../main/java/org/apache/camel/CamelContext.java | 8 +-
.../org/apache/camel/spi/DumpRoutesStrategy.java | 2 +-
.../org/apache/camel/spi/ModelToJavaDumper.java | 59 +++++++
.../camel/impl/engine/AbstractCamelContext.java | 4 +
.../camel/impl/engine/SimpleCamelContext.java | 9 +
.../org/apache/camel/dev-console/route-dump.json | 2 +-
.../camel/impl/console/RouteDumpDevConsole.java | 13 +-
.../camel/impl/DefaultDumpRoutesStrategy.java | 143 ++++++++++++++++
.../services/org/apache/camel/modeljava-dumper | 2 +
.../org/apache/camel/java/LwModelToJavaDumper.java | 184 +++++++++++++++++++++
.../camel-main-configuration-metadata.json | 2 +-
core/camel-main/src/main/docs/main.adoc | 2 +-
.../camel/main/DefaultConfigurationProperties.java | 12 +-
.../management/mbean/ManagedCamelContextMBean.java | 6 +
.../api/management/mbean/ManagedRouteMBean.java | 6 +
.../management/mbean/ManagedCamelContext.java | 18 ++
.../camel/management/mbean/ManagedRoute.java | 16 ++
.../org/apache/camel/support/PluginHelper.java | 17 +-
.../jbang-commands/camel-jbang-get-route-dump.adoc | 4 +-
.../ROOT/pages/jbang-commands/camel-jbang-get.adoc | 2 +-
.../META-INF/camel-jbang-commands-metadata.json | 2 +-
.../core/commands/action/CamelRouteDumpAction.java | 6 +-
.../dsl/jbang/core/commands/mcp/RuntimeTools.java | 4 +-
dsl/camel-kamelet-main/pom.xml | 4 +
.../camel-main-known-dependencies.properties | 1 +
parent/pom.xml | 5 +
27 files changed, 513 insertions(+), 25 deletions(-)
diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index f58c1f690ef4..f8f0e315e4a8 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -1262,6 +1262,11 @@
<artifactId>camel-jasypt</artifactId>
<version>4.21.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-java-io</artifactId>
+ <version>4.21.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-java-joor-dsl</artifactId>
diff --git a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
index 3fac54babeb1..4157100fface 100644
--- a/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/CamelContext.java
@@ -1714,16 +1714,18 @@ public interface CamelContext extends
CamelContextLifecycle, RuntimeConfiguratio
/**
* If dumping is enabled then Camel will during startup dump all loaded
routes (incl rests and route templates)
- * represented as XML/YAML DSL into the log. This is intended for trouble
shooting or to assist during development.
+ * represented as XML, YAML, or Java DSL into the log. This is intended
for trouble shooting or to assist during
+ * development.
*
* Sensitive information that may be configured in the route endpoints
could potentially be included in the dump
* output and is therefore not recommended being used for production usage.
*
- * This requires to have camel-xml-io/camel-yaml-io on the classpath to be
able to dump the routes as XML/YAML.
+ * This requires to have camel-xml-io/camel-yaml-io/camel-java-io on the
classpath to be able to dump the routes as
+ * XML/YAML/Java.
*
* Using json is a special feature to dump route structure in JSon which
can be useful for tooling.
*
- * @param format xml, yaml or json (additional configuration can be
specified using query parameters, eg
+ * @param format xml, yaml, java, or json (additional configuration can be
specified using query parameters, eg
* ?include=all&uriAsParameters=true)
*/
void setDumpRoutes(@Nullable String format);
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java
b/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java
index d60b3f59ce82..fe58d62091eb 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/DumpRoutesStrategy.java
@@ -33,7 +33,7 @@ public interface DumpRoutesStrategy extends StaticService {
/**
* Dump routes
*
- * @param format xml or yaml (json for route structure)
+ * @param format xml, yaml, or java (json for route structure)
*/
void dumpRoutes(String format);
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
new file mode 100644
index 000000000000..c8080cd1e19b
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ModelToJavaDumper.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spi;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.NamedNode;
+
+/**
+ * SPI for dumping model definitions into Java DSL representation.
+ *
+ * @since 4.21
+ */
+public interface ModelToJavaDumper {
+
+ /**
+ * Service factory key.
+ */
+ String FACTORY = "modeljava-dumper";
+
+ /**
+ * Dumps the definition as Java DSL
+ *
+ * @param context the CamelContext
+ * @param definition the definition, such as a {@link NamedNode}
+ * @return the output in Java DSL (is formatted)
+ * @throws Exception is throw if error marshalling to Java DSL
+ */
+ String dumpModelAsJava(CamelContext context, NamedNode definition) 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
+ * @return the output in Java DSL (is formatted)
+ * @throws Exception is throw if error marshalling to Java DSL
+ */
+ String dumpModelAsJava(
+ CamelContext context, NamedNode definition,
+ boolean resolvePlaceholders, boolean generatedIds)
+ throws Exception;
+
+}
diff --git
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index d2b056f2ff58..c07f7b7bafef 100644
---
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -139,6 +139,7 @@ import org.apache.camel.spi.ManagementStrategy;
import org.apache.camel.spi.MessageHistoryFactory;
import org.apache.camel.spi.MessageSizeStrategy;
import org.apache.camel.spi.ModelJAXBContextFactory;
+import org.apache.camel.spi.ModelToJavaDumper;
import org.apache.camel.spi.ModelToStructureDumper;
import org.apache.camel.spi.ModelToXMLDumper;
import org.apache.camel.spi.ModelToYAMLDumper;
@@ -405,6 +406,7 @@ public abstract class AbstractCamelContext extends
BaseService
camelContextExtension.lazyAddContextPlugin(BeanProcessorFactory.class,
this::createBeanProcessorFactory);
camelContextExtension.lazyAddContextPlugin(ModelToXMLDumper.class,
this::createModelToXMLDumper);
camelContextExtension.lazyAddContextPlugin(ModelToYAMLDumper.class,
this::createModelToYAMLDumper);
+ camelContextExtension.lazyAddContextPlugin(ModelToJavaDumper.class,
this::createModelToJavaDumper);
camelContextExtension.lazyAddContextPlugin(ModelToStructureDumper.class,
this::createModelToStructureDumper);
camelContextExtension.lazyAddContextPlugin(DeferServiceFactory.class,
this::createDeferServiceFactory);
camelContextExtension.lazyAddContextPlugin(AnnotationBasedProcessorFactory.class,
@@ -4592,6 +4594,8 @@ public abstract class AbstractCamelContext extends
BaseService
protected abstract ModelToYAMLDumper createModelToYAMLDumper();
+ protected abstract ModelToJavaDumper createModelToJavaDumper();
+
protected abstract ModelToStructureDumper createModelToStructureDumper();
protected abstract RestBindingJaxbDataFormatFactory
createRestBindingJaxbDataFormatFactory();
diff --git
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index bbef1f98be5a..8fe587dd8baa 100644
---
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -71,6 +71,7 @@ import org.apache.camel.spi.ManagementNameStrategy;
import org.apache.camel.spi.MessageHistoryFactory;
import org.apache.camel.spi.MessageSizeStrategy;
import org.apache.camel.spi.ModelJAXBContextFactory;
+import org.apache.camel.spi.ModelToJavaDumper;
import org.apache.camel.spi.ModelToStructureDumper;
import org.apache.camel.spi.ModelToXMLDumper;
import org.apache.camel.spi.ModelToYAMLDumper;
@@ -552,6 +553,14 @@ public class SimpleCamelContext extends
AbstractCamelContext {
"camel-yaml-io");
}
+ @Override
+ protected ModelToJavaDumper createModelToJavaDumper() {
+ return
ResolverHelper.resolveMandatoryBootstrapService(getCamelContextReference(),
+ ModelToJavaDumper.FACTORY,
+ ModelToJavaDumper.class,
+ "camel-java-io");
+ }
+
@Override
protected ModelToStructureDumper createModelToStructureDumper() {
return
ResolverHelper.resolveMandatoryBootstrapService(getCamelContextReference(),
diff --git
a/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/route-dump.json
b/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/route-dump.json
index 8fe9c46e8fd9..97dc896314d6 100644
---
a/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/route-dump.json
+++
b/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/route-dump.json
@@ -4,7 +4,7 @@
"group": "camel",
"name": "route-dump",
"title": "Route Dump",
- "description": "Dump route in XML or YAML format",
+ "description": "Dump route in XML, YAML, or Java DSL format",
"deprecated": false,
"javaType": "org.apache.camel.impl.console.RouteDumpDevConsole",
"groupId": "org.apache.camel",
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 e7b68689c199..01db8c942baa 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
@@ -40,7 +40,7 @@ import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
import org.apache.camel.util.json.Jsoner;
-@DevConsole(name = "route-dump", description = "Dump route in XML or YAML
format")
+@DevConsole(name = "route-dump", description = "Dump route in XML, YAML, or
Java DSL format")
public class RouteDumpDevConsole extends AbstractDevConsole {
private static final Pattern XML_SOURCE_LOCATION_PATTERN =
Pattern.compile("(\\ssourceLocation=\"(.*?)\")");
@@ -67,7 +67,7 @@ public class RouteDumpDevConsole extends AbstractDevConsole {
public static final String URI_AS_PARAMETERS = "uriAsParameters";
public RouteDumpDevConsole() {
- super("camel", "route-dump", "Route Dump", "Dump route in XML or YAML
format");
+ super("camel", "route-dump", "Route Dump", "Dump route in XML, YAML,
or Java DSL format");
}
@Override
@@ -83,6 +83,8 @@ public class RouteDumpDevConsole extends AbstractDevConsole {
dump = mrb.dumpRouteAsXml(true);
} else if ("yaml".equals(format)) {
dump = mrb.dumpRouteAsYaml(true,
"true".equals(uriAsParameters));
+ } else if ("java".equals(format)) {
+ dump = mrb.dumpRouteAsJava(true);
}
} catch (Exception e) {
// ignore
@@ -132,13 +134,16 @@ public class RouteDumpDevConsole extends
AbstractDevConsole {
} else if ("yaml".equals(format)) {
jo.put("format", "yaml");
dump = mrb.dumpRouteAsYaml(true,
"true".equals(uriAsParameters), false, true);
+ } else if ("java".equals(format)) {
+ jo.put("format", "java");
+ dump = mrb.dumpRouteAsJava(true);
}
if (dump != null) {
JsonArray code;
if (format == null || "xml".equals(format)) {
code = xmlLoadSourceAsJson(new StringReader(dump));
} else {
- code = yamlLoadSourceAsJson(new StringReader(dump));
+ code = javaOrYamlLoadSourceAsJson(new
StringReader(dump));
}
if (code != null) {
jo.put("code", code);
@@ -226,7 +231,7 @@ public class RouteDumpDevConsole extends AbstractDevConsole
{
return code.isEmpty() ? null : code;
}
- private static JsonArray yamlLoadSourceAsJson(Reader reader) {
+ private static JsonArray javaOrYamlLoadSourceAsJson(Reader reader) {
JsonArray code = new JsonArray();
try {
LineNumberReader lnr = new LineNumberReader(reader);
diff --git
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
index 78221765535e..4a3fb4211e3e 100644
---
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
+++
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java
@@ -44,6 +44,7 @@ import org.apache.camel.model.rest.RestDefinition;
import org.apache.camel.model.rest.RestsDefinition;
import org.apache.camel.spi.DumpRoutesStrategy;
import org.apache.camel.spi.ModelDumpLine;
+import org.apache.camel.spi.ModelToJavaDumper;
import org.apache.camel.spi.ModelToStructureDumper;
import org.apache.camel.spi.ModelToXMLDumper;
import org.apache.camel.spi.ModelToYAMLDumper;
@@ -176,6 +177,8 @@ public class DefaultDumpRoutesStrategy extends
ServiceSupport implements DumpRou
doDumpRoutesAsYaml(camelContext);
} else if ("xml".equalsIgnoreCase(format)) {
doDumpRoutesAsXml(camelContext);
+ } else if ("java".equalsIgnoreCase(format)) {
+ doDumpRoutesAsJava(camelContext);
} else if ("json".equals(format)) {
doDumpRoutesStructureAsJSon(camelContext);
} else if ("png".equals(format)) {
@@ -451,6 +454,146 @@ public class DefaultDumpRoutesStrategy extends
ServiceSupport implements DumpRou
}
+ protected void doDumpRoutesAsJava(CamelContext camelContext) {
+ final ModelToJavaDumper dumper =
PluginHelper.getModelToJavaDumper(camelContext);
+ final Model model =
camelContext.getCamelContextExtension().getContextPlugin(Model.class);
+ final DummyResource dummy = new DummyResource(null, null);
+ final Set<String> files = new HashSet<>();
+
+ if (include.contains("*") || include.contains("all") ||
include.contains("rests")) {
+ int size = model.getRestDefinitions().size();
+ if (size > 0) {
+ Map<Resource, RestsDefinition> groups = new LinkedHashMap<>();
+ for (RestDefinition rest : model.getRestDefinitions()) {
+ Resource res = rest.getResource();
+ if (res == null) {
+ res = dummy;
+ }
+ RestsDefinition rests = groups.computeIfAbsent(res,
resource -> new RestsDefinition());
+ rests.getRests().add(rest);
+ }
+ StringBuilder sbLog = new StringBuilder();
+ for (Map.Entry<Resource, RestsDefinition> entry :
groups.entrySet()) {
+ RestsDefinition def = entry.getValue();
+ Resource resource = entry.getKey();
+
+ StringBuilder sbLocal = new StringBuilder();
+ doDumpJava(camelContext, def, resource == dummy ? null :
resource, dumper, "rests", sbLocal, sbLog);
+ doDumpToDirectory(resource, sbLocal, "rests", "java",
files);
+ }
+ if (!sbLog.isEmpty() && log) {
+ LOG.info("Dumping {} rests as Java", size);
+ LOG.info("{}", sbLog);
+ }
+ }
+ }
+
+ if (include.contains("*") || include.contains("all") ||
include.contains("routeConfigurations")
+ || include.contains("route-configurations")) {
+ int size = model.getRouteConfigurationDefinitions().size();
+ if (size > 0) {
+ Map<Resource, RouteConfigurationsDefinition> groups = new
LinkedHashMap<>();
+ for (RouteConfigurationDefinition config :
model.getRouteConfigurationDefinitions()) {
+ Resource res = config.getResource();
+ if (res == null) {
+ res = dummy;
+ }
+ RouteConfigurationsDefinition routes
+ = groups.computeIfAbsent(res, resource -> new
RouteConfigurationsDefinition());
+ routes.getRouteConfigurations().add(config);
+ }
+ StringBuilder sbLog = new StringBuilder();
+ for (Map.Entry<Resource, RouteConfigurationsDefinition> entry
: groups.entrySet()) {
+ RouteConfigurationsDefinition def = entry.getValue();
+ Resource resource = entry.getKey();
+
+ StringBuilder sbLocal = new StringBuilder();
+ doDumpJava(camelContext, def, resource == dummy ? null :
resource, dumper, "route-configurations", sbLocal,
+ sbLog);
+ doDumpToDirectory(resource, sbLocal,
"route-configurations", "java", files);
+ }
+ if (!sbLog.isEmpty() && log) {
+ LOG.info("Dumping {} route-configurations as Java", size);
+ LOG.info("{}", sbLog);
+ }
+ }
+ }
+
+ if (include.contains("*") || include.contains("all") ||
include.contains("routeTemplates")
+ || include.contains("route-templates")) {
+ int size = model.getRouteTemplateDefinitions().size();
+ if (size > 0) {
+ Map<Resource, RouteTemplatesDefinition> groups = new
LinkedHashMap<>();
+ for (RouteTemplateDefinition rt :
model.getRouteTemplateDefinitions()) {
+ Resource res = rt.getResource();
+ if (res == null) {
+ res = dummy;
+ }
+ RouteTemplatesDefinition rests =
groups.computeIfAbsent(res, resource -> new RouteTemplatesDefinition());
+ rests.getRouteTemplates().add(rt);
+ }
+ StringBuilder sbLog = new StringBuilder();
+ for (Map.Entry<Resource, RouteTemplatesDefinition> entry :
groups.entrySet()) {
+ RouteTemplatesDefinition def = entry.getValue();
+ Resource resource = entry.getKey();
+
+ StringBuilder sbLocal = new StringBuilder();
+ doDumpJava(camelContext, def, resource == dummy ? null :
resource, dumper, "route-templates", sbLocal,
+ sbLog);
+ doDumpToDirectory(resource, sbLocal, "route-templates",
"java", files);
+ }
+ if (!sbLog.isEmpty() && log) {
+ LOG.info("Dumping {} route-templates as Java", size);
+ LOG.info("{}", sbLog);
+ }
+ }
+ }
+
+ if (include.contains("*") || include.contains("all") ||
include.contains("routes")) {
+ int size = model.getRouteDefinitions().size();
+ if (size > 0) {
+ Map<Resource, RoutesDefinition> groups = new LinkedHashMap<>();
+ for (RouteDefinition route : model.getRouteDefinitions()) {
+ if ((route.isRest() != null && route.isRest()) ||
(route.isTemplate() != null && route.isTemplate())) {
+ continue;
+ }
+ Resource res = route.getResource();
+ if (res == null) {
+ res = dummy;
+ }
+ RoutesDefinition routes = groups.computeIfAbsent(res,
resource -> new RoutesDefinition());
+ routes.getRoutes().add(route);
+ }
+ StringBuilder sbLog = new StringBuilder();
+ for (Map.Entry<Resource, RoutesDefinition> entry :
groups.entrySet()) {
+ RoutesDefinition def = entry.getValue();
+ Resource resource = entry.getKey();
+
+ StringBuilder sbLocal = new StringBuilder();
+ doDumpJava(camelContext, def, resource == dummy ? null :
resource, dumper, "routes", sbLocal, sbLog);
+ doDumpToDirectory(resource, sbLocal, "routes", "java",
files);
+ }
+ if (!sbLog.isEmpty() && log) {
+ LOG.info("Dumping {} routes as Java", size);
+ LOG.info("{}", sbLog);
+ }
+ }
+ }
+
+ }
+
+ protected void doDumpJava(
+ CamelContext camelContext, NamedNode def, Resource resource,
+ ModelToJavaDumper dumper, String kind, StringBuilder sbLocal,
StringBuilder sbLog) {
+ try {
+ String dump = dumper.dumpModelAsJava(camelContext, def,
resolvePlaceholders, generatedIds);
+ sbLocal.append(dump);
+ appendLogDump(resource, dump, sbLog);
+ } catch (Exception e) {
+ LOG.warn("Error dumping {}} to Java due to {}. This exception is
ignored.", kind, e.getMessage(), e);
+ }
+ }
+
protected void doDumpYaml(
CamelContext camelContext, NamedNode def, Resource resource,
ModelToYAMLDumper dumper, String kind, StringBuilder sbLocal,
StringBuilder sbLog) {
diff --git
a/core/camel-java-io/src/generated/resources/META-INF/services/org/apache/camel/modeljava-dumper
b/core/camel-java-io/src/generated/resources/META-INF/services/org/apache/camel/modeljava-dumper
new file mode 100644
index 000000000000..4b977fcd082d
--- /dev/null
+++
b/core/camel-java-io/src/generated/resources/META-INF/services/org/apache/camel/modeljava-dumper
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.java.LwModelToJavaDumper
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
new file mode 100644
index 000000000000..ef9705f33c16
--- /dev/null
+++
b/core/camel-java-io/src/main/java/org/apache/camel/java/LwModelToJavaDumper.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.java;
+
+import java.util.Collection;
+import java.util.Properties;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.NamedNode;
+import org.apache.camel.model.FromDefinition;
+import org.apache.camel.model.RouteConfigurationDefinition;
+import org.apache.camel.model.RouteConfigurationsDefinition;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RouteTemplateDefinition;
+import org.apache.camel.model.RouteTemplatesDefinition;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.SendDefinition;
+import org.apache.camel.model.ToDynamicDefinition;
+import org.apache.camel.model.rest.RestConfigurationDefinition;
+import org.apache.camel.model.rest.RestDefinition;
+import org.apache.camel.model.rest.RestsDefinition;
+import org.apache.camel.model.transformer.TransformerDefinition;
+import org.apache.camel.model.transformer.TransformersDefinition;
+import org.apache.camel.model.validator.ValidatorDefinition;
+import org.apache.camel.model.validator.ValidatorsDefinition;
+import org.apache.camel.spi.ModelToJavaDumper;
+import org.apache.camel.spi.annotations.JdkService;
+
+import static
org.apache.camel.model.ProcessorDefinitionHelper.filterTypeInOutputs;
+
+/**
+ * Lightweight {@link ModelToJavaDumper} based on the generated {@link
org.apache.camel.java.out.JavaDslModelWriter}.
+ */
+@JdkService(ModelToJavaDumper.FACTORY)
+public class LwModelToJavaDumper implements ModelToJavaDumper {
+
+ @Override
+ public String dumpModelAsJava(CamelContext context, NamedNode definition)
throws Exception {
+ return dumpModelAsJava(context, definition, false, true);
+ }
+
+ @Override
+ public String dumpModelAsJava(
+ CamelContext context, NamedNode definition,
+ boolean resolvePlaceholders, boolean generatedIds)
+ throws Exception {
+
+ Properties properties = new Properties();
+ if (definition instanceof RouteTemplatesDefinition templates) {
+ templates.getRouteTemplates().forEach(template -> {
+ resolveEndpointDslUris(template.getRoute());
+ collectTemplateProperties(template, properties);
+ });
+ } else if (definition instanceof RouteTemplateDefinition template) {
+ resolveEndpointDslUris(template.getRoute());
+ collectTemplateProperties(template, properties);
+ } else if (definition instanceof RoutesDefinition routes) {
+
routes.getRoutes().forEach(LwModelToJavaDumper::resolveEndpointDslUris);
+ } else if (definition instanceof RouteDefinition route) {
+ resolveEndpointDslUris(route);
+ }
+
+ org.apache.camel.java.out.JavaDslModelWriter writer = new
org.apache.camel.java.out.JavaDslModelWriter();
+
+ StringBuilder sb = new StringBuilder();
+ if (definition instanceof RoutesDefinition rd) {
+ for (RouteDefinition route : rd.getRoutes()) {
+ if (!sb.isEmpty()) {
+ sb.append("\n\n");
+ }
+ sb.append(writer.writeRouteDefinition(route));
+ }
+ } else if (definition instanceof RouteDefinition route) {
+ sb.append(writer.writeRouteDefinition(route));
+ } else if (definition instanceof RouteTemplatesDefinition rtd) {
+ for (RouteTemplateDefinition template : rtd.getRouteTemplates()) {
+ if (!sb.isEmpty()) {
+ sb.append("\n\n");
+ }
+ sb.append(writer.writeRouteTemplateDefinition(template));
+ }
+ } else if (definition instanceof RouteTemplateDefinition template) {
+ sb.append(writer.writeRouteTemplateDefinition(template));
+ } else if (definition instanceof RestsDefinition rd) {
+ for (RestDefinition rest : rd.getRests()) {
+ if (!sb.isEmpty()) {
+ sb.append("\n\n");
+ }
+ sb.append(writer.writeRestDefinition(rest));
+ }
+ } else if (definition instanceof RestDefinition rest) {
+ sb.append(writer.writeRestDefinition(rest));
+ } else if (definition instanceof RouteConfigurationsDefinition rcd) {
+ for (RouteConfigurationDefinition config :
rcd.getRouteConfigurations()) {
+ if (!sb.isEmpty()) {
+ sb.append("\n\n");
+ }
+ sb.append(writer.writeRouteConfigurationDefinition(config));
+ }
+ } else if (definition instanceof RouteConfigurationDefinition config) {
+ sb.append(writer.writeRouteConfigurationDefinition(config));
+ } else if (definition instanceof RestConfigurationDefinition
restConfig) {
+ sb.append(writer.writeRestConfigurationDefinition(restConfig));
+ } else if (definition instanceof TransformersDefinition td) {
+ for (TransformerDefinition t : td.getTransformers()) {
+ if (!sb.isEmpty()) {
+ sb.append("\n\n");
+ }
+ sb.append(writer.writeTransformer(t));
+ }
+ } else if (definition instanceof ValidatorsDefinition vd) {
+ for (ValidatorDefinition v : vd.getValidators()) {
+ if (!sb.isEmpty()) {
+ sb.append("\n\n");
+ }
+ sb.append(writer.writeValidator(v));
+ }
+ }
+
+ String result = sb.toString();
+ if (resolvePlaceholders) {
+ result = resolvePlaceholders(context, result, properties);
+ }
+
+ return result;
+ }
+
+ private static void collectTemplateProperties(RouteTemplateDefinition
template, Properties properties) {
+ if (Boolean.TRUE.equals(template.getRoute().isTemplate())) {
+ java.util.Map<String, Object> parameters =
template.getRoute().getTemplateParameters();
+ if (parameters != null) {
+ properties.putAll(parameters);
+ }
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static void resolveEndpointDslUris(RouteDefinition route) {
+ if (route == null) {
+ return;
+ }
+ FromDefinition from = route.getInput();
+ if (from != null && from.getEndpointConsumerBuilder() != null) {
+ from.setUri(from.getEndpointConsumerBuilder().getRawUri());
+ }
+ Collection<SendDefinition> col =
filterTypeInOutputs(route.getOutputs(), SendDefinition.class);
+ for (SendDefinition<?> to : col) {
+ if (to.getEndpointProducerBuilder() != null) {
+ to.setUri(to.getEndpointProducerBuilder().getRawUri());
+ }
+ }
+ Collection<ToDynamicDefinition> col2 =
filterTypeInOutputs(route.getOutputs(), ToDynamicDefinition.class);
+ for (ToDynamicDefinition to : col2) {
+ if (to.getEndpointProducerBuilder() != null) {
+ to.setUri(to.getEndpointProducerBuilder().getRawUri());
+ }
+ }
+ }
+
+ private static String resolvePlaceholders(CamelContext context, String
text, Properties properties) {
+ context.getPropertiesComponent().setLocalProperties(properties);
+ try {
+ return context.resolvePropertyPlaceholders(text);
+ } catch (Exception e) {
+ return text;
+ } finally {
+ context.getPropertiesComponent().setLocalProperties(null);
+ }
+ }
+}
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 887cc21c6825..e47ba7d7c622 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
@@ -56,7 +56,7 @@
{ "name": "camel.main.contextReloadEnabled", "required": false,
"description": "Used for enabling context reloading. If enabled then Camel
allow external systems such as security vaults (AWS secrets manager, etc.) to
trigger refreshing Camel by updating property placeholders and reload all
existing routes to take changes into effect.", "sourceType":
"org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": false, "secret": false },
{ "name": "camel.main.description", "required": false, "description":
"Sets the description (intended for humans) of the Camel application.",
"sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type":
"string", "javaType": "java.lang.String", "secret": false },
{ "name": "camel.main.devConsoleEnabled", "required": false,
"description": "Whether to enable developer console (requires camel-console on
classpath). The developer console is only for assisting during development.
This is NOT for production usage.", "sourceType":
"org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": false, "secret": false, "security":
"insecure:dev" },
- { "name": "camel.main.dumpRoutes", "required": false, "description": "If
dumping is enabled then Camel will during startup dump all loaded routes (incl
rests and route templates) represented as XML\/YAML DSL into the log. This is
intended for trouble shooting or to assist during development. Sensitive
information that may be configured in the route endpoints could potentially be
included in the dump output and is therefore not recommended being used for
production usage. This require [...]
+ { "name": "camel.main.dumpRoutes", "required": false, "description": "If
dumping is enabled then Camel will during startup dump all loaded routes (incl
rests and route templates) represented as XML, YAML, or Java DSL into the log.
This is intended for trouble shooting or to assist during development.
Sensitive information that may be configured in the route endpoints could
potentially be included in the dump output and is therefore not recommended
being used for production usage. Thi [...]
{ "name": "camel.main.dumpRoutesGeneratedIds", "required": false,
"description": "Whether to include auto generated IDs in the dumped output.
Default is false.", "sourceType":
"org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": false, "secret": false },
{ "name": "camel.main.dumpRoutesInclude", "required": false,
"description": "Controls what to include in output for route dumping. Possible
values: all, routes, rests, routeConfigurations, routeTemplates, beans,
dataFormats. Multiple values can be separated by comma. Default is routes.",
"sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type":
"string", "javaType": "java.lang.String", "defaultValue": "routes", "secret":
false },
{ "name": "camel.main.dumpRoutesLog", "required": false, "description":
"Whether to log route dumps to Logger", "sourceType":
"org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean",
"javaType": "boolean", "defaultValue": true, "secret": false },
diff --git a/core/camel-main/src/main/docs/main.adoc
b/core/camel-main/src/main/docs/main.adoc
index 890332adbfe5..6dc9f34881fa 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -49,7 +49,7 @@ The camel.main supports 129 options, which are listed below.
| *camel.main.contextReloadEnabled* | Used for enabling context reloading. If
enabled then Camel allow external systems such as security vaults (AWS secrets
manager, etc.) to trigger refreshing Camel by updating property placeholders
and reload all existing routes to take changes into effect. | false | boolean
| *camel.main.description* | Sets the description (intended for humans) of the
Camel application. | | String
| *camel.main.devConsoleEnabled* | Whether to enable developer console
(requires camel-console on classpath). The developer console is only for
assisting during development. This is NOT for production usage. | false |
boolean
-| *camel.main.dumpRoutes* | If dumping is enabled then Camel will during
startup dump all loaded routes (incl rests and route templates) represented as
XML/YAML DSL into the log. This is intended for trouble shooting or to assist
during development. Sensitive information that may be configured in the route
endpoints could potentially be included in the dump output and is therefore not
recommended being used for production usage. This requires to have
camel-xml-io/camel-yaml-io on the cla [...]
+| *camel.main.dumpRoutes* | If dumping is enabled then Camel will during
startup dump all loaded routes (incl rests and route templates) represented as
XML, YAML, or Java DSL into the log. This is intended for trouble shooting or
to assist during development. Sensitive information that may be configured in
the route endpoints could potentially be included in the dump output and is
therefore not recommended being used for production usage. This requires to
have camel-xml-io/camel-yaml-io/ [...]
| *camel.main.dumpRoutesGeneratedIds* | Whether to include auto generated IDs
in the dumped output. Default is false. | false | boolean
| *camel.main.dumpRoutesInclude* | Controls what to include in output for
route dumping. Possible values: all, routes, rests, routeConfigurations,
routeTemplates, beans, dataFormats. Multiple values can be separated by comma.
Default is routes. | routes | String
| *camel.main.dumpRoutesLog* | Whether to log route dumps to Logger | true |
boolean
diff --git
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index 42489e639866..3663ee3f1564 100644
---
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -1540,12 +1540,14 @@ public abstract class DefaultConfigurationProperties<T>
{
/**
* If dumping is enabled then Camel will during startup dump all loaded
routes (incl rests and route templates)
- * represented as XML/YAML DSL into the log. This is intended for trouble
shooting or to assist during development.
+ * represented as XML, YAML, or Java DSL into the log. This is intended
for trouble shooting or to assist during
+ * development.
*
* Sensitive information that may be configured in the route endpoints
could potentially be included in the dump
* output and is therefore not recommended being used for production usage.
*
- * This requires to have camel-xml-io/camel-yaml-io on the classpath to be
able to dump the routes as XML/YAML.
+ * This requires to have camel-xml-io/camel-yaml-io/camel-java-io on the
classpath to be able to dump the routes as
+ * XML/YAML/Java.
*
* You can also use JSon which dumps the route structure in JSon. The JSon
does not represent Camel DSL but it
* useful for tooling to understand the structure of the routes and how
EIPs are nested together.
@@ -2754,12 +2756,14 @@ public abstract class DefaultConfigurationProperties<T>
{
/**
* If dumping is enabled then Camel will during startup dump all loaded
routes (incl rests and route templates)
- * represented as XML/YAML DSL into the log. This is intended for trouble
shooting or to assist during development.
+ * represented as XML, YAML, or Java DSL into the log. This is intended
for trouble shooting or to assist during
+ * development.
*
* Sensitive information that may be configured in the route endpoints
could potentially be included in the dump
* output and is therefore not recommended being used for production usage.
*
- * This requires to have camel-xml-io/camel-yaml-io on the classpath to be
able to dump the routes as XML/YAML.
+ * This requires to have camel-xml-io/camel-yaml-io/camel-java-io on the
classpath to be able to dump the routes as
+ * XML/YAML/Java.
*
* You can also use JSon which dumps the route structure in JSon. The JSon
does not represent Camel DSL but it
* useful for tooling to understand the structure of the routes and how
EIPs are nested together.
diff --git
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
index 28cdad9e6892..e396931362a0 100644
---
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
+++
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
@@ -257,6 +257,12 @@ public interface ManagedCamelContextMBean extends
ManagedPerformanceCounterMBean
String dumpRoutesAsYaml(boolean resolvePlaceholders, boolean
uriAsParameters, boolean generatedIds, boolean sourceLocation)
throws Exception;
+ @ManagedOperation(description = "Dumps the routes as Java DSL")
+ String dumpRoutesAsJava() throws Exception;
+
+ @ManagedOperation(description = "Dumps the routes as Java DSL")
+ String dumpRoutesAsJava(boolean resolvePlaceholders) throws Exception;
+
/**
* Creates the endpoint by the given uri
*
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 cfc54f8118ec..0519b423ff8b 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
@@ -155,6 +155,12 @@ public interface ManagedRouteMBean extends
ManagedPerformanceCounterMBean {
String dumpRouteAsYaml(boolean resolvePlaceholders, boolean
uriAsParameters, boolean generatedIds, boolean sourceLocation)
throws Exception;
+ @ManagedOperation(description = "Dumps the route as Java DSL")
+ String dumpRouteAsJava() throws Exception;
+
+ @ManagedOperation(description = "Dumps the route as Java DSL")
+ String dumpRouteAsJava(boolean resolvePlaceholders) 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/ManagedCamelContext.java
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index c495526f7821..37e8ab2c38ad 100644
---
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -635,6 +635,24 @@ public class ManagedCamelContext extends
ManagedPerformanceCounter implements Ti
generatedIds, sourceLocation);
}
+ @Override
+ public String dumpRoutesAsJava() throws Exception {
+ return dumpRoutesAsJava(false);
+ }
+
+ @Override
+ public String dumpRoutesAsJava(boolean resolvePlaceholders) throws
Exception {
+ List<RouteDefinition> routes =
context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinitions();
+ if (routes.isEmpty()) {
+ return null;
+ }
+
+ RoutesDefinition def = new RoutesDefinition();
+ def.setRoutes(routes);
+
+ return
PluginHelper.getModelToJavaDumper(context).dumpModelAsJava(context, def,
resolvePlaceholders, true);
+ }
+
@Override
public String dumpRouteTemplatesAsXml() throws Exception {
List<RouteTemplateDefinition> templates
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 240b6d159239..deac037f2286 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
@@ -494,6 +494,22 @@ public class ManagedRoute extends
ManagedPerformanceCounter implements TimerList
return null;
}
+ @Override
+ public String dumpRouteAsJava() throws Exception {
+ return dumpRouteAsJava(false);
+ }
+
+ @Override
+ public String dumpRouteAsJava(boolean resolvePlaceholders) 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, true);
+ }
+
+ return null;
+ }
+
@Override
public String dumpRouteStatsAsXml(boolean fullStats, boolean
includeProcessors) throws Exception {
// in this logic we need to calculate the accumulated processing time
for the processor in the route
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/PluginHelper.java
b/core/camel-support/src/main/java/org/apache/camel/support/PluginHelper.java
index 99c33772c33c..e33122a682ed 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/PluginHelper.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/PluginHelper.java
@@ -41,6 +41,7 @@ import org.apache.camel.spi.InterceptEndpointFactory;
import org.apache.camel.spi.InternalProcessorFactory;
import org.apache.camel.spi.LanguageResolver;
import org.apache.camel.spi.ModelJAXBContextFactory;
+import org.apache.camel.spi.ModelToJavaDumper;
import org.apache.camel.spi.ModelToStructureDumper;
import org.apache.camel.spi.ModelToXMLDumper;
import org.apache.camel.spi.ModelToYAMLDumper;
@@ -564,12 +565,26 @@ public final class PluginHelper {
}
/**
- * Gets the {@link ModelToXMLDumper} to be used.
+ * Gets the {@link ModelToYAMLDumper} to be used.
*/
public static ModelToYAMLDumper getModelToYAMLDumper(ExtendedCamelContext
extendedCamelContext) {
return extendedCamelContext.getContextPlugin(ModelToYAMLDumper.class);
}
+ /**
+ * Gets the {@link ModelToJavaDumper} to be used.
+ */
+ public static ModelToJavaDumper getModelToJavaDumper(CamelContext
camelContext) {
+ return getModelToJavaDumper(camelContext.getCamelContextExtension());
+ }
+
+ /**
+ * Gets the {@link ModelToJavaDumper} to be used.
+ */
+ public static ModelToJavaDumper getModelToJavaDumper(ExtendedCamelContext
extendedCamelContext) {
+ return extendedCamelContext.getContextPlugin(ModelToJavaDumper.class);
+ }
+
/**
* Gets the {@link ModelToStructureDumper} to be used.
*/
diff --git
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-get-route-dump.adoc
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-get-route-dump.adoc
index 8f1f3302eb40..1cc3cc3622c9 100644
---
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-get-route-dump.adoc
+++
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-get-route-dump.adoc
@@ -2,7 +2,7 @@
// AUTO-GENERATED by camel-package-maven-plugin - DO NOT EDIT THIS FILE
= camel get route-dump
-Dump Camel route in XML or YAML format
+Dump Camel route in XML, YAML, or Java DSL format
== Usage
@@ -20,7 +20,7 @@ camel get route-dump [options]
|===
| Option | Description | Default | Type
| `--filter` | Filter route by filename or route id (multiple names can be
separated by comma) | | String
-| `--format` | Output format (xml, or yaml) | yaml | String
+| `--format` | Output format (xml, yaml, or java) | yaml | String
| `--raw` | To output raw without metadata | | boolean
| `--sort` | Sort route by name or id | name | String
| `--uri-as-parameters` | Whether to expand URIs into separated key/value
parameters (only in use for YAML format) | true | boolean
diff --git
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-get.adoc
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-get.adoc
index 91dbbbb51184..e96ca2f286c1 100644
--- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-get.adoc
+++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-get.adoc
@@ -42,7 +42,7 @@ camel get [options]
| xref:jbang-commands/camel-jbang-get-rest.adoc[rest] | Get REST services of
Camel integrations
| xref:jbang-commands/camel-jbang-get-route.adoc[route] | Get status of Camel
routes
| xref:jbang-commands/camel-jbang-get-route-controller.adoc[route-controller]
| List status of route controller
-| xref:jbang-commands/camel-jbang-get-route-dump.adoc[route-dump] | Dump Camel
route in XML or YAML format
+| xref:jbang-commands/camel-jbang-get-route-dump.adoc[route-dump] | Dump Camel
route in XML, YAML, or Java DSL format
| xref:jbang-commands/camel-jbang-get-service.adoc[service] | Get services of
Camel integrations
| xref:jbang-commands/camel-jbang-get-source.adoc[source] | Display Camel
route source code
| xref:jbang-commands/camel-jbang-get-startup-recorder.adoc[startup-recorder]
| Display startup recording
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
index 8ea30e87078f..0a818cf9c8f3 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
+++
b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
@@ -15,7 +15,7 @@
{ "name": "eval", "fullName": "eval", "description": "Evaluate Camel
expressions and scripts", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.EvalCommand", "options": [ { "names":
"-h,--help", "description": "Display the help and sub-commands", "javaType":
"boolean", "type": "boolean" } ], "subcommands": [ { "name": "expression",
"fullName": "eval expression", "description": "Evaluates Camel expression",
"sourceClass": "org.apache.camel.dsl.jbang.core.commands.action.EvalEx [...]
{ "name": "explain", "fullName": "explain", "description": "Explain what a
Camel route does using AI\/LLM", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.Explain", "options": [ { "names":
"--api-key", "description": "API key for authentication. Also reads
ANTHROPIC_API_KEY, OPENAI_API_KEY, or LLM_API_KEY env vars", "javaType":
"java.lang.String", "type": "string" }, { "names": "--api-type", "description":
"API type: 'ollama', 'openai' (OpenAI-compatible), or 'anthropic' (A [...]
{ "name": "export", "fullName": "export", "description": "Export to other
runtimes (Camel Main, Spring Boot, or Quarkus)", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.Export", "options": [ { "names":
"--build-property", "description": "Maven build properties, ex.
--build-property=prop1=foo", "javaType": "java.util.List", "type": "array" }, {
"names": "--camel-spring-boot-version", "description": "Camel version to use
with Spring Boot", "javaType": "java.lang.String", "ty [...]
- { "name": "get", "fullName": "get", "description": "Get status of Camel
integrations", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.process.CamelStatus", "options": [ {
"names": "--watch", "description": "Execute periodically and showing output
fullscreen", "javaType": "boolean", "type": "boolean" }, { "names":
"-h,--help", "description": "Display the help and sub-commands", "javaType":
"boolean", "type": "boolean" } ], "subcommands": [ { "name": "bean",
"fullName": "get [...]
+ { "name": "get", "fullName": "get", "description": "Get status of Camel
integrations", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.process.CamelStatus", "options": [ {
"names": "--watch", "description": "Execute periodically and showing output
fullscreen", "javaType": "boolean", "type": "boolean" }, { "names":
"-h,--help", "description": "Display the help and sub-commands", "javaType":
"boolean", "type": "boolean" } ], "subcommands": [ { "name": "bean",
"fullName": "get [...]
{ "name": "harden", "fullName": "harden", "description": "Suggest security
hardening for Camel routes using AI\/LLM", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.Harden", "options": [ { "names":
"--api-key", "description": "API key for authentication. Also reads
OPENAI_API_KEY or LLM_API_KEY env vars", "javaType": "java.lang.String",
"type": "string" }, { "names": "--api-type", "description": "API type: 'ollama'
or 'openai' (OpenAI-compatible)", "defaultValue": "ollama", [...]
{ "name": "hawtio", "fullName": "hawtio", "description": "Launch Hawtio
web console", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.process.Hawtio", "options": [ {
"names": "--host", "description": "Hostname to bind the Hawtio web console to",
"defaultValue": "127.0.0.1", "javaType": "java.lang.String", "type": "string"
}, { "names": "--openUrl", "description": "To automatic open Hawtio web console
in the web browser", "defaultValue": "true", "javaType": "boolean", "type":
[...]
{ "name": "infra", "fullName": "infra", "description": "List and Run
external services for testing and prototyping", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.infra.InfraCommand", "options": [ {
"names": "--json", "description": "Output in JSON Format", "javaType":
"boolean", "type": "boolean" }, { "names": "-h,--help", "description": "Display
the help and sub-commands", "javaType": "boolean", "type": "boolean" } ],
"subcommands": [ { "name": "get", "fullName": "infra [...]
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java
index 0bde02505a45..ccdb0c32984e 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelRouteDumpAction.java
@@ -35,7 +35,7 @@ import picocli.CommandLine.Command;
import static
org.apache.camel.support.LoggerHelper.stripSourceLocationLineNumber;
-@Command(name = "route-dump", description = "Dump Camel route in XML or YAML
format", sortOptions = false,
+@Command(name = "route-dump", description = "Dump Camel route in XML, YAML, or
Java DSL format", sortOptions = false,
showDefaultValues = true,
footer = {
"%nExamples:",
@@ -62,7 +62,7 @@ public class CamelRouteDumpAction extends ActionBaseCommand {
@Override
public Iterator<String> iterator() {
- return List.of("yaml", "xml").iterator();
+ return List.of("yaml", "xml", "java").iterator();
}
}
@@ -71,7 +71,7 @@ public class CamelRouteDumpAction extends ActionBaseCommand {
String name = "*";
@CommandLine.Option(names = { "--format" }, completionCandidates =
FormatCompletionCandidates.class,
- description = "Output format (xml, or yaml)",
defaultValue = "yaml")
+ description = "Output format (xml, yaml, or java)",
defaultValue = "yaml")
String format;
@CommandLine.Option(names = { "--raw" },
diff --git
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/RuntimeTools.java
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/RuntimeTools.java
index 2a00858f51d3..8c4eace1783a 100644
---
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/RuntimeTools.java
+++
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/RuntimeTools.java
@@ -169,11 +169,11 @@ public class RuntimeTools {
}
@Tool(annotations = @Tool.Annotations(readOnlyHint = true, destructiveHint
= false, openWorldHint = false),
- description = "Dump route definitions in XML or YAML format.")
+ description = "Dump route definitions in XML, YAML, or Java DSL
format.")
public JsonObject camel_runtime_route_dump(
@ToolArg(description = NAME_OR_PID_DESC) String nameOrPid,
@ToolArg(description = "Route ID to dump (use * for all routes)")
String routeId,
- @ToolArg(description = "Output format: xml or yaml (default:
yaml)") String format) {
+ @ToolArg(description = "Output format: xml, yaml, or java
(default: yaml)") String format) {
RuntimeService.ProcessInfo p =
runtimeService.findSingleProcess(nameOrPid);
return runtimeService.executeAction(p.pid(), "route-dump", root -> {
root.put("id", routeId != null ? routeId : "*");
diff --git a/dsl/camel-kamelet-main/pom.xml b/dsl/camel-kamelet-main/pom.xml
index 6201643b7f0f..d0967ea3e058 100644
--- a/dsl/camel-kamelet-main/pom.xml
+++ b/dsl/camel-kamelet-main/pom.xml
@@ -80,6 +80,10 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-xml-io</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-java-io</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-bean</artifactId>
diff --git
a/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
b/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
index 1bdea3b54bbb..ac4afe0e433b 100644
---
a/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
+++
b/dsl/camel-kamelet-main/src/main/resources/camel-main-known-dependencies.properties
@@ -47,6 +47,7 @@ camel.telemetryDev = camel:telemetry-dev
META-INF/services/org/apache/camel/modelxml-dumper = camel:xml-io
META-INF/services/org/apache/camel/modelyaml-dumper = camel:yaml-io
+META-INF/services/org/apache/camel/modeljava-dumper = camel:java-io
META-INF/services/org/apache/camel/cron/cron-service = camel:quartz
com.amazon.redshift.jdbc.Driver = com.amazon.redshift:redshift-jdbc42:2.1.0.33
diff --git a/parent/pom.xml b/parent/pom.xml
index 35ab9df7b57a..11a4cc86a6cf 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -662,6 +662,11 @@
<artifactId>camel-main</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-java-io</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-xml-io</artifactId>