Removing already deprecated instances of *FileList*Filters in favor of their entries.* equivalents which are generics-friendly and can be reused across adapters. Also, added some documentaton to the AbstractInboundRemoteFileSystemSynchroniz*.java classes so that the lifecycle hooks are explained for subsequent file system adapter implementations
This commit is contained in:
@@ -11,7 +11,10 @@ import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
|
||||
/**
|
||||
* This handles a lot of the common ground in our approach for synchronizing a remote file system locally
|
||||
* Strategy class charged with knowing how to connect to a remote file system, scan it for new files and then downloading the file.
|
||||
* <p/>
|
||||
* The implementation should run through any configured {@link org.springframework.integration.file.entries.EntryListFilter}s
|
||||
* to ensure the entry is worth downloading.
|
||||
*
|
||||
* @author Josh Long
|
||||
*/
|
||||
@@ -20,7 +23,8 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
|
||||
* Should we <emphasis>delete</emphasis> the <b>source</b> file?
|
||||
* For an FTP server, for example, this would delete the original FTPFile instance
|
||||
* <p/>
|
||||
* At the moment I can simply see this triggering the setting
|
||||
* At the moment I can simply see this triggering an implementation specific {@link org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer.EntryAcknowledgmentStrategy}
|
||||
* implementation that knows how to delete an entry on the remote file system.
|
||||
*/
|
||||
protected boolean shouldDeleteSourceFile;
|
||||
|
||||
@@ -48,9 +52,9 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
|
||||
* Obviously thread safe - simply provides a NOOP impl so we don't have to keep dancing around NPE's
|
||||
*/
|
||||
private EntryAcknowledgmentStrategy<T> noOpEntryAcknowledgmentStrategy = new EntryAcknowledgmentStrategy<T>() {
|
||||
public void acknowledge(Object o, T msg) {
|
||||
}
|
||||
};
|
||||
public void acknowledge(Object o, T msg) {
|
||||
}
|
||||
};
|
||||
|
||||
public void setEntryAcknowledgmentStrategy(EntryAcknowledgmentStrategy<T> entryAcknowledgmentStrategy) {
|
||||
this.entryAcknowledgmentStrategy = entryAcknowledgmentStrategy;
|
||||
@@ -69,22 +73,27 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
|
||||
}
|
||||
|
||||
/**
|
||||
* @param usefulContextOrClientData
|
||||
* @param t leverages strategy implementations to enable different behavior. It's a hook to the entry ({@link T}) after it's been successfully downloaded.
|
||||
* Conceptually, you might delete the remote one or rename it or something
|
||||
* @throws Throwable
|
||||
* @param usefulContextOrClientData this is context information to be passed to the individual {@link org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer.EntryAcknowledgmentStrategy} implementation.
|
||||
* {@link org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer.EntryAcknowledgmentStrategy#acknowledge(Object, Object)} will be called
|
||||
* in line with the {@link org.springframework.integration.core.MessageSource#receive()} call so this could conceivably be a 'live' stateful
|
||||
* client (a connection?) that is inappropriate to cache as it has per-request state.
|
||||
* @param t leverages strategy implementations to enable different behavior. It's a hook to the entry ({@link T}) after it's been successfully downloaded.
|
||||
* Conceptually, you might delete the remote one or rename it or something
|
||||
* @throws Throwable escape hatch exception, let the adapter deal with it.
|
||||
*/
|
||||
protected void acknowledge(Object usefulContextOrClientData, T t)
|
||||
throws Throwable {
|
||||
throws Throwable {
|
||||
Assert.notNull(this.entryAcknowledgmentStrategy != null, "entryAcknowledgmentStrategy can't be null!");
|
||||
this.entryAcknowledgmentStrategy.acknowledge(usefulContextOrClientData, t);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the callback where we need the implementation to do some specific work
|
||||
*
|
||||
* @throws Exception thrown if anything goes wrong
|
||||
*/
|
||||
protected abstract void syncRemoteToLocalFileSystem()
|
||||
throws Exception ;
|
||||
throws Exception;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
@@ -114,9 +123,13 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy interface to expose a hook for dispatching, moving, or deleting the file once it's been delivered
|
||||
* Strategy interface to expose a hook for dispatching, moving, or deleting the file once it's been delivered.
|
||||
* This will typically be a NOOP for the implementation. Adapters should (for consistency) expose an attribute
|
||||
* dictating whether the adapter will delete the <emphasis>source</emphasis> entry on the remote file system.
|
||||
* This is the file-system version of an <code>ack-mode</code>. Future implementations should consider
|
||||
* exposing a custom attribute that plugs a custom {@link org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer.EntryAcknowledgmentStrategy}
|
||||
* into the pipeline and also some more advanced scenarios (i.e., 'move file to another folder on delete ', or 'rename on delete')
|
||||
*
|
||||
* @author Josh Long
|
||||
* @param <T> the entry type (file, sftp, ftp, ...)
|
||||
*/
|
||||
public static interface EntryAcknowledgmentStrategy<T> {
|
||||
@@ -141,7 +154,7 @@ public abstract class AbstractInboundRemoteFileSystemSychronizer<T> extends Abst
|
||||
try {
|
||||
syncRemoteToLocalFileSystem();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e) ;
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
package org.springframework.integration.file;
|
||||
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
import org.springframework.integration.endpoint.AbstractEndpoint;
|
||||
import org.springframework.integration.file.entries.*;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* Ultimately, this factors out a lot of the common logic between the FTP and SFTP adapters
|
||||
* Ultimately, this factors out a lot of the common logic between the FTP and SFTP adapters. Designed to be extendable to handle
|
||||
* adapters whose task it is to synchronize a remote file system with a local file system (NB: this does *NOT* handle pushing files TO the remote
|
||||
* file system that exist uniquely in the local file system. It only handles bringing down the remote file system - as you'd expect
|
||||
* an 'inbound' adapter would).
|
||||
* <p/>
|
||||
* The base class supports configuration of whether the remote file system and local file system's directories should
|
||||
* be created on start (what 'creating a directory' means to the specific adapter is of course implementaton specific).
|
||||
* <p/>
|
||||
* This class is to be used as a pair with an implementation of
|
||||
* {@link org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer<T>}. This synchronizer
|
||||
* must handle the work of actually connecting to the remote file system and delivering new {@link java.io.File}s.
|
||||
* The synchronizer is designed to be
|
||||
*
|
||||
* @author Josh Long
|
||||
*/
|
||||
@@ -32,7 +38,7 @@ public abstract class AbstractInboundRemoteFileSystemSynchronizingMessageSource<
|
||||
protected volatile boolean autoCreateDirectories = true;
|
||||
|
||||
/**
|
||||
* An implementation that will handle the chores of actually syncing up the remote FS
|
||||
* An implementation that will handle the chores of actually connecting to and syncing up the remote FS with the local one, in an inbound direction
|
||||
*/
|
||||
protected volatile T synchronizer;
|
||||
|
||||
@@ -80,13 +86,10 @@ public abstract class AbstractInboundRemoteFileSystemSynchronizingMessageSource<
|
||||
}
|
||||
|
||||
if (this.autoCreateDirectories) {
|
||||
|
||||
|
||||
|
||||
if((this.localDirectory != null) && !this.localDirectory.exists() && this.localDirectory.getFile().mkdirs())
|
||||
logger.debug( "the localDirectory " + this.localDirectory + " doesn't exist");
|
||||
if ((this.localDirectory != null) && !this.localDirectory.exists() && this.localDirectory.getFile().mkdirs())
|
||||
logger.debug("the localDirectory " + this.localDirectory + " doesn't exist");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles making sure the remote files get here in one piece
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user