INT-4115: (S)FtpPersistentFileFilter by Default
JIRA: https://jira.spring.io/browse/INT-4115 Apply `(S)FtpPersistentAcceptOnceFileListFilter` for the `(S)FtpInboundFileSynchronizer` by default to avoid cases to sync the same remote files to the local directory again. Especially when `localFileName` strategy is applied and we end up with new local files, but with the same remote content Accept `(S)FtpPersistentAcceptOnceFileListFilter` for streaming adapters Make `doSetFilter()` as `protected final` Fix tests after rebase Fix "What's New" after rebase Compose `PersistentAcceptOnceFileListFilter` together with the regex or pattern filters Document such a behavior Address PR comments for formatting and typo
This commit is contained in:
committed by
Gary Russell
parent
d3fb8b8f9e
commit
10ce68d3e3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,8 +17,10 @@
|
||||
package org.springframework.integration.sftp.config;
|
||||
|
||||
import org.springframework.integration.file.config.AbstractRemoteFileInboundChannelAdapterParser;
|
||||
import org.springframework.integration.file.filters.AbstractPersistentAcceptOnceFileListFilter;
|
||||
import org.springframework.integration.file.filters.FileListFilter;
|
||||
import org.springframework.integration.file.remote.synchronizer.InboundFileSynchronizer;
|
||||
import org.springframework.integration.sftp.filters.SftpPersistentAcceptOnceFileListFilter;
|
||||
import org.springframework.integration.sftp.filters.SftpRegexPatternFileListFilter;
|
||||
import org.springframework.integration.sftp.filters.SftpSimplePatternFileListFilter;
|
||||
import org.springframework.integration.sftp.inbound.SftpInboundFileSynchronizer;
|
||||
@@ -29,6 +31,8 @@ import org.springframework.integration.sftp.inbound.SftpInboundFileSynchronizing
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SftpInboundChannelAdapterParser extends AbstractRemoteFileInboundChannelAdapterParser {
|
||||
@@ -53,4 +57,9 @@ public class SftpInboundChannelAdapterParser extends AbstractRemoteFileInboundCh
|
||||
return SftpRegexPatternFileListFilter.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends AbstractPersistentAcceptOnceFileListFilter<?>> getPersistentAcceptOnceFileListFilterClass() {
|
||||
return SftpPersistentAcceptOnceFileListFilter.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ package org.springframework.integration.sftp.config;
|
||||
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
import org.springframework.integration.file.config.AbstractRemoteFileStreamingInboundChannelAdapterParser;
|
||||
import org.springframework.integration.file.filters.AbstractPersistentAcceptOnceFileListFilter;
|
||||
import org.springframework.integration.file.filters.FileListFilter;
|
||||
import org.springframework.integration.file.remote.RemoteFileOperations;
|
||||
import org.springframework.integration.sftp.filters.SftpPersistentAcceptOnceFileListFilter;
|
||||
import org.springframework.integration.sftp.filters.SftpRegexPatternFileListFilter;
|
||||
import org.springframework.integration.sftp.filters.SftpSimplePatternFileListFilter;
|
||||
import org.springframework.integration.sftp.inbound.SftpStreamingMessageSource;
|
||||
@@ -27,6 +29,8 @@ import org.springframework.integration.sftp.session.SftpRemoteFileTemplate;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 4.3
|
||||
*
|
||||
*/
|
||||
@@ -52,4 +56,9 @@ public class SftpStreamingInboundChannelAdapterParser extends AbstractRemoteFile
|
||||
return SftpRegexPatternFileListFilter.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends AbstractPersistentAcceptOnceFileListFilter<?>> getPersistentAcceptOnceFileListFilterClass() {
|
||||
return SftpPersistentAcceptOnceFileListFilter.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,11 @@ import java.io.File;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.springframework.integration.file.dsl.RemoteFileInboundChannelAdapterSpec;
|
||||
import org.springframework.integration.file.filters.CompositeFileListFilter;
|
||||
import org.springframework.integration.file.filters.FileListFilter;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.integration.metadata.SimpleMetadataStore;
|
||||
import org.springframework.integration.sftp.filters.SftpPersistentAcceptOnceFileListFilter;
|
||||
import org.springframework.integration.sftp.filters.SftpRegexPatternFileListFilter;
|
||||
import org.springframework.integration.sftp.filters.SftpSimplePatternFileListFilter;
|
||||
import org.springframework.integration.sftp.inbound.SftpInboundFileSynchronizer;
|
||||
@@ -50,7 +54,7 @@ public class SftpInboundChannelAdapterSpec
|
||||
*/
|
||||
@Override
|
||||
public SftpInboundChannelAdapterSpec patternFilter(String pattern) {
|
||||
return filter(new SftpSimplePatternFileListFilter(pattern));
|
||||
return filter(composeFilters(new SftpSimplePatternFileListFilter(pattern)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +64,16 @@ public class SftpInboundChannelAdapterSpec
|
||||
*/
|
||||
@Override
|
||||
public SftpInboundChannelAdapterSpec regexFilter(String regex) {
|
||||
return filter(new SftpRegexPatternFileListFilter(regex));
|
||||
return filter(composeFilters(new SftpRegexPatternFileListFilter(regex)));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private CompositeFileListFilter<ChannelSftp.LsEntry> composeFilters(FileListFilter<ChannelSftp.LsEntry>
|
||||
fileListFilter) {
|
||||
CompositeFileListFilter<ChannelSftp.LsEntry> compositeFileListFilter = new CompositeFileListFilter<>();
|
||||
compositeFileListFilter.addFilters(fileListFilter,
|
||||
new SftpPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "sftpMessageSource"));
|
||||
return compositeFileListFilter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,8 +19,12 @@ package org.springframework.integration.sftp.dsl;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.springframework.integration.file.dsl.RemoteFileStreamingInboundChannelAdapterSpec;
|
||||
import org.springframework.integration.file.filters.CompositeFileListFilter;
|
||||
import org.springframework.integration.file.filters.FileListFilter;
|
||||
import org.springframework.integration.file.remote.AbstractFileInfo;
|
||||
import org.springframework.integration.file.remote.RemoteFileTemplate;
|
||||
import org.springframework.integration.metadata.SimpleMetadataStore;
|
||||
import org.springframework.integration.sftp.filters.SftpPersistentAcceptOnceFileListFilter;
|
||||
import org.springframework.integration.sftp.filters.SftpRegexPatternFileListFilter;
|
||||
import org.springframework.integration.sftp.filters.SftpSimplePatternFileListFilter;
|
||||
import org.springframework.integration.sftp.inbound.SftpStreamingMessageSource;
|
||||
@@ -34,7 +38,7 @@ import com.jcraft.jsch.ChannelSftp.LsEntry;
|
||||
*/
|
||||
public class SftpStreamingInboundChannelAdapterSpec
|
||||
extends RemoteFileStreamingInboundChannelAdapterSpec<LsEntry, SftpStreamingInboundChannelAdapterSpec,
|
||||
SftpStreamingMessageSource> {
|
||||
SftpStreamingMessageSource> {
|
||||
|
||||
SftpStreamingInboundChannelAdapterSpec(RemoteFileTemplate<LsEntry> remoteFileTemplate,
|
||||
Comparator<AbstractFileInfo<LsEntry>> comparator) {
|
||||
@@ -49,7 +53,8 @@ public class SftpStreamingInboundChannelAdapterSpec
|
||||
*/
|
||||
@Override
|
||||
public SftpStreamingInboundChannelAdapterSpec patternFilter(String pattern) {
|
||||
return filter(new SftpSimplePatternFileListFilter(pattern)); }
|
||||
return filter(composeFilters(new SftpSimplePatternFileListFilter(pattern)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a regular expression to match remote files (e.g. '[0-9].*.txt').
|
||||
@@ -59,7 +64,15 @@ public class SftpStreamingInboundChannelAdapterSpec
|
||||
*/
|
||||
@Override
|
||||
public SftpStreamingInboundChannelAdapterSpec regexFilter(String regex) {
|
||||
return filter(new SftpRegexPatternFileListFilter(regex));
|
||||
return filter(composeFilters(new SftpRegexPatternFileListFilter(regex)));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private CompositeFileListFilter<LsEntry> composeFilters(FileListFilter<LsEntry> fileListFilter) {
|
||||
CompositeFileListFilter<LsEntry> compositeFileListFilter = new CompositeFileListFilter<>();
|
||||
compositeFileListFilter.addFilters(fileListFilter,
|
||||
new SftpPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "sftpStreamingMessageSource"));
|
||||
return compositeFileListFilter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,8 @@ package org.springframework.integration.sftp.inbound;
|
||||
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer;
|
||||
import org.springframework.integration.metadata.SimpleMetadataStore;
|
||||
import org.springframework.integration.sftp.filters.SftpPersistentAcceptOnceFileListFilter;
|
||||
|
||||
import com.jcraft.jsch.ChannelSftp.LsEntry;
|
||||
|
||||
@@ -27,15 +29,21 @@ import com.jcraft.jsch.ChannelSftp.LsEntry;
|
||||
* @author Josh Long
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SftpInboundFileSynchronizer extends AbstractInboundFileSynchronizer<LsEntry> {
|
||||
|
||||
/**
|
||||
* Create a synchronizer with the {@code SessionFactory} used to acquire {@code Session} instances.
|
||||
* @param sessionFactory The session factory.
|
||||
*/
|
||||
public SftpInboundFileSynchronizer(SessionFactory<LsEntry> sessionFactory) {
|
||||
super(sessionFactory);
|
||||
doSetFilter(new SftpPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "sftpMessageSource"));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isFile(LsEntry file) {
|
||||
return (file != null && file.getAttrs() != null && !file.getAttrs().isDir() && !file.getAttrs().isLink());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,8 @@ import java.util.List;
|
||||
import org.springframework.integration.file.remote.AbstractFileInfo;
|
||||
import org.springframework.integration.file.remote.AbstractRemoteFileStreamingMessageSource;
|
||||
import org.springframework.integration.file.remote.RemoteFileTemplate;
|
||||
import org.springframework.integration.metadata.SimpleMetadataStore;
|
||||
import org.springframework.integration.sftp.filters.SftpPersistentAcceptOnceFileListFilter;
|
||||
import org.springframework.integration.sftp.session.SftpFileInfo;
|
||||
|
||||
import com.jcraft.jsch.ChannelSftp.LsEntry;
|
||||
@@ -32,6 +34,8 @@ import com.jcraft.jsch.ChannelSftp.LsEntry;
|
||||
* Message source for streaming SFTP remote file contents.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 4.3
|
||||
*
|
||||
*/
|
||||
@@ -42,7 +46,7 @@ public class SftpStreamingMessageSource extends AbstractRemoteFileStreamingMessa
|
||||
* @param template the template.
|
||||
*/
|
||||
public SftpStreamingMessageSource(RemoteFileTemplate<LsEntry> template) {
|
||||
super(template, null);
|
||||
this(template, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,6 +59,7 @@ public class SftpStreamingMessageSource extends AbstractRemoteFileStreamingMessa
|
||||
public SftpStreamingMessageSource(RemoteFileTemplate<LsEntry> template,
|
||||
Comparator<AbstractFileInfo<LsEntry>> comparator) {
|
||||
super(template, comparator);
|
||||
doSetFilter(new SftpPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "sftpStreamingMessageSource"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,14 +26,20 @@ import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
|
||||
import org.springframework.integration.file.filters.CompositeFileListFilter;
|
||||
import org.springframework.integration.file.filters.ExpressionFileListFilter;
|
||||
import org.springframework.integration.file.filters.FileListFilter;
|
||||
import org.springframework.integration.file.remote.session.CachingSessionFactory;
|
||||
import org.springframework.integration.sftp.filters.SftpPersistentAcceptOnceFileListFilter;
|
||||
import org.springframework.integration.sftp.filters.SftpSimplePatternFileListFilter;
|
||||
import org.springframework.integration.sftp.inbound.SftpStreamingMessageSource;
|
||||
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
|
||||
@@ -76,7 +82,16 @@ public class SftpStreamingInboundChannelAdapterParserTests {
|
||||
|
||||
assertNotNull(TestUtils.getPropertyValue(source, "comparator"));
|
||||
assertThat(TestUtils.getPropertyValue(source, "remoteFileSeparator", String.class), equalTo("X"));
|
||||
assertThat(TestUtils.getPropertyValue(source, "filter"), instanceOf(SftpSimplePatternFileListFilter.class));
|
||||
|
||||
FileListFilter<?> filter = TestUtils.getPropertyValue(source, "filter", FileListFilter.class);
|
||||
assertNotNull(filter);
|
||||
assertThat(filter, instanceOf(CompositeFileListFilter.class));
|
||||
Set<?> fileFilters = TestUtils.getPropertyValue(filter, "fileFilters", Set.class);
|
||||
|
||||
Iterator<?> filtersIterator = fileFilters.iterator();
|
||||
assertThat(filtersIterator.next(), instanceOf(SftpSimplePatternFileListFilter.class));
|
||||
assertThat(filtersIterator.next(), instanceOf(SftpPersistentAcceptOnceFileListFilter.class));
|
||||
|
||||
assertSame(this.csf, TestUtils.getPropertyValue(source, "remoteFileTemplate.sessionFactory"));
|
||||
assertEquals(31, TestUtils.getPropertyValue(source, "maxFetchSize"));
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
|
||||
import org.springframework.integration.file.FileHeaders;
|
||||
import org.springframework.integration.file.filters.AcceptAllFileListFilter;
|
||||
import org.springframework.integration.file.remote.FileInfo;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.integration.scheduling.PollerMetadata;
|
||||
@@ -129,6 +130,7 @@ public class SftpStreamingMessageSourceTests extends SftpTestSupport {
|
||||
public MessageSource<InputStream> sftpMessageSource() {
|
||||
SftpStreamingMessageSource messageSource = new SftpStreamingMessageSource(template(),
|
||||
Comparator.comparing(FileInfo::getFilename));
|
||||
messageSource.setFilter(new AcceptAllFileListFilter<>());
|
||||
messageSource.setRemoteDirectory("sftpSource/");
|
||||
return messageSource;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user