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/04 08:09:45 UTC

[camel] branch main updated (2f3f70c20a2 -> 7669be51529)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


    from 2f3f70c20a2 [CAMEL-18159] SendDynamicAware of several components parses uri that starts with schema:// incorectly (#7713)
     new fdd7d9b9d87 CAMEL-18165: camel-jackson - Add out of the box type converters for converting to/from JSonNode
     new 7669be51529 Polished

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../converter/JacksonTypeConvertersLoader.java     |  30 +++++
 .../src/main/docs/jackson-dataformat.adoc          |  12 +-
 .../jackson/converter/JacksonTypeConverters.java   |  72 +++++++++++
 .../converter/JacksonJSonNodeConverterTest.java    | 139 +++++++++++++++++++++
 .../src/main/docs/jacksonXml-dataformat.adoc       |  88 ++++++-------
 5 files changed, 294 insertions(+), 47 deletions(-)
 create mode 100644 components/camel-jackson/src/test/java/org/apache/camel/component/jackson/converter/JacksonJSonNodeConverterTest.java


[camel] 02/02: Polished

Posted by da...@apache.org.
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 7669be515297756642bc55b617603013f350fe6d
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Jun 4 10:09:28 2022 +0200

    Polished
---
 .../src/main/docs/jacksonXml-dataformat.adoc       | 88 +++++++++++-----------
 1 file changed, 45 insertions(+), 43 deletions(-)

diff --git a/components/camel-jacksonxml/src/main/docs/jacksonXml-dataformat.adoc b/components/camel-jacksonxml/src/main/docs/jacksonXml-dataformat.adoc
index a0ec5428cf8..4be9b42e628 100644
--- a/components/camel-jacksonxml/src/main/docs/jacksonXml-dataformat.adoc
+++ b/components/camel-jacksonxml/src/main/docs/jacksonXml-dataformat.adoc
@@ -88,7 +88,7 @@ to XML.
 
 Note that the weight field is missing in the resulting XML:
 
-[source,java]
+[source,xml]
 ----------------------------
 <pojo age="30" weight="70"/>
 ----------------------------
@@ -100,8 +100,9 @@ As an example of using this attribute you can instead of:
 [source,java]
 ---------------------------------------------------------------------------------------------------
 JacksonXMLDataFormat ageViewFormat = new JacksonXMLDataFormat(TestPojoView.class, Views.Age.class);
-from("direct:inPojoAgeView").
-  marshal(ageViewFormat);
+
+from("direct:inPojoAgeView")
+  .marshal(ageViewFormat);
 ---------------------------------------------------------------------------------------------------
 
 Directly specify your https://github.com/FasterXML/jackson-annotations/blob/master/src/main/java/com/fasterxml/jackson/annotation/JsonView.java[JSON
@@ -109,18 +110,20 @@ view] inside the Java DSL as:
 
 [source,java]
 ------------------------------------------------------------
-from("direct:inPojoAgeView").
-  marshal().jacksonXml(TestPojoView.class, Views.Age.class);
+from("direct:inPojoAgeView")
+  .marshal().jacksonXml(TestPojoView.class, Views.Age.class);
 ------------------------------------------------------------
 
 And the same in XML DSL:
 
 [source,xml]
 ---------------------------------------------------------------------------------------------------------------------------------------------------
+<route>
 <from uri="direct:inPojoAgeView"/>
-  <marshal>
-    <jacksonXml unmarshalType="org.apache.camel.component.jacksonxml.TestPojoView" jsonView="org.apache.camel.component.jacksonxml.Views$Age"/>
-  </marshal>
+    <marshal>
+      <jacksonXml unmarshalType="org.apache.camel.component.jacksonxml.TestPojoView" jsonView="org.apache.camel.component.jacksonxml.Views$Age"/>
+    </marshal>
+</route>
 ---------------------------------------------------------------------------------------------------------------------------------------------------
 
 == Setting serialization include option
@@ -149,7 +152,7 @@ format.setInclude("NON_NULL");
 
 Or from XML DSL you configure this as
 
-[source,java]
+[source,xml]
 ------------------------------------------------------
 <dataFormats>
   <jacksonXml id="jacksonxml" include="NON_NULL"/>
