[ 
https://issues.apache.org/jira/browse/CAMEL-20889?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Luigi De Masi updated CAMEL-20889:
----------------------------------
    Description: 
Having the following Camel route on Camel  2.x
{code:java}
from("timer:mytimer2?repeatCount=1&delay=1000")
    .routeId("generate-route-marshall")
    .streamCaching()
    .transform(constant("\{\"maskme\":\"json payload\"}"))
    .marshal().json(JsonLibrary.Jackson)
    .process(exchange ->
    {
         LOGGER.info("body class name -> " + 
exchange.getIn().getBody().getClass().getName());
         LOGGER.info("consumed once  using .getBody(String.class) -> " + 
exchange.getIn().getBody(String.class));
        LOGGER.info("consumed twice using .getBody(String.class) -> " + 
exchange.getIn().getBody(String.class));
    })
    .to("jms:queue:INCOMING");

{code}
 

Shows that the consumption of the message payload  in the processor via 
{code:java}
exchange.getIn().getBody(String.class));\{code}
 works as expected, as the body is shown twice on the logs, as follows.
{code:java}
body class name -> org.apache.camel.converter.stream.InputStreamCache
consumed once  using .getBody(String.class) -> "\{\"maskme\":\"json payload\"}"
consumed twice using .getBody(String.class) -> "\{\"maskme\":\"json payload\"}"

{code}
 

But if you run this same route from  Camel 3.x to the latest 4.x one,  you will 
get the following output:
{code:java}
body class name -> org.apache.camel.converter.stream.InputStreamCache
consumed once  using .getBody(String.class) -> "\{\"maskme\":\"json payload\"}"
consumed once  using .getBody(String.class) ->
{code}
 

