This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 3.6.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit db4d23057d58ca9bf25eff1d95aa556d0f1b582d Author: Andriy Redko <[email protected]> AuthorDate: Sat Oct 26 10:17:04 2024 -0400 CXF-7396: CachedOutputStream doesn't delete temp files. Add forced cleanup on Bus shutdown (#2111) (cherry picked from commit bbba93ebbaf0d2978f5605bfc16001825c138efe) (cherry picked from commit addaf007f612d73dc3adf4db0d2571b8d5dcb403) --- .../java/org/apache/cxf/io/CachedConstants.java | 8 ++++++++ .../cxf/io/DelayedCachedOutputStreamCleaner.java | 19 ++++++++++++++++- .../io/DelayedCachedOutputStreamCleanerTest.java | 24 +++++++++++++++++++++- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/cxf/io/CachedConstants.java b/core/src/main/java/org/apache/cxf/io/CachedConstants.java index 1b23f66e99..7b45d0861b 100644 --- a/core/src/main/java/org/apache/cxf/io/CachedConstants.java +++ b/core/src/main/java/org/apache/cxf/io/CachedConstants.java @@ -79,6 +79,14 @@ public final class CachedConstants { public static final String CLEANER_DELAY_BUS_PROP = "bus.io.CachedOutputStreamCleaner.Delay"; + /** + * Forces cleaning of the unclosed {@code CachedOutputStream} instances on {@link Bus} shutdown. + * The default value is "true", if the cleaner is deactivated or the value is set to "false", no + * cleanup attempt on shutdown will be performed. + */ + public static final String CLEANER_CLEAN_ON_SHUTDOWN_BUS_PROP = + "bus.io.CachedOutputStreamCleaner.CleanOnShutdown"; + private CachedConstants() { // complete } diff --git a/core/src/main/java/org/apache/cxf/io/DelayedCachedOutputStreamCleaner.java b/core/src/main/java/org/apache/cxf/io/DelayedCachedOutputStreamCleaner.java index 5edc8027ed..5124e4ef21 100644 --- a/core/src/main/java/org/apache/cxf/io/DelayedCachedOutputStreamCleaner.java +++ b/core/src/main/java/org/apache/cxf/io/DelayedCachedOutputStreamCleaner.java @@ -47,6 +47,7 @@ public final class DelayedCachedOutputStreamCleaner implements CachedOutputStrea }; private DelayedCleaner cleaner = NOOP_CLEANER; + private boolean cleanupOnShutdown = true; private interface DelayedCleaner extends CachedOutputStreamCleaner, Closeable { @Override @@ -175,9 +176,11 @@ public final class DelayedCachedOutputStreamCleaner implements CachedOutputStrea public void setBus(Bus bus) { Number delayValue = null; BusLifeCycleManager busLifeCycleManager = null; + Boolean cleanupOnShutdownValue = null; if (bus != null) { delayValue = (Number) bus.getProperty(CachedConstants.CLEANER_DELAY_BUS_PROP); + cleanupOnShutdownValue = (Boolean) bus.getProperty(CachedConstants.CLEANER_CLEAN_ON_SHUTDOWN_BUS_PROP); busLifeCycleManager = bus.getExtension(BusLifeCycleManager.class); } @@ -185,6 +188,12 @@ public final class DelayedCachedOutputStreamCleaner implements CachedOutputStrea cleaner.close(); } + if (cleanupOnShutdownValue != null) { + cleanupOnShutdown = cleanupOnShutdownValue; + } else { + cleanupOnShutdown = true; + } + if (delayValue == null) { // Default delay is set to 30 mins cleaner = new DelayedCleanerImpl(TimeUnit.MILLISECONDS.convert(30, TimeUnit.MINUTES)); @@ -227,11 +236,19 @@ public final class DelayedCachedOutputStreamCleaner implements CachedOutputStrea @Override public void postShutdown() { + // If cleanup on shutdown is asked, force cleaning all cached output streams + if (cleanupOnShutdown) { + forceClean(); + cleaner.close(); + } } @Override public void preShutdown() { - cleaner.close(); + // If cleanup on shutdown is asked, defer closing till postShutdown hook + if (!cleanupOnShutdown) { + cleaner.close(); + } } public void forceClean() { diff --git a/core/src/test/java/org/apache/cxf/io/DelayedCachedOutputStreamCleanerTest.java b/core/src/test/java/org/apache/cxf/io/DelayedCachedOutputStreamCleanerTest.java index 3f0603aa7f..8fcb12cf46 100644 --- a/core/src/test/java/org/apache/cxf/io/DelayedCachedOutputStreamCleanerTest.java +++ b/core/src/test/java/org/apache/cxf/io/DelayedCachedOutputStreamCleanerTest.java @@ -146,7 +146,7 @@ public class DelayedCachedOutputStreamCleanerTest { } @Test - public void testBusLifecycle() throws InterruptedException { + public void testCleanOnShutdown() throws InterruptedException { /* Delay of 2.5 seconds */ final Map<String, Object> properties = Collections.singletonMap(CachedConstants.CLEANER_DELAY_BUS_PROP, 2500); bus = new ExtensionManagerBus(new HashMap<>(), properties); @@ -161,6 +161,28 @@ public class DelayedCachedOutputStreamCleanerTest { // Closes the bus, the cleaner should cancel the internal timer(s) bus.shutdown(true); + // The Closeable::close should be called on shutdown + assertThat(latch.get(), is(true)); + } + + @Test + public void testCleanOnShutdownDisabled() throws InterruptedException { + /* Delay of 2.5 seconds */ + final Map<String, Object> properties = new HashMap<>(); + properties.put(CachedConstants.CLEANER_DELAY_BUS_PROP, 2500); + properties.put(CachedConstants.CLEANER_CLEAN_ON_SHUTDOWN_BUS_PROP, false); + bus = new ExtensionManagerBus(new HashMap<>(), properties); + + final AtomicBoolean latch = new AtomicBoolean(); + final Closeable closeable = () -> latch.compareAndSet(false, true); + + bus.setProperty(CachedConstants.CLEANER_DELAY_BUS_PROP, 2500); /* 2.5 seconds */ + final CachedOutputStreamCleaner cleaner = bus.getExtension(CachedOutputStreamCleaner.class); + cleaner.register(closeable); + + // Closes the bus, the cleaner should cancel the internal timer(s) + bus.shutdown(true); + // The Closeable::close should not be called since timer(s) is cancelled await().during(3, TimeUnit.SECONDS).untilAtomic(latch, is(false)); }