@@ -176,7 +179,7 @@ format.setAllowJmsType(true);
 
 Or from XML DSL you configure this as
 
-[source,java]
+[source,xml]
 -------------------------------------------------------
 <dataFormats>
   <jacksonXml id="jacksonxml" allowJmsType="true"/>
@@ -203,20 +206,20 @@ format.setUnmarshalType(MyPojo.class);
 And if you use XML DSL then you configure to use list
 using `useList` attribute as shown below:
 
-[source,java]
+[source,xml]
 --------------------------------------------
-    <dataFormats>
-      <jacksonXml id="jack" useList="true"/>
-    </dataFormats>
+<dataFormats>
+    <jacksonXml id="jack" useList="true"/>
+</dataFormats>
 --------------------------------------------
 
 And you can specify the pojo type also
 
-[source,java]
+[source,xml]
 -------------------------------------------------------------------------------
-    <dataFormats>
-      <jacksonXml id="jack" useList="true" unmarshalType="com.foo.MyPojo"/>
-    </dataFormats>
+<dataFormats>
+    <jacksonXml id="jack" useList="true" unmarshalType="com.foo.MyPojo"/>
+</dataFormats>
 -------------------------------------------------------------------------------
 
 == Using custom Jackson modules
@@ -224,11 +227,11 @@ And you can specify the pojo type also
 You can use custom Jackson modules by specifying the class names of
 those using the moduleClassNames option as shown below.
 
-[source,java]
+[source,xml]
 -----------------------------------------------------------------------------------------------------------------------------------------
-    <dataFormats>
-      <jacksonXml id="jack" useList="true" unmarshalType="com.foo.MyPojo" moduleClassNames="com.foo.MyModule,com.foo.MyOtherModule"/>
-    </dataFormats>
+<dataFormats>
+    <jacksonXml id="jack" useList="true" unmarshalType="com.foo.MyPojo" moduleClassNames="com.foo.MyModule,com.foo.MyOtherModule"/>
+</dataFormats>
 -----------------------------------------------------------------------------------------------------------------------------------------
 
 When using moduleClassNames then the custom jackson modules are not
@@ -237,19 +240,18 @@ custom module needs any custom configuration, then an instance of the
 module can be created and configured, and then use modulesRefs to refer
 to the module as shown below:
 
-[source,java]
+[source,xml]
 ------------------------------------------------------------------------------------------------------------------
-    <bean id="myJacksonModule" class="com.foo.MyModule">
-      ... // configure the module as you want
-    </bean>
+<bean id="myJacksonModule" class="com.foo.MyModule">
+  ... // configure the module as you want
+</bean>
  
-    <dataFormats>
-      <jacksonXml id="jacksonxml" useList="true" unmarshalType="com.foo.MyPojo" moduleRefs="myJacksonModule"/>
-    </dataFormats>
+<dataFormats>
+    <jacksonXml id="jacksonxml" useList="true" unmarshalType="com.foo.MyPojo" moduleRefs="myJacksonModule"/>
+</dataFormats>
 ------------------------------------------------------------------------------------------------------------------
 
- Multiple modules can be specified separated by comma, such as
-moduleRefs="myJacksonModule,myOtherModule"
+Multiple modules can be specified separated by comma, such as `moduleRefs="myJacksonModule,myOtherModule"`.
 
 == Enabling or disable features using Jackson
 
@@ -257,20 +259,20 @@ Jackson has a number of features you can enable or disable, which its
 ObjectMapper uses. For example to disable failing on unknown properties
 when marshalling, you can configure this using the disableFeatures:
 
-[source,java]
+[source,xml]
 -------------------------------------------------------------------------------------------------------------------
- <dataFormats>
-      <jacksonXml id="jacksonxml" unmarshalType="com.foo.MyPojo" disableFeatures="FAIL_ON_UNKNOWN_PROPERTIES"/>
- </dataFormats>
+<dataFormats>
+    <jacksonXml id="jacksonxml" unmarshalType="com.foo.MyPojo" disableFeatures="FAIL_ON_UNKNOWN_PROPERTIES"/>
+</dataFormats>
 -------------------------------------------------------------------------------------------------------------------
 
 You can disable multiple features by separating the values using comma.
 The values for the features must be the name of the enums from Jackson
