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 2023/11/26 12:26:17 UTC
(camel) 05/05: CAMEL-20154: camel-jsonpath - Make it easier to grab elements in a template like fashion
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch jp
in repository https://gitbox.apache.org/repos/asf/camel.git
commit dbc4968476f580d92506641105cb74c3205cb9ca
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Nov 26 13:25:57 2023 +0100
CAMEL-20154: camel-jsonpath - Make it easier to grab elements in a template like fashion
---
.../src/main/docs/jsonpath-language.adoc | 27 ++++++++++
.../jsonpath/JsonPathSimpleTransformTest.java | 59 ++++++++++++++++++++++
.../modules/languages/pages/simple-language.adoc | 3 ++
.../simple/ast/SimpleFunctionExpression.java | 10 ++++
4 files changed, 99 insertions(+)
diff --git a/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc b/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
index 1da4bd1d8e7..b73e2177370 100644
--- a/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
+++ b/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
@@ -318,5 +318,32 @@ The same example in XML DSL would be:
</route>
----
+== Transforming a JSon message
+
+For basic JSon transformation where you have a fixed structure you can represent with a combination of using
+Camel simple and JSonPath language as:
+
+[source]
+----
+{
+ "company": "${jsonpath($.customer.name)}",
+ "location": "${jsonpath($.customer.address.country)}",
+ "gold": ${jsonpath($.customer.orders.length() > 5)}
+}
+----
+
+Here we use the simple language to define the structure and use JSonPath as inlined functions via the `${jsonpath(exp)}` syntax.
+
+This makes it possible to use simple as a template language to define a basic structure and then JSonPath to grab the data
+from an incoming JSon message. The output of the transformation is also JSon, but with simple you could
+also make it XML or plain text based:
+
+[source,xml]
+----
+<customer gold="${jsonpath($.customer.orders.length() > 5)}">
+ <company>${jsonpath($.customer.name)}</company>
+ <location>${jsonpath($.customer.address.country)}</location>
+</customer>
+----
include::spring-boot:partial$starter.adoc[]
diff --git a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathSimpleTransformTest.java b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathSimpleTransformTest.java
new file mode 100644
index 00000000000..04fba80e077
--- /dev/null
+++ b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathSimpleTransformTest.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.jsonpath;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+public class JsonPathSimpleTransformTest extends CamelTestSupport {
+
+ private static String EXPECTED = """
+ {
+ "roll": 123,
+ "years": 42,
+ "fullname": "scott"
+ }""";
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct:start")
+ .transform().simple("""
+ {
+ "roll": ${jsonpath($.id)},
+ "years": ${jsonpath($.age)},
+ "fullname": "${jsonpath($.name)}"
+ }""")
+ .to("mock:result");
+ }
+ };
+ }
+
+ @Test
+ public void testTransform() throws Exception {
+ getMockEndpoint("mock:result").expectedBodiesReceived(EXPECTED);
+
+ template.sendBody("direct:start", "{\"id\": 123, \"age\": 42, \"name\": \"scott\"}");
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+}
diff --git a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
index 9d9452bb9b1..744273908c6 100644
--- a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
+++ b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
@@ -252,6 +252,9 @@ If no type is given the default is used. It is also possible to use a custom `Uu
and bind the bean to the xref:manual::registry.adoc[Registry] with an id. For example `${uuid(myGenerator}`
where the ID is _myGenerator_.
+|jsonpath(exp) | Object | When working with JSon data, then this allows to use the JsonPath language
+for example to extract data from the message body (in JSon format). This requires having camel-jsonpath JAR on the classpath.
+
|jq(exp) | Object | When working with JSon data, then this allows to use the JQ language
for example to extract data from the message body (in JSon format). This requires having camel-jq JAR on the classpath.
diff --git a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
index d0f93f30cce..2698d8fe8ce 100644
--- a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
+++ b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
@@ -462,6 +462,16 @@ public class SimpleFunctionExpression extends LiteralExpression {
exp = StringHelper.removeQuotes(exp);
return ExpressionBuilder.languageExpression("jq", exp);
}
+ // jsonpath
+ remainder = ifStartsWithReturnRemainder("jsonpath(", function);
+ if (remainder != null) {
+ String exp = StringHelper.beforeLast(remainder, ")");
+ if (exp == null) {
+ throw new SimpleParserException("Valid syntax: ${jsonpath(exp)} was: " + function, token.getIndex());
+ }
+ exp = StringHelper.removeQuotes(exp);
+ return ExpressionBuilder.languageExpression("jsonpath", exp);
+ }
remainder = ifStartsWithReturnRemainder("xpath(", function);
if (remainder != null) {
String exp = StringHelper.beforeLast(remainder, ")");