[ 
https://issues.apache.org/jira/browse/CAMEL-25922?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18138234#comment-18138234
 ] 

Claus Ibsen commented on CAMEL-25922:
-------------------------------------

Thanks for the detailed report and reproducer.

Fix: https://github.com/apache/camel/pull/29192 (for 4.24.0). A resolved 
placeholder value that has no {{ (one that is not escaped or quoted) is now 
used as it is, so a }} in it (such as JSON) no longer fails with "Missing {{". 
This is the option to relax the check on nested values that was left open in 
CAMEL-18576. The {{"a":1}} case stays as it is, because it is valid placeholder 
syntax (key "a", default value 1).

Until then there is a workaround per placeholder that needs no change to the 
parameter values: turn off nested placeholders for that placeholder in the 
template:

{code:java}
.setBody().simple("{{expression?nested=false}}")
{code}

See "Turning off nested placeholders" in the property placeholder docs.

_Claude Code on behalf of Claus Ibsen_


> Route template parameter value containing }} (e.g. JSON) fails with “Missing 
> {{ from the text”
> ----------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25922
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25922
>             Project: Camel
>          Issue Type: Bug
>    Affects Versions: 4.23.0
>            Reporter: Raymond
>            Assignee: Claus Ibsen
>            Priority: Minor
>             Fix For: 4.24.0
>
>
> h3. Problem
> When a route template parameter value contains the text {{}}}} (for example a 
> JSON body or a Simple expression that ends with a nested object), creating 
> the route fails with:
> {noformat}
> org.apache.camel.FailedToCreateRouteException: Failed to create route: 
> templated at: >>> SetBody[simple{{{expression}}}] <<< ...
> Caused by: java.lang.IllegalArgumentException: Missing {{ from the text: 
> {"title":${header.title}}
>       at 
> org.apache.camel.component.properties.DefaultPropertiesParser$ParsingContext.readProperty(DefaultPropertiesParser.java:268)
>       at 
> org.apache.camel.component.properties.DefaultPropertiesParser$ParsingContext.doParseNested(DefaultPropertiesParser.java:192)
>       at 
> org.apache.camel.component.properties.DefaultPropertiesParser$ParsingContext.doParseNested(DefaultPropertiesParser.java:217)
>       ...
> {noformat}
> The exact same expression works when used directly in a route. It only fails 
> when passed as a template parameter (or any property value referenced via 
> {{...}}).
> The cause: {{{{expression}}}} is resolved, and then the resolved value is 
> parsed again for nested placeholders. In {{{"title":${header.title}}}} the 
> closing brace of {{${...}}} plus the closing brace of the JSON object form 
> {{}}}}, which is taken as a placeholder suffix without a matching prefix.
> Top-level text without {{{{}} is skipped by the parser, so it is not 
> affected. A resolved value is always parsed, so there the same text fails.
> h3. Reproducer
> {code:java}
> import java.util.Map;
> import org.apache.camel.builder.RouteBuilder;
> import org.apache.camel.impl.DefaultCamelContext;
> public class JsonTemplateParameterIssue {
>     public static void main(String[] args) throws Exception {
>         try (DefaultCamelContext context = new DefaultCamelContext()) {
>             context.addRoutes(new RouteBuilder() {
>                 @Override
>                 public void configure() {
>                     // works: expression used directly
>                     from("direct:plain")
>                         .setBody().simple("{\"title\":${header.title}}");
>                     // fails: same expression passed as a route template 
> parameter
>                     routeTemplate("setBodyTemplate")
>                         .templateParameter("expression")
>                         .from("direct:{{routeId}}")
>                         .setBody().simple("{{expression}}");
>                 }
>             });
>             context.start();
>             System.out.println(context.createProducerTemplate()
>                 .requestBodyAndHeader("direct:plain", null, "title", 
> "\"Hello\""));
>             // prints {"title":"Hello"}
>             context.addRouteFromTemplate("templated", "setBodyTemplate",
>                 Map.of("routeId", "templated", "expression", 
> "{\"title\":${header.title}}"));
>             // throws FailedToCreateRouteException
>             //   Caused by: IllegalArgumentException: Missing {{ from the 
> text: {"title":${header.title}}
>         }
>     }
> }
> {code}
> h3. Observed results (Camel 4.23.0, template parameter "expression")
> ||Value||Result||
> |{{{"title":${header.title}}}}|FAIL - Missing {{|
> |{{{"a":{"b":1}}}} (plain nested JSON, constant)|FAIL - Missing {{|
> |{{{"title":"${header.title}"}}}|OK|
> |{{{"title":${header.title} }}} (space added)|OK|
> |{{{"title":${header.title\}}}} (escaped)|OK|
> |any of the above with {{setNestedPlaceholder(false)}}|OK|
> A related silent case: a value such as {{{{"a":1}}}} does not fail. It is 
> resolved as placeholder key {{"a"}} with default value {{1}}, so the route 
> gets {{1}} instead of the JSON.
> h3. Context
> We hit this in Assimbly (https://github.com/assimbly/runtime), which builds 
> routes from Kamelet-style route templates. User-supplied setBody expressions 
> (often JSON) are passed as template parameters. Users can't be expected to 
> escape {{}}}} in JSON payloads, and turning off nested placeholders for the 
> whole CamelContext is too broad.
> h3. Suggested improvements (any of these)
> # When parsing a resolved (nested) value, treat an unmatched {{}}}} (no 
> {{{{}} in the text) as literal text instead of throwing. This is consistent 
> with top-level text, which is left untouched when it contains no {{{{}}.
> # Allow route template parameters to be marked as raw/literal (e.g. per 
> {{templateParameter}}, or a template-level option), so their values are not 
> parsed for nested placeholders.
> # Document the {{\}}}} / {{\{{}} escape for template parameter values in the 
> route template docs.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to