Anton Berzelius created CAMEL-26640:
---------------------------------------
Summary: Route level StreamCachingAdvice fails exchange with
"Cannot reset stream from file" when using spooled stream cache
Key: CAMEL-26640
URL: https://issues.apache.org/jira/browse/CAMEL-26640
Project: Camel
Issue Type: Bug
Components: came-core
Affects Versions: 4.23.0, 4.22.2, 4.22.1, 4.18.5
Reporter: Anton Berzelius
Since CAMEL-24392 (fixed in 4.18.5, 4.22.1, 4.23.0),
CamelInternalProcessor.addRouteLifecycleAdvice adds a StreamCachingAdvice to
the route level internal processor of every route with stream caching enabled.
As the advice has order Ordered.HIGHEST, its after() runs last, after
UnitOfWorkProcessorAdvice.after() has done the unit of work. Doing the unit of
work runs the on completions, including the one from
CachedOutputStream/TempFileManager that deletes the spool file of a
FileInputStreamCache. StreamCachingAdvice.after() then calls
MessageHelper.resetStreamCache() on the body, and FileInputStreamCache.reset()
throws because the file no longer exists:
{noformat}
org.apache.camel.RuntimeCamelException: Cannot reset stream from file
/tmp/camel/camel-tmp-.../cos7728779785713617308.tmp
at
org.apache.camel.converter.stream.FileInputStreamCache.reset(FileInputStreamCache.java:98)
at
org.apache.camel.support.MessageHelper.resetStreamCache(MessageHelper.java:140)
at
org.apache.camel.impl.engine.CamelInternalProcessor$StreamCachingAdvice.after(CamelInternalProcessor.java:1309)
at
org.apache.camel.impl.engine.AdviceIterator.runAfterTask(AdviceIterator.java:60)
at
org.apache.camel.impl.engine.AdviceIterator.runAfterTasks(AdviceIterator.java:54)
at
org.apache.camel.impl.engine.AdviceIterator.runAfterTasks(AdviceIterator.java:31)
at
org.apache.camel.impl.engine.CamelInternalProcessor$AsyncAfterTask.done(CamelInternalProcessor.java:266)
at
org.apache.camel.impl.engine.DefaultUnitOfWork$UnitOfWorkCallback.done(DefaultUnitOfWork.java:523)
...
at
org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:136)
{noformat}
The exception is set on the exchange after the route has completed, so the
exchange fails even though all processing succeeded.
h3. Conditions
All of these must hold:
* stream caching is enabled on the route;
* the route owns the unit of work, i.e. the exchange was created by the route's
consumer (JMS, file, timer, ...). When the route is called from a
ProducerTemplate, or via direct: from another route, the caller
owns the unit of work, so the file still exists when the route level advice
resets it, and nothing fails;
* the body at the end of the route is a FileInputStreamCache. This needs
spooling enabled (spoolEnabled=true), and a body above spoolThreshold or a
spool rule matching, such as spoolUsedHeapMemoryThreshold.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)