The problem is that on Camel 2.x, when ` 
exchange.getIn().getBody(String.class))` is called, the 
[org.apache.camel.converter.IOConverterOptimised|https://github.com/apache/camel/blob/camel-2.x/camel-core/src/main/java/org/apache/camel/converter/IOConverterOptimised.java]
 is triggered to convert the body from 
{{org.apache.camel.converter.stream.InputStreamCache}} to 
{{{}java.lang.String{}}}, which at the beginning of the convertion, [it reset 
the 
stream|https://github.com/apache/camel/blob/a05826ece32fbb8e2ba6df0e0ac2a3d5903f9572/camel-core/src/main/java/org/apache/camel/converter/IOConverterOptimised.java#L50]:

 
{code:java|title=IOConverterOptimised.java}
public final class IOConverterOptimised {
    private IOConverterOptimised() {
    }

    public static Object convertTo(final Class<?> type, final Exchange 
exchange, final Object value) throws Exception {
        Class fromType = value.getClass();
        if (value instanceof StreamCache) {
            ((StreamCache)value).reset();      // <------ HERE
        }
{code}
>From Camel 3.x, IOConverterOptimised.java has been dropped, and 
>[org.apache.camel.impl.converter.CoreTypeConverterRegistry|] is used instead, 
>which doesn't reset the stream.



  was:
Having the following Camel route on Camel  2.x
{code:java}
from("timer:mytimer2?repeatCount=1&delay=1000")
    .routeId("generate-route-marshall")
    .streamCaching()
    .transform(constant("\{\"maskme\":\"json payload\"}"))
    .marshal().json(JsonLibrary.Jackson)
    .process(exchange ->
    {
         LOGGER.info("body class name -> " + 
exchange.getIn().getBody().getClass().getName());
         LOGGER.info("consumed once  using .getBody(String.class) -> " + 
exchange.getIn().getBody(String.class));
        LOGGER.info("consumed twice using .getBody(String.class) -> " + 
exchange.getIn().getBody(String.class));
    })
    .to("jms:queue:INCOMING");

{code}
 

Shows that the consumption of the message payload  in the processor via 
{code:java}
exchange.getIn().getBody(String.class));\{code}
 works as expected, as the body is shown twice on the logs, as follows.
{code:java}
body class name -> org.apache.camel.converter.stream.InputStreamCache
consumed once  using .getBody(String.class) -> "\{\"maskme\":\"json payload\"}"
consumed twice using .getBody(String.class) -> "\{\"maskme\":\"json payload\"}"

{code}
 

But if you run this same route from  Camel 3.x to the latest 4.x one,  you will 
get the following output:
{code:java}
body class name -> org.apache.camel.converter.stream.InputStreamCache
consumed once  using .getBody(String.class) -> "\{\"maskme\":\"json payload\"}"
consumed once  using .getBody(String.class) ->
{code}
 

The problem is that on Camel 2.x, when ` 
exchange.getIn().getBody(String.class))` is called, the 
[org.apache.camel.converter.IOConverterOptimised|https://github.com/apache/camel/blob/camel-2.x/camel-core/src/main/java/org/apache/camel/converter/IOConverterOptimised.java]
 is triggered to convert the body from 
{{org.apache.camel.converter.stream.InputStreamCache}} to 
{{{}java.lang.String{}}}, which at the beginning of the convertion, [it reset 
the 
stream|https://github.com/apache/camel/blob/a05826ece32fbb8e2ba6df0e0ac2a3d5903f9572/camel-core/src/main/java/org/apache/camel/converter/IOConverterOptimised.java#L50]:

 
{code:java|title=IOConverterOptimised.java}
public final class IOConverterOptimised {
    private IOConverterOptimised() {
    }

    public static Object convertTo(final Class<?> type, final Exchange 
exchange, final Object value) throws Exception {
        Class fromType = value.getClass();
        if (value instanceof StreamCache) {
            ((StreamCache)value).reset();      // <------ HERE
        }
{code}
>From Camel 3.x, IOConverterOptimised.java has been dropped, and 
>[org.apache.camel.impl.converter.CoreTypeConverterRegistry|] is used instead, 
>which doesn't reset the stream.

A quick workaround is to reset the stream manually before trying to read it 
again:
{code:java}
                LOGGER.info("body class name -> " + 
exchange.getIn().getBody().getClass().getName());
                LOGGER.info("consumed once  using .getBody(String.class) -> " + 
exchange.getIn().getBody(String.class));
                exchange.getIn().getBody(InputStreamCache.class).reset();
                LOGGER.info("consumed twice using .getBody(String.class) -> " + 
exchange.getIn().getBody(String.class));
{code}
and you get this as output:
{code:java}
Started CamelArtemisApplication in 2.069 seconds (JVM running for 2.686)
body class name -> org.apache.camel.converter.stream.InputStreamCache
consumed once  using .getBody(String.class) -> "{\"maskme\":\"json payload\"}"
consumed twice using .getBody(String.class) -> "{\"maskme\":\"json payload\"}"
{code}


> Stream is not reset when Message.getBody(class) is invoked ans stream caching 
> is enabled
> ----------------------------------------------------------------------------------------
>
>                 Key: CAMEL-20889
>                 URL: https://issues.apache.org/jira/browse/CAMEL-20889
>             Project: Camel
>          Issue Type: Bug
>          Components: came-core
>            Reporter: Luigi De Masi
>            Assignee: Luigi De Masi
>            Priority: Major
>
> Having the following Camel route on Camel  2.x
> {code:java}
> from("timer:mytimer2?repeatCount=1&delay=1000")
>     .routeId("generate-route-marshall")
>     .streamCaching()
>     .transform(constant("\{\"maskme\":\"json payload\"}"))
>     .marshal().json(JsonLibrary.Jackson)
>     .process(exchange ->
>     {
>          LOGGER.info("body class name -> " + 
> exchange.getIn().getBody().getClass().getName());
>          LOGGER.info("consumed once  using .getBody(String.class) -> " + 
> exchange.getIn().getBody(String.class));
>         LOGGER.info("consumed twice using .getBody(String.class) -> " + 
> exchange.getIn().getBody(String.class));
>     })
>     .to("jms:queue:INCOMING");
> {code}
>  
> Shows that the consumption of the message payload  in the processor via 
> {code:java}
> exchange.getIn().getBody(String.class));\{code}
>  works as expected, as the body is shown twice on the logs, as follows.
> {code:java}
> body class name -> org.apache.camel.converter.stream.InputStreamCache
> consumed once  using .getBody(String.class) -> "\{\"maskme\":\"json 
> payload\"}"
> consumed twice using .getBody(String.class) -> "\{\"maskme\":\"json 
> payload\"}"
> {code}
>  
> But if you run this same route from  Camel 3.x to the latest 4.x one,  you 
> will get the following output:
> {code:java}
> body class name -> org.apache.camel.converter.stream.InputStreamCache
> consumed once  using .getBody(String.class) -> "\{\"maskme\":\"json 
> payload\"}"
> consumed once  using .getBody(String.class) ->
> {code}
>  
> The problem is that on Camel 2.x, when ` 
> exchange.getIn().getBody(String.class))` is called, the 
> [org.apache.camel.converter.IOConverterOptimised|https://github.com/apache/camel/blob/camel-2.x/camel-core/src/main/java/org/apache/camel/converter/IOConverterOptimised.java]
>  is triggered to convert the body from 
> {{org.apache.camel.converter.stream.InputStreamCache}} to 
> {{{}java.lang.String{}}}, which at the beginning of the convertion, [it reset 
> the 
> stream|https://github.com/apache/camel/blob/a05826ece32fbb8e2ba6df0e0ac2a3d5903f9572/camel-core/src/main/java/org/apache/camel/converter/IOConverterOptimised.java#L50]:
>  
> {code:java|title=IOConverterOptimised.java}
> public final class IOConverterOptimised {
>     private IOConverterOptimised() {
>     }
>     public static Object convertTo(final Class<?> type, final Exchange 
> exchange, final Object value) throws Exception {
>         Class fromType = value.getClass();
>         if (value instanceof StreamCache) {
>             ((StreamCache)value).reset();      // <------ HERE
>         }
> {code}
> From Camel 3.x, IOConverterOptimised.java has been dropped, and 
> [org.apache.camel.impl.converter.CoreTypeConverterRegistry|] is used instead, 
> which doesn't reset the stream.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to