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/06/08 05:14:49 UTC
[camel] 02/02: CAMEL-18165: camel-jackson - Add out of the box type converters for converting to/from JSonNode. Add converter for TextNode to unwrap the text without quotes. Polished camel-jq.
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
commit 460ca01b4c80565a397d5ea78b1a2773c97a10e2
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Jun 8 07:12:27 2022 +0200
CAMEL-18165: camel-jackson - Add out of the box type converters for converting to/from JSonNode. Add converter for TextNode to unwrap the text without quotes. Polished camel-jq.
---
.../jackson/converter/JacksonTypeConverters.java | 11 +++++
.../converter/JacksonJSonNodeConverterTest.java | 12 ++++++
components/camel-jq/src/main/docs/jq-language.adoc | 13 +++---
.../main/java/org/apache/camel/language/jq/Jq.java | 3 +-
.../org/apache/camel/language/jq/JqExpression.java | 2 +-
.../org/apache/camel/language/jq/JqFunctions.java | 2 +-
.../org/apache/camel/language/jq/JqLanguage.java | 14 +++----
.../language/jq/JqHelloFromHeaderAsStringTest.java | 47 ++++++++++++++++++++++
8 files changed, 87 insertions(+), 17 deletions(-)
diff --git a/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/converter/JacksonTypeConverters.java b/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/converter/JacksonTypeConverters.java
index 20830dc5986..ec0c60c06ec 100644
--- a/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/converter/JacksonTypeConverters.java
+++ b/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/converter/JacksonTypeConverters.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;
@@ -29,6 +30,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.TextNode;
import org.apache.camel.CamelContext;
import org.apache.camel.Converter;
import org.apache.camel.Exchange;
@@ -103,6 +105,10 @@ public final class JacksonTypeConverters {
@Converter
public String toString(JsonNode node, Exchange exchange) throws Exception {
+ if (node instanceof TextNode) {
+ TextNode tn = (TextNode) node;
+ return tn.textValue();
+ }
ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
// output as string in pretty mode
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node);
@@ -110,6 +116,11 @@ public final class JacksonTypeConverters {
@Converter
public byte[] toByteArray(JsonNode node, Exchange exchange) throws Exception {
+ if (node instanceof TextNode) {
+ TextNode tn = (TextNode) node;
+ return tn.textValue().getBytes(StandardCharsets.UTF_8);
+ }
+
ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
return mapper.writeValueAsBytes(node);
}
diff --git a/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/converter/JacksonJSonNodeConverterTest.java b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/converter/JacksonJSonNodeConverterTest.java
index a34300ea244..f4669c0eab0 100644
--- a/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/converter/JacksonJSonNodeConverterTest.java
+++ b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/converter/JacksonJSonNodeConverterTest.java
@@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets;
import java.util.Map;
import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.TextNode;
import org.apache.camel.Exchange;
import org.apache.camel.support.DefaultExchange;
import org.apache.camel.test.junit5.CamelTestSupport;
@@ -80,6 +81,17 @@ public class JacksonJSonNodeConverterTest extends CamelTestSupport {
Assertions.assertEquals("\"Hello Camel\"", node.get("message").toString());
}
+ @Test
+ public void jsonTextNodeToString() {
+ Exchange exchange = new DefaultExchange(context);
+
+ TextNode node = new TextNode("Hello World");
+ String text = context.getTypeConverter().convertTo(String.class, exchange, node);
+ assertNotNull(text);
+
+ Assertions.assertEquals("Hello World", text);
+ }
+
@Test
public void jsonNodeToString() {
Exchange exchange = new DefaultExchange(context);
diff --git a/components/camel-jq/src/main/docs/jq-language.adoc b/components/camel-jq/src/main/docs/jq-language.adoc
index 1933fb43ee6..a474898ac12 100644
--- a/components/camel-jq/src/main/docs/jq-language.adoc
+++ b/components/camel-jq/src/main/docs/jq-language.adoc
@@ -38,12 +38,11 @@ from("queue:books.new")
== Message body types
Camel JQ leverages `camel-jackson` for type conversion.
-To enable camel-jackson` POJO type conversion, refer to the Camel Jackson documentation.
-
+To enable camel-jackson` POJO type conversion, refer to the Camel Jackson documentation.
== Using header as input
-By default, JQ uses the message body as the input source. However, you can also use a header as input by specifying the `headerName` option.
+By default, JQ uses the message body as the input source. However, you can also use a header as input by specifying the `headerName` option.
For example to count the number of books from a JSON document that was stored in a header named `books` you can do:
@@ -59,10 +58,10 @@ from("direct:start")
The camel-jq adds the following functions:
-* `header`: allow to access the Message header in a JQ expression.
-+
-For example, to set the property foo to the Message header `MyHeader':
-+
+* `header` - Allow to access the Message header in a JQ expression.
+
+For example, to set the property foo with the value from the Message header `MyHeader':
+
[source, java]
----
from("direct:start")
diff --git a/components/camel-jq/src/main/java/org/apache/camel/language/jq/Jq.java b/components/camel-jq/src/main/java/org/apache/camel/language/jq/Jq.java
index bb11e449ade..1eda7478817 100644
--- a/components/camel-jq/src/main/java/org/apache/camel/language/jq/Jq.java
+++ b/components/camel-jq/src/main/java/org/apache/camel/language/jq/Jq.java
@@ -19,6 +19,7 @@ package org.apache.camel.language.jq;
import org.apache.camel.CamelContext;
public final class Jq {
+
private Jq() {
}
@@ -29,7 +30,7 @@ public final class Jq {
public static JqExpression expression(CamelContext context, String expression) {
JqExpression answer = new JqExpression(expression);
answer.init(context);
-
return answer;
}
+
}
diff --git a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqExpression.java b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqExpression.java
index 09a6278183f..d30343a3b00 100644
--- a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqExpression.java
+++ b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqExpression.java
@@ -36,13 +36,13 @@ import org.apache.camel.support.CamelContextHelper;
import org.apache.camel.support.ExpressionAdapter;
public class JqExpression extends ExpressionAdapter implements ExpressionResultTypeAware {
+
private final String expression;
private Scope scope;
private String resultTypeName;
private Class<?> resultType;
private String headerName;
-
private JsonQuery query;
private TypeConverter typeConverter;
diff --git a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
index fd27f25c40f..1b6264a6f21 100644
--- a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
+++ b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
@@ -37,6 +37,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class JqFunctions {
+
public static final ThreadLocal<Exchange> EXCHANGE_LOCAL = new ThreadLocal<>();
private static final Logger LOGGER = LoggerFactory.getLogger(JqFunctions.class);
@@ -81,7 +82,6 @@ public final class JqFunctions {
public static void loadLocal(Scope scope) {
scope.addFunction(Header.NAME, 1, new Header());
scope.addFunction(Header.NAME, 2, new Header());
-
}
/**
diff --git a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
index cdfc680c108..30ad2c326e1 100644
--- a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
+++ b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
@@ -47,10 +47,12 @@ public class JqLanguage extends LanguageSupport implements StaticService {
@Override
public void start() {
+ // noop
}
@Override
public void stop() {
+ // noop
}
@Override
@@ -65,12 +67,11 @@ public class JqLanguage extends LanguageSupport implements StaticService {
@Override
public Expression createExpression(String expression) {
- JqExpression exp = new JqExpression(expression);
- exp.setResultType(resultType);
- exp.setHeaderName(headerName);
- exp.init(getCamelContext());
-
- return exp;
+ JqExpression answer = new JqExpression(expression);
+ answer.setResultType(resultType);
+ answer.setHeaderName(headerName);
+ answer.init(getCamelContext());
+ return answer;
}
@Override
@@ -79,7 +80,6 @@ public class JqLanguage extends LanguageSupport implements StaticService {
answer.setResultType(property(Class.class, properties, 0, resultType));
answer.setHeaderName(property(String.class, properties, 1, headerName));
answer.init(getCamelContext());
-
return answer;
}
}
diff --git a/components/camel-jq/src/test/java/org/apache/camel/language/jq/JqHelloFromHeaderAsStringTest.java b/components/camel-jq/src/test/java/org/apache/camel/language/jq/JqHelloFromHeaderAsStringTest.java
new file mode 100644
index 00000000000..52017d965d7
--- /dev/null
+++ b/components/camel-jq/src/test/java/org/apache/camel/language/jq/JqHelloFromHeaderAsStringTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.language.jq;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+
+public class JqHelloFromHeaderAsStringTest extends JqTestSupport {
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct:start")
+ .transform().jq(".foo", String.class, "Content")
+ .to("mock:result");
+ }
+ };
+ }
+
+ @Test
+ public void testHelloHeader() throws Exception {
+ getMockEndpoint("mock:result").expectedBodiesReceived("bar");
+
+ ObjectNode node = MAPPER.createObjectNode();
+ node.put("foo", "bar");
+
+ template.sendBodyAndHeader("direct:start", null, "Content", node);
+
+ assertMockEndpointsSatisfied();
+ }
+}