Hello,

Thank you for your response and the code modification. Did you see my
comment on the Jira ticket (
https://issues.apache.org/jira/browse/CAMEL-20938)?
I believe the fix does not align with the description of the
“disableStreamCache” option specified in the Camel documentation.
Therefore, it still does not work as expected for our application.

Best regards,

Le mer. 3 juil. 2024 à 08:54, Claus Ibsen <claus.ib...@gmail.com> a écrit :

> Hi
>
> Thanks for reporting I created a ticket
> https://issues.apache.org/jira/browse/CAMEL-20938
>
> On Fri, Jun 21, 2024 at 3:09 PM Ryan Ikhlef <ryanikhlef....@gmail.com>
> wrote:
>
> > Sorry, I think I sent this mail in the wrong mailing list, I should have
> > sent it to the users list.
> >
> > Please ignore this, I resend it to the user mailing list.
> >
> > Le ven. 21 juin 2024 à 14:38, Ryan Ikhlef <ryanikhlef....@gmail.com> a
> > écrit :
> >
> > > Hello,
> > >
> > > I'm facing a weird behavior on the Camel-HTTP component (4.2.2) when I
> > > want to use the "disableStreamCache=true" configuration specified in
> this
> > > page : https://camel.apache.org/components/4.4.x/http-component.html.
> > > When this option is set to true, the stream is consumed first by the
> > > Apache HTTP Client, and then, when Camel tries to convert the
> InputStream
> > > to CacheOutputStream object by copying the data, it raises a
> > > "StreamAlreadyClosed" exception.
> > >
> > > I even tried to get the body in a processor, to convert it into another
> > > object like String.class etc... So, I tried to go deeply in the code to
> > > figure out this error. Please find below my analysis.
> > >
> > > When I make an HTTP call, the execution goes through the
> > >
> >
> org.apache.hc.client5.http.impl.classic.CloseableHttpClient#execute(HttpHost,
> > > ClassicHttpRequest, HttpContext, HttpClientResponseHandler) method.
> Here,
> > > it calls the handler defined by Camel in
> > > org.apache.camel.component.http.HttpProducer#process(Exchange) - line
> > 248.
> > > In this handler, because I set up the option "disableStreamCache=true"
> > the
> > > handler sets the exchange body as the InputStream provided by the HTTP
> > > Client. So, when it goes back to the execute method, the Apache HTTP
> > Client
> > > consumes the stream (i.e ; he closes it).
> > > This is where the problem starts. In the exchange, I have a closed
> stream
> > > that can't be used inside my route. For example, if I try to log the
> > body,
> > > it raises the exception pasted below.
> > >
> > > I also tried the run my app with the option :
> > > "camel.springboot.stream-caching-enabled: false" in my application.yml
> > but
> > > the bug is caused before this option is valuated (in the HTTP Client)
> so,
> > > it's not effective.
> > >
> > > I don't really know if it's me who does not fully understand this
> option
> > > or if it's a bug. I think, the HTTP Client expects the user to read the
> > > response inside the handler given in the execute method, then, it can
> > > safely close the InputStream. But, in the Camel case, the handler just
> > put
> > > the InputStream reference inside the exchange. Maybe, when the option
> > > disableStreamCache is set to true, the final user of Camel should be
> able
> > > to give his own handler's implementation in order to consume it in the
> > way
> > > we need?
> > >
> > > Thanks in advance for your inputs.
> > > Regards,
> > >
> > > Steps to reproduce :
> > >
> > > I noticed this bug by using Camel spring boot 4.2.2 but I think this
> bug
> > > is reproducible without Spring Boot.
> > >
> > > Here find my dependencies in my pom.xml :
> > > <properties>
> > >      <camel.version>4.4.2</camel.version>
> > > </properties>
> > >
> > > <dependencies>
> > >        <dependency>
> > >            <groupId>org.springframework.boot</groupId>
> > >           <artifactId>spring-boot-starter</artifactId>
> > >      </dependency>
> > >
> > >        <dependency>
> > >            <groupId>org.apache.camel.springboot</groupId>
> > >           <artifactId>camel-spring-boot-starter</artifactId>
> > >           <version>${camel.version}</version>
> > >      </dependency>
> > >      <dependency>
> > >            <groupId>org.apache.camel.springboot</groupId>
> > >           <artifactId>camel-http-starter</artifactId>
> > >           <version>${camel.version}</version>
> > >      </dependency>
> > >
> > >       <dependency>
> > >            <groupId>org.slf4j</groupId>
> > >           <artifactId>slf4j-api</artifactId>
> > >      </dependency>
> > >
> > >        <dependency>
> > >            <groupId>org.springframework.boot</groupId>
> > >           <artifactId>spring-boot-starter-logging</artifactId>
> > >      </dependency>
> > > </dependencies>
> > >
> > > Here my Main class :
> > >
> > > @SpringBootApplication
> > > public class Main {
> > >     public static void main(String[] args) {
> > >         SpringApplication.run(Main.class, args);
> > >      }
> > > }
> > >
> > > and found my route here :
> > >
> > > @Component
> > > public class MyRoute extends RouteBuilder {
> > >
> > >     @Override
> > >     public void configure() throws Exception {
> > >         getContext().getTypeConverterRegistry();
> > >
> > >         //@formatter:off
> > >         from("timer:test?repeatCount=1")
> > >             .setHeader(Exchange.HTTP_METHOD, constant("GET"))
> > >             .setHeader(Exchange.HTTP_URI, constant("
> > > https://camel.apache.org/components/4.4.x/http-component.html";))
> > >             .to("http:myHttpRequest?disableStreamCache=true")
> > >             .log("body : ${body}")
> > >         .end();
> > >         //@formatter:on
> > >     }
> > > }
> > >
> > > Find here the log I got after running this project :
> > >
> > > org.apache.camel.StreamCacheException: Error during type conversion
> from
> > > type: org.apache.hc.client5.http.entity.LazyDecompressingInputStream to
> > the
> > > required type: org.apache.camel.StreamCache with value
> > > org.apache.hc.client5.http.entity.LazyDecompressingInputStream@2e74480e
> > > due to org.apache.camel.TypeConversionException: Error during type
> > > conversion from type:
> > > org.apache.hc.client5.http.entity.LazyDecompressingInputStream to the
> > > required type: org.apache.camel.StreamCache with value
> > > org.apache.hc.client5.http.entity.LazyDecompressingInputStream@2e74480e
> > > due to java.io.IOException: Attempted read on closed stream.
> > > at
> > >
> >
> org.apache.camel.impl.engine.StreamCachingHelper.handleException(StreamCachingHelper.java:86)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.StreamCachingHelper.handleException(StreamCachingHelper.java:81)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.StreamCachingHelper.tryStreamCache(StreamCachingHelper.java:74)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.StreamCachingHelper.convertToStreamCache(StreamCachingHelper.java:55)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.CamelInternalProcessor$StreamCachingAdvice.before(CamelInternalProcessor.java:1009)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.CamelInternalProcessor$StreamCachingAdvice.before(CamelInternalProcessor.java:999)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:317)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > org.apache.camel.processor.Pipeline$PipelineTask.run(Pipeline.java:102)
> > > ~[camel-core-processor-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.doRun(DefaultReactiveExecutor.java:199)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.executeReactiveWork(DefaultReactiveExecutor.java:189)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.tryExecuteReactiveWork(DefaultReactiveExecutor.java:166)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:148)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:59)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at org.apache.camel.processor.Pipeline.process(Pipeline.java:163)
> > > ~[camel-core-processor-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.CamelInternalProcessor.processNonTransacted(CamelInternalProcessor.java:354)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:330)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:293)
> > > ~[camel-timer-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.component.timer.TimerConsumer$1.doRun(TimerConsumer.java:164)
> > > ~[camel-timer-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:136)
> > > ~[camel-timer-4.4.2.jar:4.4.2]
> > > at java.base/java.util.TimerThread.mainLoop(Timer.java:566) ~[na:na]
> > > at java.base/java.util.TimerThread.run(Timer.java:516) ~[na:na]
> > > Caused by: org.apache.camel.TypeConversionException: Error during type
> > > conversion from type:
> > > org.apache.hc.client5.http.entity.LazyDecompressingInputStream to the
> > > required type: org.apache.camel.StreamCache with value
> > > org.apache.hc.client5.http.entity.LazyDecompressingInputStream@2e74480e
> > > due to java.io.IOException: Attempted read on closed stream.
> > > at
> > >
> >
> org.apache.camel.converter.stream.StreamCacheBulkConverterLoader.convertTo(StreamCacheBulkConverterLoader.java:62)
> > > ~[camel-support-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.spi.BulkTypeConverters.convertTo(BulkTypeConverters.java:122)
> > > ~[camel-api-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.converter.CoreTypeConverterRegistry.tryCachedConverters(CoreTypeConverterRegistry.java:419)
> > > ~[camel-base-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.converter.CoreTypeConverterRegistry.doConvertTo(CoreTypeConverterRegistry.java:378)
> > > ~[camel-base-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.converter.CoreTypeConverterRegistry.doConvertToAndStat(CoreTypeConverterRegistry.java:272)
> > > ~[camel-base-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.converter.CoreTypeConverterRegistry.convertTo(CoreTypeConverterRegistry.java:167)
> > > ~[camel-base-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.DefaultStreamCachingStrategy.doCache(DefaultStreamCachingStrategy.java:275)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.DefaultStreamCachingStrategy.cache(DefaultStreamCachingStrategy.java:252)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.impl.engine.StreamCachingHelper.tryStreamCache(StreamCachingHelper.java:68)
> > > ~[camel-base-engine-4.4.2.jar:4.4.2]
> > > ... 18 common frames omitted
> > > Caused by: java.io.IOException: Attempted read on closed stream.
> > > at
> > > org.apache.hc.core5.http.io
> > .EofSensorInputStream.isReadAllowed(EofSensorInputStream.java:107)
> > > ~[httpcore5-5.2.4.jar:5.2.4]
> > > at
> > > org.apache.hc.core5.http.io
> > .EofSensorInputStream.read(EofSensorInputStream.java:116)
> > > ~[httpcore5-5.2.4.jar:5.2.4]
> > > at
> > >
> >
> java.base/java.util.zip.CheckedInputStream.read(CheckedInputStream.java:59)
> > > ~[na:na]
> > > at
> > >
> >
> java.base/java.util.zip.GZIPInputStream.readUByte(GZIPInputStream.java:266)
> > > ~[na:na]
> > > at
> > >
> >
> java.base/java.util.zip.GZIPInputStream.readUShort(GZIPInputStream.java:258)
> > > ~[na:na]
> > > at
> > >
> >
> java.base/java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:164)
> > > ~[na:na]
> > > at
> > java.base/java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:79)
> > > ~[na:na]
> > > at
> > java.base/java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:91)
> > > ~[na:na]
> > > at
> > >
> >
> org.apache.hc.client5.http.entity.GZIPInputStreamFactory.create(GZIPInputStreamFactory.java:61)
> > > ~[httpclient5-5.2.3.jar:5.2.3]
> > > at
> > >
> >
> org.apache.hc.client5.http.entity.LazyDecompressingInputStream.initWrapper(LazyDecompressingInputStream.java:51)
> > > ~[httpclient5-5.2.3.jar:5.2.3]
> > > at
> > >
> >
> org.apache.hc.client5.http.entity.LazyDecompressingInputStream.available(LazyDecompressingInputStream.java:86)
> > > ~[httpclient5-5.2.3.jar:5.2.3]
> > > at org.apache.camel.util.IOHelper.copy(IOHelper.java:178)
> > > ~[camel-util-4.4.2.jar:4.4.2]
> > > at org.apache.camel.util.IOHelper.copy(IOHelper.java:164)
> > > ~[camel-util-4.4.2.jar:4.4.2]
> > > at org.apache.camel.util.IOHelper.copy(IOHelper.java:159)
> > > ~[camel-util-4.4.2.jar:4.4.2]
> > > at org.apache.camel.util.IOHelper.copyAndCloseInput(IOHelper.java:232)
> > > ~[camel-util-4.4.2.jar:4.4.2]
> > > at org.apache.camel.util.IOHelper.copyAndCloseInput(IOHelper.java:228)
> > > ~[camel-util-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.converter.stream.StreamCacheConverter.convertToStreamCache(StreamCacheConverter.java:54)
> > > ~[camel-support-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.converter.stream.StreamCacheBulkConverterLoader.doConvertTo(StreamCacheBulkConverterLoader.java:80)
> > > ~[camel-support-4.4.2.jar:4.4.2]
> > > at
> > >
> >
> org.apache.camel.converter.stream.StreamCacheBulkConverterLoader.convertTo(StreamCacheBulkConverterLoader.java:53)
> > > ~[camel-support-4.4.2.jar:4.4.2]
> > > ... 26 common frames omitted
> > >
> >
>
>
> --
> Claus Ibsen
> -----------------
> @davsclaus
> Camel in Action 2: https://www.manning.com/ibsen2
>

Reply via email to