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 <claus.ib...@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(); + } +}