You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/10/13 07:52:24 UTC
[camel] branch main updated: CAMEL-18576: Using property placeholder allows to turn off nested, with myKey?nested=false. (#8533)
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 944724c03d3 CAMEL-18576: Using property placeholder allows to turn off nested, with myKey?nested=false. (#8533)
944724c03d3 is described below
commit 944724c03d325dc533516d01c631fb5c22441454
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Oct 13 09:52:16 2022 +0200
CAMEL-18576: Using property placeholder allows to turn off nested, with myKey?nested=false. (#8533)
---
.../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 ddb0ad3a693..1130591acda 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,6 +186,36 @@ 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);
+----
+
=== Escape a property placeholder
The property placeholder can be problematic if the double curly brackets are used by a third party library like for example a query in ElasticSearch of type `{"query":{"match_all":{}}}`.
@@ -196,7 +226,7 @@ If for some reason, the backslash character before the double curly brackets mus
=== 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]
----