This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch nested in repository https://gitbox.apache.org/repos/asf/camel.git
commit cdcc397312a3a5dc971e7344f7151de11fb857ad Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Oct 13 08:25:27 2022 +0200 CAMEL-18576: Using property placeholder allows to turn off nested, with myKey?nested=false. --- .../properties/DefaultPropertiesParser.java | 15 +++++-- ...t.java => ExpressionPlaceholderNestedTest.java} | 47 ++++++++++++++++++---- .../ROOT/pages/using-propertyplaceholder.adoc | 34 +++++++++++++++- 3 files changed, 84 insertions(+), 12 deletions(-) diff --git a/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesParser.java b/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesParser.java index 7cb0d895576..83a1e16a3cf 100644 --- a/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesParser.java +++ b/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesParser.java @@ -105,7 +105,16 @@ public class DefaultPropertiesParser implements PropertiesParser { * @return Evaluated string */ public String parse(String input) { - if (nestedPlaceholder) { + // does the key turn on or off nested? + boolean nested = nestedPlaceholder; + if (input.contains("?nested=true")) { + nested = true; + input = input.replace("?nested=true", ""); + } else if (input.contains("?nested=false")) { + nested = false; + input = input.replace("?nested=false", ""); + } + if (nested) { return doParseNested(input, new HashSet<String>()); } else { return doParse(input); @@ -474,14 +483,14 @@ public class DefaultPropertiesParser implements PropertiesParser { } /** - * Gets the begin index of the property (including the prefix token). + * Gets the beginning index of the property (including the prefix token). */ public int getBeginIndex() { return beginIndex; } /** - * Gets the end index of the property (including the suffix token). + * Gets the ending index of the property (including the suffix token). */ public int getEndIndex() { return endIndex; diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/ExpressionPlaceholderTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/ExpressionPlaceholderNestedTest.java similarity index 55% rename from core/camel-core/src/test/java/org/apache/camel/processor/ExpressionPlaceholderTest.java rename to core/camel-core/src/test/java/org/apache/camel/processor/ExpressionPlaceholderNestedTest.java index b331096352a..8035fe588c6 100644 --- a/core/camel-core/src/test/java/org/apache/camel/processor/ExpressionPlaceholderTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/processor/ExpressionPlaceholderNestedTest.java @@ -20,13 +20,14 @@ import java.util.Properties; import org.apache.camel.CamelContext; import org.apache.camel.ContextTestSupport; +import org.apache.camel.FailedToCreateRouteException; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -@Disabled("CAMEL-18576") -public class ExpressionPlaceholderTest extends ContextTestSupport { +import static org.junit.jupiter.api.Assertions.fail; + +public class ExpressionPlaceholderNestedTest extends ContextTestSupport { @Override protected CamelContext createCamelContext() throws Exception { @@ -34,6 +35,7 @@ public class ExpressionPlaceholderTest extends ContextTestSupport { Properties myProp = new Properties(); myProp.put("query", "{\"query\":{\"match_all\":{}}}"); + myProp.put("queryEscaped", "{\"query\":{\"match_all\":{}\\}}"); context.getPropertiesComponent().setInitialProperties(myProp); @@ -41,11 +43,38 @@ public class ExpressionPlaceholderTest extends ContextTestSupport { } @Test - public void testPlaceholder() throws Exception { + public void testPlaceholderFalse() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedBodiesReceived("{\"query\":{\"match_all\":{}}}"); + + template.sendBody("direct:off", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + @Test + public void testPlaceholderOn() throws Exception { + try { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:on") + .setBody().constant("{{query?nested=true}}") + .to("mock:result"); + } + }); + fail(); + } catch (FailedToCreateRouteException e) { + assertIsInstanceOf(IllegalArgumentException.class, e.getCause()); + } + } + + @Test + public void testPlaceholderEscaped() throws Exception { MockEndpoint mock = getMockEndpoint("mock:result"); mock.expectedBodiesReceived("{\"query\":{\"match_all\":{}}}"); - template.sendBody("direct:start", "Hello World"); + template.sendBody("direct:escaped", "Hello World"); assertMockEndpointsSatisfied(); } @@ -55,8 +84,12 @@ public class ExpressionPlaceholderTest extends ContextTestSupport { return new RouteBuilder() { @Override public void configure() throws Exception { - from("direct:start") - .setBody().constant("{{query}}") + from("direct:off") + .setBody().constant("{{query?nested=false}}") + .to("mock:result"); + + from("direct:escaped") + .setBody().constant("{{queryEscaped}}") .to("mock:result"); } }; diff --git a/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc b/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc index d7ec74932a5..6a8d2f4a76e 100644 --- a/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc +++ b/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc @@ -164,7 +164,7 @@ from("direct:start") In the example above the mock endpoint, is already hardcoded to start with `mock:`, and the `where` placeholder has the value `cheese` so the resolved uri becomes `mock:cheese`. -=== Property placeholders referring to other properties +=== Property placeholders referring to other properties (nested placeholders) You can also have properties with refer to each other such as: @@ -186,9 +186,39 @@ And the route in XML: </route> ---- +==== Turning off nested placeholders + +If the placeholder value contains data that interfere with the property placeholder syntax `{{` and `}}` (such as JSon data), +you can be then explicit turn off nested placeholder by `?nested=false` in the key name, such as shown: + +[source,xml] +---- +<route> + <from uri="direct:start"/> + <to uri="elasticsearch:foo?query={{myQuery?nested=false}}"/> +</route> +---- + +In the example above the placeholder _myQuery_ placeholder value is as follows + +[source,json] +---- +{"query":{"match_all":{}}} +---- + +Notice how the json query ends with `}}` which interfere with the Camel property placeholder syntax. + +Nested placeholders can also be turned off globally on the xref:components::properties-component.adoc[Properties] component, such as: + +[source,java] +---- +CamelContext context = ... +context.getPropertiesComponent().setNestedPlaceholder(false); +---- + === Using property placeholders multiple times -You can of couse also use placeholders several times: +You can of course also use placeholders several times: [source,properties] ----