INT-4147: Fix NPE in the FileReadingMessageSource
JIRA: https://jira.spring.io/browse/INT-4147 By default `FileReadingMessageSource` is created without `filter`, at the same time internal `WatchServiceDirectoryScanner` is supplied with default `filter` by its `DefaultDirectoryScanner` super class. A `DELETE` watch event condition around `FileReadingMessageSource.this.filter` is wrong, because it is `null` by default. Therefore `DELETE` events never succeed * Modify `FileInboundTransactionTests` to accept `DELETE` watch event as well and verify that `ResettableFileListFilter.remove(File)` is performed * Call newly created getter for `DefaultDirectoryScanner.filter` in the `WatchServiceDirectoryScanner` to assert against supplied `filter` Polishing **Cherry-pick to 4.3.x**
This commit is contained in:
committed by
Gary Russell
parent
ee848e9ecf
commit
8c95f001da
@@ -62,11 +62,19 @@ public class DefaultDirectoryScanner implements DirectoryScanner {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
protected FileListFilter<File> getFilter() {
|
||||
return this.filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setLocker(FileLocker locker) {
|
||||
this.locker = locker;
|
||||
}
|
||||
|
||||
protected FileLocker getLocker() {
|
||||
return this.locker;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class takes the minimal implementation and merely delegates to the locker if set.
|
||||
* @param file the file to try to claim.
|
||||
|
||||
@@ -490,8 +490,8 @@ public class FileReadingMessageSource extends IntegrationObjectSupport implement
|
||||
}
|
||||
|
||||
if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
|
||||
if (FileReadingMessageSource.this.filter instanceof ResettableFileListFilter) {
|
||||
((ResettableFileListFilter<File>) FileReadingMessageSource.this.filter).remove(file);
|
||||
if (getFilter() != null && getFilter() instanceof ResettableFileListFilter) {
|
||||
((ResettableFileListFilter<File>) getFilter()).remove(file);
|
||||
}
|
||||
boolean fileRemoved = files.remove(file);
|
||||
if (fileRemoved && logger.isDebugEnabled()) {
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
<int-file:inbound-channel-adapter id="pseudoTx"
|
||||
channel="input" auto-startup="false"
|
||||
directory="#{T (org.springframework.integration.file.FileInboundTransactionTests).tmpDir.root}/si-test1"
|
||||
use-watch-service="true">
|
||||
use-watch-service="true"
|
||||
watch-events="CREATE,DELETE">
|
||||
<int:poller fixed-rate="500">
|
||||
<int:transactional synchronization-factory="syncFactoryA"/>
|
||||
</int:poller>
|
||||
|
||||
@@ -22,6 +22,8 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
@@ -32,8 +34,10 @@ import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
|
||||
import org.springframework.integration.file.filters.ResettableFileListFilter;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
@@ -84,6 +88,16 @@ public class FileInboundTransactionTests {
|
||||
|
||||
@Test
|
||||
public void testNoTx() throws Exception {
|
||||
|
||||
Object scanner = TestUtils.getPropertyValue(pseudoTx.getMessageSource(), "scanner");
|
||||
assertThat(scanner.getClass().getName(), containsString("FileReadingMessageSource$WatchServiceDirectoryScanner"));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ResettableFileListFilter<File> fileListFilter =
|
||||
spy(TestUtils.getPropertyValue(scanner, "filter", ResettableFileListFilter.class));
|
||||
|
||||
new DirectFieldAccessor(scanner).setPropertyValue("filter", fileListFilter);
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final AtomicBoolean crash = new AtomicBoolean();
|
||||
input.subscribe(message -> {
|
||||
@@ -110,8 +124,7 @@ public class FileInboundTransactionTests {
|
||||
assertFalse(transactionManager.getCommitted());
|
||||
assertFalse(transactionManager.getRolledBack());
|
||||
|
||||
Object scanner = TestUtils.getPropertyValue(pseudoTx.getMessageSource(), "scanner");
|
||||
assertThat(scanner.getClass().getName(), containsString("FileReadingMessageSource$WatchServiceDirectoryScanner"));
|
||||
verify(fileListFilter).remove(new File(tmpDir.getRoot(), "si-test1/foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user