[
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.
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.
> 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}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)