You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/05/11 14:06:07 UTC

[camel] branch main updated: CAMEL-18098: camel-core - Stream caching should not spool to disk by default

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new d15cc12604c CAMEL-18098: camel-core - Stream caching should not spool to disk by default
d15cc12604c is described below

commit d15cc12604c02e0f01f565f5bebe31942828100a
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed May 11 16:01:56 2022 +0200

    CAMEL-18098: camel-core - Stream caching should not spool to disk by default
---
 .../processor/SpringStreamCachingStrategyTest.xml  |  2 +-
 .../apache/camel/spi/StreamCachingStrategy.java    | 14 +++++++
 .../camel/impl/engine/AbstractCamelContext.java    |  8 ++--
 .../impl/engine/DefaultStreamCachingStrategy.java  | 28 +++++++++-----
 .../org/apache/camel/core/xml/streamCaching.json   |  5 ++-
 .../core/xml/AbstractCamelContextFactoryBean.java  |  8 ++++
 .../xml/CamelStreamCachingStrategyDefinition.java  | 37 ++++++++++++++++--
 .../converter/stream/CachedOutputStreamTest.java   |  1 +
 .../MulticastParallelTimeoutStreamCachingTest.java |  1 +
 .../RedeliveryErrorHandlerNonBlockedDelayTest.java |  4 +-
 .../StreamCachingSpoolDirectoryQuarkusTest.java    |  1 +
 .../MainConfigurationPropertiesConfigurer.java     |  6 +++
 .../camel-main-configuration-metadata.json         |  3 +-
 core/camel-main/src/main/docs/main.adoc            |  5 ++-
 .../camel/main/DefaultConfigurationConfigurer.java |  1 +
 .../camel/main/DefaultConfigurationProperties.java | 44 +++++++++++++++++++++-
 .../ROOT/pages/camel-3x-upgrade-guide-3_17.adoc    | 41 ++++++++++++++++++++
 17 files changed, 182 insertions(+), 27 deletions(-)

diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/SpringStreamCachingStrategyTest.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/SpringStreamCachingStrategyTest.xml
index 2d76c4f4d7e..b1383a12cc2 100644
--- a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/SpringStreamCachingStrategyTest.xml
+++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/SpringStreamCachingStrategyTest.xml
@@ -26,7 +26,7 @@
 
   <camelContext streamCache="true" xmlns="http://camel.apache.org/schema/spring">
 