-from the following enum classes
+from the following enum classes:
 
-* com.fasterxml.jackson.databind.SerializationFeature
-* com.fasterxml.jackson.databind.DeserializationFeature
-* com.fasterxml.jackson.databind.MapperFeature
+* `com.fasterxml.jackson.databind.SerializationFeature`
+* `com.fasterxml.jackson.databind.DeserializationFeature`
+* `com.fasterxml.jackson.databind.MapperFeature`
 
 To enable a feature use the enableFeatures options instead.
 
@@ -310,11 +312,11 @@ Otherwise the default mapper will be used.
 Using the `prettyPrint` option one can output a well formatted XML while
 marshalling:
 
-[source,java]
+[source,xml]
 ------------------------------------------------
- <dataFormats>
-      <jacksonXml id="jack" prettyPrint="true"/>
- </dataFormats>
+<dataFormats>
+    <jacksonXml id="jack" prettyPrint="true"/>
+</dataFormats>
 ------------------------------------------------
 
 And in Java DSL:


[camel] 01/02: CAMEL-18165: camel-jackson - Add out of the box type converters for converting to/from JSonNode

Posted by da...@apache.org.
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 fdd7d9b9d8736b3e85ad9cefc1e7671c7abc9a3e
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Jun 4 10:05:09 2022 +0200

    CAMEL-18165: camel-jackson - Add out of the box type converters for converting to/from JSonNode
---
 .../converter/JacksonTypeConvertersLoader.java     |  30 +++++
 .../src/main/docs/jackson-dataformat.adoc          |  12 +-
 .../jackson/converter/JacksonTypeConverters.java   |  72 +++++++++++
 .../converter/JacksonJSonNodeConverterTest.java    | 139 +++++++++++++++++++++
 4 files changed, 249 insertions(+), 4 deletions(-)

diff --git a/components/camel-jackson/src/generated/java/org/apache/camel/component/jackson/converter/JacksonTypeConvertersLoader.java b/components/camel-jackson/src/generated/java/org/apache/camel/component/jackson/converter/JacksonTypeConvertersLoader.java
index ec2fda53072..a527933abc1 100644
--- a/components/camel-jackson/src/generated/java/org/apache/camel/component/jackson/converter/JacksonTypeConvertersLoader.java
+++ b/components/camel-jackson/src/generated/java/org/apache/camel/component/jackson/converter/JacksonTypeConvertersLoader.java
@@ -37,9 +37,39 @@ public final class JacksonTypeConvertersLoader implements TypeConverterLoader, C
 
     @Override
     public void load(TypeConverterRegistry registry) throws TypeConverterLoaderException {
+        registerConverters(registry);
         registerFallbackConverters(registry);
     }
 
+    private void registerConverters(TypeConverterRegistry registry) {
+        addTypeConverter(registry, byte[].class, com.fasterxml.jackson.databind.JsonNode.class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toByteArray((com.fasterxml.jackson.databind.JsonNode) value, exchange));
+        addTypeConverter(registry, com.fasterxml.jackson.databind.JsonNode.class, byte[].class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toJsonNode((byte[]) value, exchange));
+        addTypeConverter(registry, com.fasterxml.jackson.databind.JsonNode.class, java.io.File.class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toJsonNode((java.io.File) value, exchange));
+        addTypeConverter(registry, com.fasterxml.jackson.databind.JsonNode.class, java.io.InputStream.class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toJsonNode((java.io.InputStream) value, exchange));
+        addTypeConverter(registry, com.fasterxml.jackson.databind.JsonNode.class, java.io.Reader.class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toJsonNode((java.io.Reader) value, exchange));
+        addTypeConverter(registry, com.fasterxml.jackson.databind.JsonNode.class, java.lang.String.class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toJsonNode((java.lang.String) value, exchange));
+        addTypeConverter(registry, com.fasterxml.jackson.databind.JsonNode.class, java.util.Map.class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toJsonNode((java.util.Map) value, exchange));
+        addTypeConverter(registry, java.io.InputStream.class, com.fasterxml.jackson.databind.JsonNode.class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toInputStream((com.fasterxml.jackson.databind.JsonNode) value, exchange));
+        addTypeConverter(registry, java.io.Reader.class, com.fasterxml.jackson.databind.JsonNode.class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toReader((com.fasterxml.jackson.databind.JsonNode) value, exchange));
+        addTypeConverter(registry, java.lang.String.class, com.fasterxml.jackson.databind.JsonNode.class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toString((com.fasterxml.jackson.databind.JsonNode) value, exchange));
+        addTypeConverter(registry, java.util.Map.class, com.fasterxml.jackson.databind.JsonNode.class, false,
+            (type, exchange, value) -> getJacksonTypeConverters().toMap((com.fasterxml.jackson.databind.JsonNode) value, exchange));
+    }
+
+    private static void addTypeConverter(TypeConverterRegistry registry, Class<?> toType, Class<?> fromType, boolean allowNull, SimpleTypeConverter.ConversionMethod method) { 
+        registry.addTypeConverter(toType, fromType, new SimpleTypeConverter(allowNull, method));
+    }
+
     private void registerFallbackConverters(TypeConverterRegistry registry) {
         addFallbackTypeConverter(registry, false, false, (type, exchange, value) -> getJacksonTypeConverters().convertTo(type, exchange, value, registry));
     }
