GH-3043: Add FileHeaders.REMOTE_HOST header (#3044)
* GH-3043: Add FileHeaders.REMOTE_HOST header Fixes https://github.com/spring-projects/spring-integration/issues/3043 * Populate a `FileHeaders.REMOTE_HOST` from the `AbstractRemoteFileStreamingMessageSource` and "get"-based commands in the `AbstractRemoteFileOutboundGateway` * Extract the value from the a `Session.getHost()` contract * The `AbstractInboundFileSynchronizingMessageSource` cannot be addressed with this because the real message is already based on the locally stored file * Adjust some affected tests according our code style requirements * * Add remote file info support into `AbstractInboundFileSynchronizingMessageSource` * Introduce a `MetadataStore` functionality into the `AbstractInboundFileSynchronizer` to gather a remote file info an save it in the URI style against local file * Retrieve such an info in the `AbstractInboundFileSynchronizingMessageSource` during local file polling * Introduce `protocol()` contract for the `AbstractInboundFileSynchronizer` to build a proper URI in the metadata for external readers to distinguish remote files properly * Document the feature * * Fix some typos in Docs * * Rename property and header constant to the `HOST_PORT` pair * Fix typos in Docs * Add `remote-file-metadata-store` and `metadata-store-prefix` into XSD of (S)FTP Inbound Channel Adapters * Add `remoteFileMetadataStore` and `metadataStorePrefix` options into `RemoteFileInboundChannelAdapterSpec` for Java DSL
This commit is contained in:
committed by
Gary Russell
parent
ff15d5265d
commit
a756e6334d
@@ -32,6 +32,7 @@ import org.springframework.integration.metadata.SimpleMetadataStore;
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class FtpInboundFileSynchronizer extends AbstractInboundFileSynchronizer<FTPFile> {
|
||||
@@ -62,4 +63,9 @@ public class FtpInboundFileSynchronizer extends AbstractInboundFileSynchronizer<
|
||||
return file.getTimestamp().getTimeInMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String protocol() {
|
||||
return "ftp";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,13 +38,14 @@ import org.springframework.util.ObjectUtils;
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class FtpSession implements Session<FTPFile> {
|
||||
|
||||
private static final String SERVER_REPLIED_WITH = "'. Server replied with: ";
|
||||
private static final Log LOGGER = LogFactory.getLog(FtpSession.class);
|
||||
|
||||
private final Log logger = LogFactory.getLog(this.getClass());
|
||||
private static final String SERVER_REPLIED_WITH = "'. Server replied with: ";
|
||||
|
||||
private final FTPClient client;
|
||||
|
||||
@@ -86,7 +87,9 @@ public class FtpSession implements Session<FTPFile> {
|
||||
throw new IOException("Failed to copy '" + path +
|
||||
SERVER_REPLIED_WITH + this.client.getReplyString());
|
||||
}
|
||||
this.logger.info("File has been successfully transferred from: " + path);
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("File has been successfully transferred from: " + path);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,8 +112,8 @@ public class FtpSession implements Session<FTPFile> {
|
||||
}
|
||||
if (this.client.completePendingCommand()) {
|
||||
int replyCode = this.client.getReplyCode();
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug(this + " finalizeRaw - reply code: " + replyCode);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(this + " finalizeRaw - reply code: " + replyCode);
|
||||
}
|
||||
return FTPReply.isPositiveCompletion(replyCode);
|
||||
}
|
||||
@@ -126,8 +129,8 @@ public class FtpSession implements Session<FTPFile> {
|
||||
throw new IOException("Failed to write to '" + path
|
||||
+ SERVER_REPLIED_WITH + this.client.getReplyString());
|
||||
}
|
||||
if (this.logger.isInfoEnabled()) {
|
||||
this.logger.info("File has been successfully transferred to: " + path);
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("File has been successfully transferred to: " + path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,8 +143,8 @@ public class FtpSession implements Session<FTPFile> {
|
||||
throw new IOException("Failed to append to '" + path
|
||||
+ SERVER_REPLIED_WITH + this.client.getReplyString());
|
||||
}
|
||||
if (this.logger.isInfoEnabled()) {
|
||||
this.logger.info("File has been successfully appended to: " + path);
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("File has been successfully appended to: " + path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,17 +153,15 @@ public class FtpSession implements Session<FTPFile> {
|
||||
try {
|
||||
if (this.readingRaw.get()) {
|
||||
if (!finalizeRaw()) {
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("Finalize on readRaw() returned false for " + this);
|
||||
if (LOGGER.isWarnEnabled()) {
|
||||
LOGGER.warn("Finalize on readRaw() returned false for " + this);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.client.disconnect();
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
this.logger.warn("failed to disconnect FTPClient", e);
|
||||
}
|
||||
LOGGER.warn("failed to disconnect FTPClient", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,8 +184,8 @@ public class FtpSession implements Session<FTPFile> {
|
||||
throw new IOException("Failed to rename '" + pathFrom +
|
||||
"' to " + pathTo + SERVER_REPLIED_WITH + this.client.getReplyString());
|
||||
}
|
||||
if (this.logger.isInfoEnabled()) {
|
||||
this.logger.info("File has been successfully renamed from: " + pathFrom + " to " + pathTo);
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("File has been successfully renamed from: " + pathFrom + " to " + pathTo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +229,10 @@ public class FtpSession implements Session<FTPFile> {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHostPort() {
|
||||
return this.client.getRemoteAddress().getHostName() + ':' + this.client.getRemotePort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test() {
|
||||
|
||||
@@ -177,6 +177,29 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="remote-file-metadata-store" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.metadata.MetadataStore" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Reference to a MetadataStore for saving remote files information between
|
||||
synchronization and polling.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="metadata-store-prefix" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify a prefix for metadata store to distinguish keys from another places
|
||||
where the same shared store is used.
|
||||
By default, the remote a component name is used.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attributeGroup ref="tempSuffixGroup" />
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
|
||||
Reference in New Issue
Block a user