GH-3271: Close session on error in stream source
Fixes https://github.com/spring-projects/spring-integration/issues/3271 When exception happens at `.withPayload(session.readRaw(remotePath))` in the `AbstractRemoteFileStreamingMessageSource` we don't close session. The resource leaking happens in the caching session factory * Add `session.close();` into the `catch (IOException e) {` in the `AbstractRemoteFileStreamingMessageSource.doReceive()` to clean up resources properly **Cherry-pick to 5.2.x, 5.1.x & 4.3.x**
This commit is contained in:
committed by
Gary Russell
parent
f047f0528b
commit
d71fb2e5da
@@ -216,6 +216,7 @@ public abstract class AbstractRemoteFileStreamingMessageSource<F>
|
||||
this.fileInfoJson ? file.toJson() : file);
|
||||
}
|
||||
catch (IOException e) {
|
||||
session.close();
|
||||
throw new UncheckedIOException("IOException when retrieving " + remotePath, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,22 +17,26 @@
|
||||
package org.springframework.integration.file.remote;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.integration.file.filters.FileListFilter;
|
||||
import org.springframework.integration.file.remote.session.CachingSessionFactory;
|
||||
import org.springframework.integration.file.remote.session.Session;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
|
||||
/**
|
||||
* @author Lukas Gemela
|
||||
@@ -69,6 +73,32 @@ public class RemoteFileStreamingMessageSourceTests {
|
||||
assertThat(testRemoteFileStreamingMessageSource.doReceive()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void sessionReturnedToCacheProperlyOnDoReceive() throws IOException {
|
||||
Session<String> session = mock(Session.class);
|
||||
when(session.readRaw(anyString())).thenThrow(IOException.class);
|
||||
when(session.list("remoteDirectory")).thenReturn(new String[] { "file1" });
|
||||
|
||||
SessionFactory<String> sessionFactory = mock(SessionFactory.class);
|
||||
when(sessionFactory.getSession()).thenReturn(session);
|
||||
|
||||
CachingSessionFactory<String> cachingSessionFactory = new CachingSessionFactory<>(sessionFactory, 1);
|
||||
RemoteFileTemplate<String> remoteFileTemplate = new RemoteFileTemplate<>(cachingSessionFactory);
|
||||
|
||||
TestRemoteFileStreamingMessageSource testRemoteFileStreamingMessageSource =
|
||||
new TestRemoteFileStreamingMessageSource(remoteFileTemplate, null);
|
||||
|
||||
testRemoteFileStreamingMessageSource.setRemoteDirectory("remoteDirectory");
|
||||
testRemoteFileStreamingMessageSource.setBeanFactory(mock(BeanFactory.class));
|
||||
testRemoteFileStreamingMessageSource.start();
|
||||
|
||||
assertThatExceptionOfType(UncheckedIOException.class)
|
||||
.isThrownBy(testRemoteFileStreamingMessageSource::doReceive);
|
||||
|
||||
assertThat(cachingSessionFactory.getSession()).isNotNull();
|
||||
}
|
||||
|
||||
static class TestRemoteFileStreamingMessageSource extends AbstractRemoteFileStreamingMessageSource<String> {
|
||||
|
||||
TestRemoteFileStreamingMessageSource(RemoteFileTemplate<String> template, Comparator<String> comparator) {
|
||||
|
||||
Reference in New Issue
Block a user