diff --git a/components/camel-jackson/src/main/docs/jackson-dataformat.adoc b/components/camel-jackson/src/main/docs/jackson-dataformat.adoc
index b4098f20959..0f96603425d 100644
--- a/components/camel-jackson/src/main/docs/jackson-dataformat.adoc
+++ b/components/camel-jackson/src/main/docs/jackson-dataformat.adoc
@@ -40,14 +40,18 @@ and then use it. When this happens you should set a `INFO` logging from Camel.
 == Using Jackson for automatic type conversion
 
 The `camel-jackson` module allows integrating Jackson as a xref:manual::type-converter.adoc[Type Converter].
-This works in similar ways that xref:dataformats:jaxb-dataformat.adoc[JAXB] integrates with Camels type converter.
 
-To use this `camel-jackson` must be enabled, which is done by setting the following options
-on the `CamelContext` global options, as shown:
+This gives a set of out of the box converters to/from the Jackson type `JSonNode`, such as converting
+from `JSonNode` to `String` or vice-versa.
+
+=== Enabling more type converters and support for POJOs
+
+To enable POJO conversion support for `camel-jackson` then this must be enabled,
+which is done by setting the following options on the `CamelContext` global options, as shown:
 
 [source,java]
 ----
-// Enable Jackson JSON type converter.
+// Enable Jackson JSON type converter for more types.
 camelContext.getGlobalOptions().put("CamelJacksonEnableTypeConverter", "true");
 // Allow Jackson JSON to convert to pojo types also
 // (by default Jackson only converts to String and other simple types)
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 0751d2c110e..20830dc5986 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
@@ -16,13 +16,17 @@
  */
 package org.apache.camel.component.jackson.converter;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.Reader;
 import java.nio.ByteBuffer;
 import java.util.Map;
 import java.util.Set;
 
+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 org.apache.camel.CamelContext;
@@ -61,6 +65,74 @@ public final class JacksonTypeConverters {
         this.lock = new Object();
     }
 
