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

reta pushed a commit to branch 3.5.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit d86bdbf9151b8aa19a633dbf7b2aa2519bdb7206
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)
    (cherry picked from commit db4d23057d58ca9bf25eff1d95aa556d0f1b582d)
---
 .../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));
     }

Reply via email to