While stream types (like StreamSource, InputStream and Reader) are commonly used in messaging for performance reasons, they also have an important drawback: they can only be read once. In order to be able to work with message content multiple times, the stream needs to be cached.
Streams are caching in memory. In Camel 2.0, large stream messages (over 64 Kb in Camel 2.11 or older, and 128 kb from Camel 2.12 onwards) will be cached in a temporary file instead – Camel itself will handle deleting the temporary file once the cached stream is no longer necessary.
In Camel 2.0 stream cache is default disabled out of the box.
StreamCache Affects your payload object
The StreamCache will affect your payload object as it will replace the Stream payload with a
However to not change the payload under the covers without the end user really knowing we changed the default in Camel 2.0 to disabled. So in Camel 2.0 you have to explicit enable it if you want to use it.
If using Camel 2.12 onwards then see about StreamCachingStrategy further below which is the recommended way to configure stream caching options.
Enabling stream caching
In Apache Camel, you can explicitly enable stream caching for a single route with the
In Spring XML you enable it by setting the
StreamCache supports the global and per route scope. So by setting the streamCache attribute on camelContext you can enable/disable it globally.
The route scope is configured by the
You can mix and match for instance you can enable it globally and disable it on a particular route such as:
Enabling from Java DSL
You can enable stream cache by setting the property on CamelContext, for instance in a RouteBuilder class:
Disable stream caching explicitly
If you have enabled stream caching globally on the CamelContext and you want to disable it for certain routes in a selective manner, you can use the following syntax.
Streaming cache to files
When stream cache is enabled it will by default spool big streams to files instead of keeping them in memory. The default threshold is 64kb but you can configure it with the following properties:
You set these properties on the CamelContext as shown below, where we use a 1mb threshold to spool to disk for messages bigger than 1mb:
And in XML you do
Disabling spooling to disk
You can disable spooling to disk by setting a threshold of 0 or a negative value.
And in XML you do
Available as of Camel 2.12
Stream caching is from Camel 2.12 onwards intended to be configured using
The strategy has the following options:
SpoolDirectory naming pattern
The following patterns is supported:
A could of examples, to store in the java temp directory with a sub directory using the CamelContext name:
To store in KARAF_HOME/tmp/bundleId directory
Using StreamCachingStrategy in Java
You can configure the
Using StreamCachingStrategy in XML
And in XML you do:
You can also define a <bean> instead of using the <streamCaching> tag:
And in XML you do
By default stream caching will spool only big payloads (128kb or bigger) to disk. However you can also set the spoolUsedHeapMemoryThreshold option which is a percentage of used heap memory. This can be used to also spool to disk when running low on memory.
For example with:
Then notice that as spoolThreshold is default enabled with 128kb, then we have both thresholds in use (spoolThreshold and spoolUsedHeapMemoryThreshold). And in this example then we only spool to disk if payload is > 128kb and that used heap memory is > 70%. The reason is that we have the option
If we want to spool to disk if either of the rules (eg OR), then we can do:
If we only want to spool to disk if we run low on memory then we can set:
... then we do not use the spoolThreshold rule, and only the heap memory based is in use.
By default the upper limit of the used heap memory is based on the maximum heap size. Though you can also configure to use the committed heap size as the upper limit, this is done using the
Using custom SpoolRule implementations
You can implement your custom rules to determine if the stream should be spooled to disk. This can be done by implementing the interface
The length is the length of the stream.
To use the rule then add it to the
And from XML you need to define a <bean> with your custom rule
How it works?
In order to determine if a type requires caching, we leverage the type converter feature. Any type that requires stream caching can be converted into an