This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch CAMEL-22991 in repository https://gitbox.apache.org/repos/asf/camel.git
commit 9a3ee0dfd362e5e60b5cfa9bfaa8d03944dcb348 Author: Andrea Cosentino <[email protected]> AuthorDate: Thu Feb 12 12:23:42 2026 +0100 CAMEL-22991 - Camel-Jbang-mcp: Support Transform route xml to yaml and yaml to xml in mcp tool Signed-off-by: Andrea Cosentino <[email protected]> --- dsl/camel-jbang/camel-jbang-mcp/pom.xml | 14 +++ .../jbang/core/commands/mcp/TransformTools.java | 101 ++++++++++++++++++++- 2 files changed, 110 insertions(+), 5 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-mcp/pom.xml b/dsl/camel-jbang/camel-jbang-mcp/pom.xml index f507a62c08ec..be3855f34d2b 100644 --- a/dsl/camel-jbang/camel-jbang-mcp/pom.xml +++ b/dsl/camel-jbang/camel-jbang-mcp/pom.xml @@ -92,6 +92,20 @@ <artifactId>camel-yaml-dsl-validator</artifactId> </dependency> + <!-- Camel XML/YAML IO for route transformation --> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-xml-io</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-yaml-io</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-yaml-dsl</artifactId> + </dependency> + <!-- test dependencies --> <dependency> <groupId>io.quarkus</groupId> diff --git a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java index be69d593818a..fae26b231f53 100644 --- a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java +++ b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java @@ -16,7 +16,10 @@ */ package org.apache.camel.dsl.jbang.core.commands.mcp; +import java.io.ByteArrayInputStream; import java.io.File; +import java.io.StringWriter; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.ArrayList; import java.util.HashMap; @@ -33,6 +36,13 @@ import org.apache.camel.catalog.CamelCatalog; import org.apache.camel.catalog.DefaultCamelCatalog; import org.apache.camel.catalog.EndpointValidationResult; import org.apache.camel.dsl.yaml.validator.YamlValidator; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.model.RouteDefinition; +import org.apache.camel.model.RoutesDefinition; +import org.apache.camel.spi.Resource; +import org.apache.camel.support.PluginHelper; +import org.apache.camel.support.ResourceHelper; +import org.apache.camel.xml.in.ModelParser; /** * MCP Tools for validating and transforming Camel routes using Quarkus MCP Server. @@ -147,14 +157,95 @@ public class TransformTools { TransformResult result = new TransformResult(); result.fromFormat = fromFormat; result.toFormat = toFormat; - result.note = "Route transformation requires the full Camel route parser. " + - "Use 'camel transform route' CLI command for complete transformation."; - result.supported = true; - result.recommendation = "Use 'camel transform route --format=" + toFormat + " <file>' for DSL transformation"; + + String from = fromFormat.toLowerCase(); + String to = toFormat.toLowerCase(); + + if (from.equals(to)) { + result.supported = true; + result.result = route; + return result; + } + + if ("java".equals(from)) { + result.supported = false; + result.note = "Java DSL to " + toFormat + " transformation is not supported. " + + "There is no lightweight Java DSL parser available."; + return result; + } + + try { + if ("xml".equals(from) && "yaml".equals(to)) { + result.result = transformXmlToYaml(route); + result.supported = true; + } else if ("yaml".equals(from) && "xml".equals(to)) { + result.result = transformYamlToXml(route); + result.supported = true; + } else { + result.supported = false; + result.note = "Unsupported transformation: " + fromFormat + " to " + toFormat; + } + } catch (Exception e) { + throw new ToolCallException("Failed to transform route: " + e.getMessage(), e); + } return result; } + /** + * Transform an XML route definition to YAML format. + */ + private String transformXmlToYaml(String xml) throws Exception { + // Try Spring namespace first (most common), then fall back to no namespace + RoutesDefinition routes = null; + try (ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) { + routes = new ModelParser(is, "http://camel.apache.org/schema/spring") + .parseRoutesDefinition().orElse(null); + } + if (routes == null) { + try (ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) { + routes = new ModelParser(is) + .parseRoutesDefinition().orElse(null); + } + } + if (routes == null) { + throw new IllegalArgumentException( + "Could not parse XML route. Ensure it contains a valid <routes> or <route> element."); + } + + StringWriter sw = new StringWriter(); + new org.apache.camel.yaml.out.ModelWriter(sw).writeRoutesDefinition(routes); + return sw.toString(); + } + + /** + * Transform a YAML route definition to XML format. + */ + private String transformYamlToXml(String yaml) throws Exception { + DefaultCamelContext ctx = new DefaultCamelContext(); + try { + ctx.build(); + + Resource resource = ResourceHelper.fromString("route.yaml", yaml); + PluginHelper.getRoutesLoader(ctx).loadRoutes(resource); + + List<RouteDefinition> routeDefs = ctx.getRouteDefinitions(); + if (routeDefs == null || routeDefs.isEmpty()) { + throw new IllegalArgumentException( + "Could not parse YAML route. Ensure it contains a valid route definition."); + } + + RoutesDefinition rd = new RoutesDefinition(); + rd.setRoutes(routeDefs); + + StringWriter sw = new StringWriter(); + new org.apache.camel.xml.out.ModelWriter(sw).writeRoutesDefinition(rd); + return sw.toString(); + } finally { + ctx.stop(); + } + } + /** * Tool to validate a YAML DSL route definition against the Camel YAML DSL JSON schema. */ @@ -259,7 +350,7 @@ public class TransformTools { public String toFormat; public String note; public boolean supported; - public String recommendation; + public String result; } public record YamlDslValidationResult(boolean valid, int numberOfErrors, List<YamlDslError> errors) {