+    @Converter
+    public JsonNode toJsonNode(String text, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.readTree(text);
+    }
+
+    @Converter
+    public JsonNode toJsonNode(byte[] arr, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.readTree(arr);
+    }
+
+    @Converter
+    public JsonNode toJsonNode(InputStream is, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.readTree(is);
+    }
+
+    @Converter
+    public JsonNode toJsonNode(File file, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.readTree(file);
+    }
+
+    @Converter
+    public JsonNode toJsonNode(Reader reader, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.readTree(reader);
+    }
+
+    @Converter
+    public JsonNode toJsonNode(Map map, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.valueToTree(map);
+    }
+
+    @Converter
+    public String toString(JsonNode node, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        // output as string in pretty mode
+        return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node);
+    }
+
+    @Converter
+    public byte[] toByteArray(JsonNode node, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.writeValueAsBytes(node);
+    }
+
+    @Converter
+    public InputStream toInputStream(JsonNode node, Exchange exchange) throws Exception {
+        byte[] arr = toByteArray(node, exchange);
+        return new ByteArrayInputStream(arr);
+    }
+
+    @Converter
+    public Map<String, Object> toMap(JsonNode node, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.convertValue(node, new TypeReference<Map<String, Object>>() {
+        });
+    }
+
+    @Converter
+    public Reader toReader(JsonNode node, Exchange exchange) throws Exception {
+        InputStream is = toInputStream(node, exchange);
+        return new InputStreamReader(is);
+    }
+
     @Converter(fallback = true)
     public <T> T convertTo(Class<T> type, Exchange exchange, Object value, TypeConverterRegistry registry) throws Exception {
 
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
new file mode 100644
index 00000000000..a34300ea244
--- /dev/null
+++ b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/converter/JacksonJSonNodeConverterTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.component.jackson.converter;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.camel.Exchange;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class JacksonJSonNodeConverterTest extends CamelTestSupport {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void stringToJsonNode() {
+        Exchange exchange = new DefaultExchange(context);
+
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, exchange, "{ \"message\": \"Hello World\" }");
+        assertNotNull(node);
+
+        Assertions.assertEquals("\"Hello World\"", node.get("message").toString());
+    }
+
+    @Test
+    public void byteArrayToJsonNode() {
+        Exchange exchange = new DefaultExchange(context);
+
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, exchange,
+                "{ \"message\": \"Bye World\" }".getBytes(StandardCharsets.UTF_8));
+        assertNotNull(node);
+
+        Assertions.assertEquals("\"Bye World\"", node.get("message").toString());
+    }
+
+    @Test
+    public void inputStreamToJsonNode() {
+        Exchange exchange = new DefaultExchange(context);
+
+        ByteArrayInputStream bis = new ByteArrayInputStream("{ \"message\": \"Bye World\" }".getBytes(StandardCharsets.UTF_8));
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, exchange, bis);
+        assertNotNull(node);
+
+        Assertions.assertEquals("\"Bye World\"", node.get("message").toString());
+    }
+
+    @Test
+    public void mapToJsonNode() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Map<String, Object> map = Map.of("message", "Hello Camel");
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, exchange, map);
+        assertNotNull(node);
+
+        Assertions.assertEquals("\"Hello Camel\"", node.get("message").toString());
+    }
+
+    @Test
+    public void jsonNodeToString() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Map<String, Object> map = Map.of("message", "Hello Camel");
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, exchange, map);
+
+        String text = context.getTypeConverter().convertTo(String.class, exchange, node);
+        assertNotNull(text);
+
+        Assertions.assertEquals("{\n  \"message\" : \"Hello Camel\"\n}", text);
+    }
+
+    @Test
+    public void jsonNodeToByteArray() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Map<String, Object> map = Map.of("message", "Hello Camel");
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, exchange, map);
+
+        byte[] arr = context.getTypeConverter().convertTo(byte[].class, exchange, node);
+        assertNotNull(arr);
+        String s = context.getTypeConverter().convertTo(String.class, exchange, arr);
+
+        Assertions.assertEquals("{\"message\":\"Hello Camel\"}", s);
+    }
+
+    @Test
+    public void jsonNodeToInputStream() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Map<String, Object> map = Map.of("message", "Hello Camel");
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, exchange, map);
+
+        InputStream is = context.getTypeConverter().convertTo(InputStream.class, exchange, node);
+        assertNotNull(is);
+        String s = context.getTypeConverter().convertTo(String.class, exchange, is);
+
+        Assertions.assertEquals("{\"message\":\"Hello Camel\"}", s);
+    }
+
+    @Test
+    public void jsonNodeToMap() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Map<String, Object> map = Map.of("message", "Bye Camel", "age", 44);
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, exchange, map);
+
+        Map out = context.getTypeConverter().convertTo(Map.class, exchange, node);
+        assertNotNull(out);
+
+        Assertions.assertEquals(2, out.size());
+        Assertions.assertEquals("Bye Camel", out.get("message"));
+        Assertions.assertEquals(44, out.get("age"));
+    }
+
+}