-    <streamCaching id="myCacheConfig" bufferSize="2048" spoolDirectory="target/cachedir" spoolThreshold="8192"/>
+    <streamCaching id="myCacheConfig" spoolEnabled="true" bufferSize="2048" spoolDirectory="target/cachedir" spoolThreshold="8192"/>
 
     <route>
       <from uri="direct:c"/>
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/StreamCachingStrategy.java b/core/camel-api/src/main/java/org/apache/camel/spi/StreamCachingStrategy.java
index 5c5eb1c47e0..4918f3974fa 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/StreamCachingStrategy.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/StreamCachingStrategy.java
@@ -114,6 +114,20 @@ public interface StreamCachingStrategy extends StaticService {
 
     boolean isEnabled();
 
+    /**
+     * Enables spooling to disk.
+     * <p/>
+     * <b>Notice:</b> This cannot be changed at runtime.
+     *
+     * Default is disabled.
+     */
+    void setSpoolEnabled(boolean spoolEnabled);
+
+    /**
+     * Is spooling to disk enabled.
+     */
+    boolean isSpoolEnabled();
+
     /**
      * Sets the spool (temporary) directory to use for overflow and spooling to disk.
      * <p/>
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 88b2c2e81e9..bdd9d7d0440 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -3209,13 +3209,13 @@ public abstract class AbstractCamelContext extends BaseService
                     getClassResolver(),
                     getPackageScanClassResolver(), getApplicationContextClassLoader(), getRouteController());
         }
-        if (!isStreamCaching()) {
+        if (isStreamCaching()) {
             // stream caching is default enabled so lets report if it has been disabled
-            LOG.info("StreamCaching is disabled on CamelContext: {}", getName());
+            LOG.debug("StreamCaching is disabled on CamelContext: {}", getName());
         }
         if (isBacklogTracing()) {
             // tracing is added in the DefaultChannel so we can enable it on the fly
-            LOG.info("Backlog Tracing is enabled on CamelContext: {}", getName());
+            LOG.debug("Backlog Tracing is enabled on CamelContext: {}", getName());
         }
         if (isTracing()) {
             // tracing is added in the DefaultChannel so we can enable it on the fly
@@ -3298,7 +3298,7 @@ public abstract class AbstractCamelContext extends BaseService
 
         if (isUseDataType()) {
             // log if DataType has been enabled
-            LOG.info("Message DataType is enabled on CamelContext: {}", getName());
+            LOG.debug("Message DataType is enabled on CamelContext: {}", getName());
         }
 
         // is there any stream caching enabled then log an info about this and
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java
index 2d0bd1ca242..88eb40a706d 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultStreamCachingStrategy.java
@@ -44,6 +44,7 @@ public class DefaultStreamCachingStrategy extends ServiceSupport implements Came
 
     private CamelContext camelContext;
     private boolean enabled;
+    private boolean spoolEnabled;
     private File spoolDirectory;
     private transient String spoolDirectoryName = "${java.io.tmpdir}/camel/camel-tmp-#uuid#";
     private long spoolThreshold = StreamCache.DEFAULT_SPOOL_THRESHOLD;
@@ -76,6 +77,16 @@ public class DefaultStreamCachingStrategy extends ServiceSupport implements Came
         this.enabled = enabled;
     }
 
+    @Override
+    public boolean isSpoolEnabled() {
+        return spoolEnabled;
+    }
+
+    @Override
+    public void setSpoolEnabled(boolean spoolEnabled) {
+        this.spoolEnabled = spoolEnabled;
+    }
+
     @Override
     public void setSpoolDirectory(String path) {
         this.spoolDirectoryName = path;
@@ -279,12 +290,10 @@ public class DefaultStreamCachingStrategy extends ServiceSupport implements Came
         }
 
         // if we can overflow to disk then make sure directory exists / is created
-        if (spoolThreshold > 0 || spoolUsedHeapMemoryThreshold > 0) {
-
+        if (spoolEnabled && (spoolThreshold > 0 || spoolUsedHeapMemoryThreshold > 0)) {
             if (spoolDirectory == null && spoolDirectoryName == null) {
                 throw new IllegalArgumentException("SpoolDirectory must be configured when using SpoolThreshold > 0");
             }
-
             if (spoolDirectory == null) {
                 String name = resolveSpoolDirectory(spoolDirectoryName);
                 if (name != null) {
@@ -294,7 +303,6 @@ public class DefaultStreamCachingStrategy extends ServiceSupport implements Came
                     throw new IllegalStateException("Cannot resolve spool directory from pattern: " + spoolDirectoryName);
                 }
             }
-
             if (spoolDirectory.exists()) {
                 if (spoolDirectory.isDirectory()) {
                     LOG.debug("Using spool directory: {}", spoolDirectory);
@@ -312,9 +320,7 @@ public class DefaultStreamCachingStrategy extends ServiceSupport implements Came
                 } else {
                     LOG.debug("Created spool directory: {}", spoolDirectory);
                 }
-
             }
-
             if (spoolThreshold > 0) {
                 spoolRules.add(new FixedThresholdSpoolRule());
             }
@@ -331,14 +337,17 @@ public class DefaultStreamCachingStrategy extends ServiceSupport implements Came
 
         if (spoolDirectory != null) {
             LOG.info("StreamCaching in use with spool directory: {} and rules: {}", spoolDirectory.getPath(), spoolRules);
-        } else {
+        } else if (!spoolRules.isEmpty()) {
             LOG.info("StreamCaching in use with rules: {}", spoolRules);
+        } else {
+            // reduce logging noise when its in-memory stream caching
+            LOG.debug("StreamCaching in use");
         }
     }
 
     @Override
     protected void doStop() throws Exception {
-        if (spoolThreshold > 0 & spoolDirectory != null && isRemoveSpoolDirectoryWhenStopping()) {
+        if (spoolEnabled && (spoolThreshold > 0 & spoolDirectory != null && isRemoveSpoolDirectoryWhenStopping())) {
             LOG.debug("Removing spool directory: {}", spoolDirectory);
             FileUtil.removeDir(spoolDirectory);
         }
@@ -353,7 +362,8 @@ public class DefaultStreamCachingStrategy extends ServiceSupport implements Came
     @Override
     public String toString() {
         return "DefaultStreamCachingStrategy["
-               + "spoolDirectory=" + spoolDirectory
+               + "spoolDirectoryEnabled=" + spoolEnabled
+               + ", spoolDirectory=" + spoolDirectory
                + ", spoolCipher=" + spoolCipher
                + ", spoolThreshold=" + spoolThreshold
                + ", spoolUsedHeapMemoryThreshold=" + spoolUsedHeapMemoryThreshold
diff --git a/core/camel-core-xml/src/generated/resources/org/apache/camel/core/xml/streamCaching.json b/core/camel-core-xml/src/generated/resources/org/apache/camel/core/xml/streamCaching.json
index 5cd31cbfaff..c0e2a90ade1 100644
--- a/core/camel-core-xml/src/generated/resources/org/apache/camel/core/xml/streamCaching.json
+++ b/core/camel-core-xml/src/generated/resources/org/apache/camel/core/xml/streamCaching.json
@@ -12,7 +12,8 @@
     "output": false
   },
   "properties": {
-    "enabled": { "kind": "attribute", "displayName": "Enabled", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "false", "description": "Sets whether the stream caching is enabled. Notice: This cannot be changed at runtime." },
+    "enabled": { "kind": "attribute", "displayName": "Enabled", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether stream caching is enabled or not. 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 w [...]
+    "spoolEnabled": { "kind": "attribute", "displayName": "Spool Enabled", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To enable stream caching spooling to disk. This means, for large stream messages (over 128 KB by default) will be cached in a temporary file instead, and Camel will handle deleting the temporary file once the cached stream is no longer necessary. De [...]
     "spoolDirectory": { "kind": "attribute", "displayName": "Spool Directory", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the spool (temporary) directory to use for overflow and spooling to disk. If no spool directory has been explicit configured, then a temporary directory is created in the java.io.tmpdir directory." },
     "spoolCipher": { "kind": "attribute", "displayName": "Spool Cipher", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets a cipher name to use when spooling to disk to write with encryption. By default the data is not encrypted." },
     "spoolThreshold": { "kind": "attribute", "displayName": "Spool Threshold", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Threshold in bytes when overflow to disk is activated. The default threshold is org.apache.camel.StreamCache#DEFAULT_SPOOL_THRESHOLD bytes (eg 128kb). Use -1 to disable overflow to disk." },
@@ -21,7 +22,7 @@
     "spoolRules": { "kind": "attribute", "displayName": "Spool Rules", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Reference to one or more custom org.apache.camel.spi.StreamCachingStrategy.SpoolRule to use. Multiple rules can be separated by comma." },
     "bufferSize": { "kind": "attribute", "displayName": "Buffer Size", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the buffer size to use when allocating in-memory buffers used for in-memory stream caches. The default size is org.apache.camel.util.IOHelper#DEFAULT_BUFFER_SIZE" },
     "removeSpoolDirectoryWhenStopping": { "kind": "attribute", "displayName": "Remove Spool Directory When Stopping", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "true", "description": "Whether to remove the temporary directory when stopping. This option is default true" },
-    "statisticsEnabled": { "kind": "attribute", "displayName": "Statistics Enabled", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets whether statistics is enabled." },
+    "statisticsEnabled": { "kind": "attribute", "displayName": "Statistics Enabled", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Sets whether statistics is enabled." },
     "anySpoolRules": { "kind": "attribute", "displayName": "Any Spool Rules", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "false", "description": "Sets whether if just any of the org.apache.camel.spi.StreamCachingStrategy.SpoolRule rules returns true then shouldSpoolCache(long) returns true. If this option is false, then all the org.apache.camel.spi.StreamCachingStrategy.SpoolRule must retu [...]
     "id": { "kind": "attribute", "displayName": "Id", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The id of this node" }
   }
diff --git a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index b9238c769fa..43787c7b9ce 100644
--- a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -724,12 +724,20 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
     protected void initStreamCachingStrategy() throws Exception {
         CamelStreamCachingStrategyDefinition streamCaching = getCamelStreamCachingStrategy();
         if (streamCaching == null) {
+            getContext().getStreamCachingStrategy().setEnabled(true);
             return;
         }
 
         Boolean enabled = CamelContextHelper.parseBoolean(getContext(), streamCaching.getEnabled());
         if (enabled != null) {
             getContext().getStreamCachingStrategy().setEnabled(enabled);
+        } else {
+            // stream-caching is default enabled
+            getContext().getStreamCachingStrategy().setEnabled(true);
+        }
+        Boolean spoolEnabled = CamelContextHelper.parseBoolean(getContext(), streamCaching.getSpoolEnabled());
+        if (spoolEnabled != null) {
+            getContext().getStreamCachingStrategy().setSpoolEnabled(spoolEnabled);
         }
         String spoolDirectory = CamelContextHelper.parseText(getContext(), streamCaching.getSpoolDirectory());
         if (spoolDirectory != null) {
diff --git a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/CamelStreamCachingStrategyDefinition.java b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/CamelStreamCachingStrategyDefinition.java
index d221153d28c..c54a3e4536b 100644
--- a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/CamelStreamCachingStrategyDefinition.java
+++ b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/CamelStreamCachingStrategyDefinition.java
@@ -33,9 +33,12 @@ import org.apache.camel.spi.Metadata;
 public class CamelStreamCachingStrategyDefinition extends IdentifiedType {
 
     @XmlAttribute
-    @Metadata(defaultValue = "false")
+    @Metadata(defaultValue = "true", javaType = "java.lang.Boolean")
     private String enabled;
     @XmlAttribute
+    @Metadata(defaultValue = "false", javaType = "java.lang.Boolean")
+    private String spoolEnabled;
+    @XmlAttribute
     private String spoolDirectory;
     @XmlAttribute
     private String spoolCipher;
@@ -53,6 +56,7 @@ public class CamelStreamCachingStrategyDefinition extends IdentifiedType {
     @Metadata(defaultValue = "true")
     private String removeSpoolDirectoryWhenStopping;
     @XmlAttribute
+    @Metadata(defaultValue = "false", javaType = "java.lang.Boolean")
     private String statisticsEnabled;
     @XmlAttribute
     @Metadata(defaultValue = "false")
@@ -63,14 +67,39 @@ public class CamelStreamCachingStrategyDefinition extends IdentifiedType {
     }
 
     /**
-     * Sets whether the stream caching is enabled.
-     * <p/>
-     * <b>Notice:</b> This cannot be changed at runtime.
+     * Sets whether stream caching is enabled or not.
+     *
+     * 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 cached in memory only (by default).
+     *
+     * If streamCachingSpoolEnabled=true, then, for large stream messages (over 128 KB by default) will be cached in a
+     * temporary file instead, and Camel will handle deleting the temporary file once the cached stream is no longer
+     * necessary.
+     *
+     * Default is true.
      */
     public void setEnabled(String enabled) {
         this.enabled = enabled;
     }
 
+    public String getSpoolEnabled() {
+        return spoolEnabled;
+    }
+
+    /**
+     * To enable stream caching spooling to disk. This means, for large stream messages (over 128 KB by default) will be cached in a
+     * temporary file instead, and Camel will handle deleting the temporary file once the cached stream is no longer
+     * necessary.
+     *
+     * Default is false.
+     */
+    public void setSpoolEnabled(String spoolEnabled) {
+        this.spoolEnabled = spoolEnabled;
+    }
+
     public String getSpoolDirectory() {
         return spoolDirectory;
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/converter/stream/CachedOutputStreamTest.java b/core/camel-core/src/test/java/org/apache/camel/converter/stream/CachedOutputStreamTest.java
index daa8dc1c107..916d9c49e46 100644
--- a/core/camel-core/src/test/java/org/apache/camel/converter/stream/CachedOutputStreamTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/converter/stream/CachedOutputStreamTest.java
@@ -54,6 +54,7 @@ public class CachedOutputStreamTest extends ContextTestSupport {
         CamelContext context = super.createCamelContext();
         context.setStreamCaching(true);
         context.getStreamCachingStrategy().setSpoolDirectory(testDirectory(true).toFile());
+        context.getStreamCachingStrategy().setSpoolEnabled(true);
         context.getStreamCachingStrategy().setSpoolThreshold(16);
         return context;
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/MulticastParallelTimeoutStreamCachingTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/MulticastParallelTimeoutStreamCachingTest.java
index 24c547d4afd..772162fde04 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/MulticastParallelTimeoutStreamCachingTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/MulticastParallelTimeoutStreamCachingTest.java
@@ -103,6 +103,7 @@ public class MulticastParallelTimeoutStreamCachingTest extends ContextTestSuppor
             public void configure() {
                 // enable stream caching
                 context.getStreamCachingStrategy().setSpoolDirectory(testDirectory().toFile());
+                context.getStreamCachingStrategy().setSpoolEnabled(true);
                 context.getStreamCachingStrategy().setEnabled(true);
                 context.getStreamCachingStrategy().setRemoveSpoolDirectoryWhenStopping(false);
                 context.getStreamCachingStrategy().setSpoolThreshold(1L);
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerNonBlockedDelayTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerNonBlockedDelayTest.java
index aeddfea4f5f..be1e04c90dd 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerNonBlockedDelayTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/RedeliveryErrorHandlerNonBlockedDelayTest.java
@@ -34,12 +34,12 @@ public class RedeliveryErrorHandlerNonBlockedDelayTest extends ContextTestSuppor
     @Test
     public void testRedelivery() throws Exception {
         MockEndpoint before = getMockEndpoint("mock:result");
-        before.expectedBodiesReceived("Hello World", "Hello Camel");
+        before.expectedBodiesReceivedInAnyOrder("Hello World", "Hello Camel");
 
         // we use NON blocked redelivery delay so the messages arrive which
         // completes first
         MockEndpoint result = getMockEndpoint("mock:result");
-        result.expectedBodiesReceived("Hello Camel", "Hello World");
+        result.expectedBodiesReceivedInAnyOrder("Hello Camel", "Hello World");
 
         template.sendBody("seda:start", "World");
         template.sendBody("seda:start", "Camel");
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/StreamCachingSpoolDirectoryQuarkusTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/StreamCachingSpoolDirectoryQuarkusTest.java
index 22a99705436..807056f5f55 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/StreamCachingSpoolDirectoryQuarkusTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/StreamCachingSpoolDirectoryQuarkusTest.java
@@ -90,6 +90,7 @@ public class StreamCachingSpoolDirectoryQuarkusTest extends ContextTestSupport {
             @Override
             public void configure() throws Exception {
                 context.getStreamCachingStrategy().setSpoolDirectory(testDirectory().toFile());
+                context.getStreamCachingStrategy().setSpoolEnabled(true);
                 context.getStreamCachingStrategy().addSpoolRule(spoolRule);
                 context.getStreamCachingStrategy().setAnySpoolRules(true);
                 context.setStreamCaching(true);
diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
index 5a2510cda73..fd03a1a7ac8 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
@@ -221,6 +221,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "StreamCachingSpoolCipher": target.setStreamCachingSpoolCipher(property(camelContext, java.lang.String.class, value)); return true;
         case "streamcachingspooldirectory":
         case "StreamCachingSpoolDirectory": target.setStreamCachingSpoolDirectory(property(camelContext, java.lang.String.class, value)); return true;
+        case "streamcachingspoolenabled":
+        case "StreamCachingSpoolEnabled": target.setStreamCachingSpoolEnabled(property(camelContext, boolean.class, value)); return true;
         case "streamcachingspoolthreshold":
         case "StreamCachingSpoolThreshold": target.setStreamCachingSpoolThreshold(property(camelContext, long.class, value)); return true;
         case "streamcachingspoolusedheapmemorylimit":
@@ -454,6 +456,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "StreamCachingSpoolCipher": return java.lang.String.class;
         case "streamcachingspooldirectory":
         case "StreamCachingSpoolDirectory": return java.lang.String.class;
+        case "streamcachingspoolenabled":
+        case "StreamCachingSpoolEnabled": return boolean.class;
         case "streamcachingspoolthreshold":
         case "StreamCachingSpoolThreshold": return long.class;
         case "streamcachingspoolusedheapmemorylimit":
@@ -688,6 +692,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "StreamCachingSpoolCipher": return target.getStreamCachingSpoolCipher();
         case "streamcachingspooldirectory":
         case "StreamCachingSpoolDirectory": return target.getStreamCachingSpoolDirectory();
+        case "streamcachingspoolenabled":
+        case "StreamCachingSpoolEnabled": return target.isStreamCachingSpoolEnabled();
         case "streamcachingspoolthreshold":
         case "StreamCachingSpoolThreshold": return target.getStreamCachingSpoolThreshold();
         case "streamcachingspoolusedheapmemorylimit":
diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index d6df43111f8..26c9225dcaf 100644
--- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -109,10 +109,11 @@
     { "name": "camel.main.startupSummaryLevel", "description": "Controls the level of information logged during startup (and shutdown) of CamelContext.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "object", "javaType": "org.apache.camel.StartupSummaryLevel", "defaultValue": "Default" },
     { "name": "camel.main.streamCachingAnySpoolRules", "description": "Sets whether if just any of the org.apache.camel.spi.StreamCachingStrategy.SpoolRule rules returns true then shouldSpoolCache(long) returns true, to allow spooling to disk. If this option is false, then all the org.apache.camel.spi.StreamCachingStrategy.SpoolRule must return true. The default value is false which means that all the rules must return true.", "sourceType": "org.apache.camel.main.DefaultConfigurationProp [...]
     { "name": "camel.main.streamCachingBufferSize", "description": "Sets the stream caching buffer size to use when allocating in-memory buffers used for in-memory stream caches. The default size is 4096.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int" },
-    { "name": "camel.main.streamCachingEnabled", "description": "Sets whether stream caching is enabled or not. 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 cached in memory. However, for large stream messages (over 128 KB by default) will be c [...]
+    { "name": "camel.main.streamCachingEnabled", "description": "Sets whether stream caching is enabled or not. 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 cached in memory only (by default). If streamCachingSpoolEnabled=true, then, for large  [...]
     { "name": "camel.main.streamCachingRemoveSpoolDirectoryWhenStopping", "description": "Whether to remove stream caching temporary directory when stopping. This option is default true.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.main.streamCachingSpoolCipher", "description": "Sets a stream caching cipher name to use when spooling to disk to write with encryption. By default the data is not encrypted.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
     { "name": "camel.main.streamCachingSpoolDirectory", "description": "Sets the stream caching spool (temporary) directory to use for overflow and spooling to disk. If no spool directory has been explicit configured, then a temporary directory is created in the java.io.tmpdir directory.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
+    { "name": "camel.main.streamCachingSpoolEnabled", "description": "To enable stream caching spooling to disk. This means, for large stream messages (over 128 KB by default) will be cached in a temporary file instead, and Camel will handle deleting the temporary file once the cached stream is no longer necessary. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.streamCachingSpoolThreshold", "description": "Stream caching threshold in bytes when overflow to disk is activated. The default threshold is 128kb. Use -1 to disable overflow to disk.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "long" },
     { "name": "camel.main.streamCachingSpoolUsedHeapMemoryLimit", "description": "Sets what the upper bounds should be when streamCachingSpoolUsedHeapMemoryThreshold is in use.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
     { "name": "camel.main.streamCachingSpoolUsedHeapMemoryThreshold", "description": "Sets a percentage (1-99) of used heap memory threshold to activate stream caching spooling to disk.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int" },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index a387bd9e338..c9bd04497a3 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -18,7 +18,7 @@ The following tables lists all the options:
 
 // main options: START
 === Camel Main configurations
-The camel.main supports 113 options, which are listed below.
+The camel.main supports 114 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -119,10 +119,11 @@ The camel.main supports 113 options, which are listed below.
 | *camel.main.startupSummaryLevel* | Controls the level of information logged during startup (and shutdown) of CamelContext. | Default | StartupSummaryLevel
 | *camel.main.streamCachingAny{zwsp}SpoolRules* | Sets whether if just any of the org.apache.camel.spi.StreamCachingStrategy.SpoolRule rules returns true then shouldSpoolCache(long) returns true, to allow spooling to disk. If this option is false, then all the org.apache.camel.spi.StreamCachingStrategy.SpoolRule must return true. The default value is false which means that all the rules must return true. | false | boolean
 | *camel.main.streamCachingBuffer{zwsp}Size* | Sets the stream caching buffer size to use when allocating in-memory buffers used for in-memory stream caches. The default size is 4096. |  | int
-| *camel.main.streamCaching{zwsp}Enabled* | Sets whether stream caching is enabled or not. 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 cached in memory. However, for large stream messages (over 128 KB by default) will be cached in a temporary  [...]
+| *camel.main.streamCaching{zwsp}Enabled* | Sets whether stream caching is enabled or not. 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 cached in memory only (by default). If streamCachingSpoolEnabled=true, then, for large stream messages (over [...]
 | *camel.main.streamCachingRemove{zwsp}SpoolDirectoryWhenStopping* | Whether to remove stream caching temporary directory when stopping. This option is default true. | true | boolean
 | *camel.main.streamCachingSpool{zwsp}Cipher* | Sets a stream caching cipher name to use when spooling to disk to write with encryption. By default the data is not encrypted. |  | String
 | *camel.main.streamCachingSpool{zwsp}Directory* | Sets the stream caching spool (temporary) directory to use for overflow and spooling to disk. If no spool directory has been explicit configured, then a temporary directory is created in the java.io.tmpdir directory. |  | String
+| *camel.main.streamCachingSpool{zwsp}Enabled* | To enable stream caching spooling to disk. This means, for large stream messages (over 128 KB by default) will be cached in a temporary file instead, and Camel will handle deleting the temporary file once the cached stream is no longer necessary. Default is false. | false | boolean
 | *camel.main.streamCachingSpool{zwsp}Threshold* | Stream caching threshold in bytes when overflow to disk is activated. The default threshold is 128kb. Use -1 to disable overflow to disk. |  | long
 | *camel.main.streamCachingSpool{zwsp}UsedHeapMemoryLimit* | Sets what the upper bounds should be when streamCachingSpoolUsedHeapMemoryThreshold is in use. |  | String
 | *camel.main.streamCachingSpool{zwsp}UsedHeapMemoryThreshold* | Sets a percentage (1-99) of used heap memory threshold to activate stream caching spooling to disk. |  | int
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index 2c7a769ac87..24f82e2ee5c 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -177,6 +177,7 @@ public final class DefaultConfigurationConfigurer {
 
         // stream caching
         camelContext.setStreamCaching(config.isStreamCachingEnabled());
+        camelContext.getStreamCachingStrategy().setSpoolEnabled(config.isStreamCachingSpoolEnabled());
         camelContext.getStreamCachingStrategy().setAnySpoolRules(config.isStreamCachingAnySpoolRules());
         camelContext.getStreamCachingStrategy().setBufferSize(config.getStreamCachingBufferSize());
         camelContext.getStreamCachingStrategy()
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index 3da030fb362..7423cea21ed 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -58,6 +58,7 @@ public abstract class DefaultConfigurationProperties<T> {
     private boolean modeline;
     private int logDebugMaxChars;
     private boolean streamCachingEnabled = true;
+    private boolean streamCachingSpoolEnabled;
     private String streamCachingSpoolDirectory;
     private String streamCachingSpoolCipher;
     private long streamCachingSpoolThreshold;
@@ -433,7 +434,9 @@ public abstract class DefaultConfigurationProperties<T> {
      * 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 cached in memory. However, for large stream messages (over 128 KB by default) will be cached in a
+     * Streams are cached in memory only (by default).
+     *
+     * If streamCachingSpoolEnabled=true, then, for large stream messages (over 128 KB by default) will be cached in a
      * temporary file instead, and Camel will handle deleting the temporary file once the cached stream is no longer
      * necessary.
      *
@@ -443,6 +446,21 @@ public abstract class DefaultConfigurationProperties<T> {
         this.streamCachingEnabled = streamCachingEnabled;
     }
 
+    public boolean isStreamCachingSpoolEnabled() {
+        return streamCachingSpoolEnabled;
+    }
+
+    /**
+     * To enable stream caching spooling to disk. This means, for large stream messages (over 128 KB by default) will be cached in a
+     * temporary file instead, and Camel will handle deleting the temporary file once the cached stream is no longer
+     * necessary.
+     *
+     * Default is false.
+     */
+    public void setStreamCachingSpoolEnabled(boolean streamCachingSpoolEnabled) {
+        this.streamCachingSpoolEnabled = streamCachingSpoolEnabled;
+    }
+
     public String getStreamCachingSpoolDirectory() {
         return streamCachingSpoolDirectory;
     }
@@ -1711,13 +1729,35 @@ public abstract class DefaultConfigurationProperties<T> {
     /**
      * Sets whether stream caching is enabled or not.
      *
-     * Default is false.
+     * 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 cached in memory only (by default).
+     *
+     * If streamCachingSpoolEnabled=true, then, for large stream messages (over 128 KB by default) will be cached in a
+     * temporary file instead, and Camel will handle deleting the temporary file once the cached stream is no longer
+     * necessary.
+     *
+     * Default is true.
      */
     public T withStreamCachingEnabled(boolean streamCachingEnabled) {
         this.streamCachingEnabled = streamCachingEnabled;
         return (T) this;
     }
 
+    /**
+     * To enable stream caching spooling to disk. This means, for large stream messages (over 128 KB by default) will be cached in a
+     * temporary file instead, and Camel will handle deleting the temporary file once the cached stream is no longer
+     * necessary.
+     *
+     * Default is false.
+     */
+    public T withStreamCachingSpoolEnabled(boolean streamCachingSpoolEnabled) {
+        this.streamCachingSpoolEnabled = streamCachingSpoolEnabled;
+        return (T) this;
+    }
+
     /**
      * Sets the stream caching spool (temporary) directory to use for overflow and spooling to disk.
      *
diff --git a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_17.adoc b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_17.adoc
index 981c308a9ca..d166822e483 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_17.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_17.adoc
@@ -8,6 +8,8 @@ from both 3.0 to 3.1 and 3.1 to 3.2.
 
 === camel-core
 
+==== Stream Caching
+
 We have enabled xref:stream-caching.adoc[Stream Caching] by default on `CamelContext`. The reason is that Camel users
 may often hit this problem without knowing what is causing this, and blaming it on Apache Camel.
 
@@ -37,6 +39,45 @@ Or in Spring Boot
 camel.springboot.streamCachingEnabled=false
 ----
 
+And in legacy Spring XML or OSGi Blueprint:
+
+[source,xml]
+----
+<streamCaching enabled="true" .../>
+----
+
+We also changed the default settings for stream caching to not spool to disk, meaning that the cache
+is an in-memory on cache.
+
+To enable spool to disk, you can configure this as follows:
+
+[source,java]
+----
+CamelContext context = ...
+context.getStreamCachingStrategy().setSpoolEnabled(true);
+----
+
+Or via Camel Main / Camel K / Quarkus:
+
+[source,properties]
+----
+camel.main.streamCachingSpoolEnabled=true
+----
+
+Or in Spring Boot
+
+[source,properties]
+----
+camel.springboot.streamCachingSpoolEnabled=true
+----
+
+And in legacy Spring XML or OSGi Blueprint:
+
+[source,xml]
+----
+<streamCaching spoolEnabled="true" .../>
+----
+
 === camel-health
 
 Camel now reports DOWN when Camel is being stopped, during the graceful shutdown process.