Spring SFTP 入站通道适配器删除本地文件
Spring SFTP inbound chanel adapter delete local file
我已经配置 spring SFTP 将文件从远程路径集中到本地,以处理一些作业,然后同时删除本地和远程文件。
以下配置正常,除了本地文件删除,我没有找到任何删除本地文件的配置,比如delete-remote-files="true"
<bean id="sftpSessionFactory"
class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory"
p:host="${sftp.host}"
p:port="${sftp.port}"
p:user="${sftp.username}"
p:password="${sftp.password}"
p:allowUnknownKeys="${sftp.allowUnknownKeys}" />
<int:channel id="sftpChannel">
<int:queue />
</int:channel>
<int-sftp:inbound-channel-adapter
id="sftpInboundAdapter"
channel="sftpChannel"
session-factory="sftpSessionFactory"
remote-directory="${sftp.remotedir}"
local-directory="${sftp.localdir}"
auto-create-local-directory="true"
delete-remote-files="true"
filename-pattern="*.TXT">
</int-sftp:inbound-channel-adapter>
<int:poller default="true" fixed-rate="${quartz.pick.repeatInterval}" max-messages-per-poll="${sftp.msg.per.poll}">
<int:transactional synchronization-factory="syncFactory" />
</int:poller>
<int:transaction-synchronization-factory id="syncFactory">
<int:after-rollback expression="@acceptOnceFilter.remove(payload)"/>
</int:transaction-synchronization-factory>
<bean id="acceptOnceFilter" class="org.springframework.integration.file.filters.AcceptOnceFileListFilter"/>
<int:service-activator input-channel="sftpChannel" ref="msgHandler" method="handleMessage"/>
<bean id="transactionManager" class="org.springframework.integration.transaction.PseudoTransactionManager"/>
<bean id="fileNameGenerator" class="org.springframework.integration.file.DefaultFileNameGenerator" />
此处,当文件从远程传输到本地时,服务激活器被调用。
如何配置在服务激活器完成作业时删除本地文件?
编辑:从远程和本地删除有效载荷都通过以下更改解决:
<int:transaction-synchronization-factory id="syncFactory">
<int:after-commit expression="payload.delete()" channel="nullChannel"/>
<int:after-rollback expression="@acceptOnceFilter.remove(payload)"/>
</int:transaction-synchronization-factory>
在消息发送到流后,入站适配器永远不会(自行)采取任何行动;它对下游流拓扑一无所知——异步切换等。远程删除是在获取文件之后和发送消息之前完成的。
由于您已经在使用伪事务,并且在轮询线程上执行所有操作,因此您可以使用 after-commit-expression
.
进行删除
另一种技术是向最终消费者(您的情况下为服务激活器)添加 request-handler-advice
。这在 the retry-and-more
sample app.
中得到了证明
编辑:
回应您在下方的评论;不,不可能用 SpEL 做两件事——但是,你可以使用
<int:after-commit expression="payload" channel="postProcess"/>
然后在 postProcess
通道的下游做任何你想做的事。
但是,我不清楚为什么要从过滤器中删除成功和失败的文件 - 您应该改用 AcceptAllFileListFilter
。
顺便说一下,我没有看到你的 acceptOnceFilter
在这里被使用 - 你打算将它配置到 local-filter
属性中吗?
我已经配置 spring SFTP 将文件从远程路径集中到本地,以处理一些作业,然后同时删除本地和远程文件。
以下配置正常,除了本地文件删除,我没有找到任何删除本地文件的配置,比如delete-remote-files="true"
<bean id="sftpSessionFactory"
class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory"
p:host="${sftp.host}"
p:port="${sftp.port}"
p:user="${sftp.username}"
p:password="${sftp.password}"
p:allowUnknownKeys="${sftp.allowUnknownKeys}" />
<int:channel id="sftpChannel">
<int:queue />
</int:channel>
<int-sftp:inbound-channel-adapter
id="sftpInboundAdapter"
channel="sftpChannel"
session-factory="sftpSessionFactory"
remote-directory="${sftp.remotedir}"
local-directory="${sftp.localdir}"
auto-create-local-directory="true"
delete-remote-files="true"
filename-pattern="*.TXT">
</int-sftp:inbound-channel-adapter>
<int:poller default="true" fixed-rate="${quartz.pick.repeatInterval}" max-messages-per-poll="${sftp.msg.per.poll}">
<int:transactional synchronization-factory="syncFactory" />
</int:poller>
<int:transaction-synchronization-factory id="syncFactory">
<int:after-rollback expression="@acceptOnceFilter.remove(payload)"/>
</int:transaction-synchronization-factory>
<bean id="acceptOnceFilter" class="org.springframework.integration.file.filters.AcceptOnceFileListFilter"/>
<int:service-activator input-channel="sftpChannel" ref="msgHandler" method="handleMessage"/>
<bean id="transactionManager" class="org.springframework.integration.transaction.PseudoTransactionManager"/>
<bean id="fileNameGenerator" class="org.springframework.integration.file.DefaultFileNameGenerator" />
此处,当文件从远程传输到本地时,服务激活器被调用。
如何配置在服务激活器完成作业时删除本地文件?
编辑:从远程和本地删除有效载荷都通过以下更改解决:
<int:transaction-synchronization-factory id="syncFactory">
<int:after-commit expression="payload.delete()" channel="nullChannel"/>
<int:after-rollback expression="@acceptOnceFilter.remove(payload)"/>
</int:transaction-synchronization-factory>
在消息发送到流后,入站适配器永远不会(自行)采取任何行动;它对下游流拓扑一无所知——异步切换等。远程删除是在获取文件之后和发送消息之前完成的。
由于您已经在使用伪事务,并且在轮询线程上执行所有操作,因此您可以使用 after-commit-expression
.
另一种技术是向最终消费者(您的情况下为服务激活器)添加 request-handler-advice
。这在 the retry-and-more
sample app.
编辑:
回应您在下方的评论;不,不可能用 SpEL 做两件事——但是,你可以使用
<int:after-commit expression="payload" channel="postProcess"/>
然后在 postProcess
通道的下游做任何你想做的事。
但是,我不清楚为什么要从过滤器中删除成功和失败的文件 - 您应该改用 AcceptAllFileListFilter
。
顺便说一下,我没有看到你的 acceptOnceFilter
在这里被使用 - 你打算将它配置到 local-filter
属性中吗?