0
votes

I have configured spring SFTP to pool the files into local from remote path, to process some jobs, then delete the local & remote file both.

below configuration works fine, except the local file delete, i didn't find any configuration to delete the local file, like 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" />

Here, an service activator invoked, when an file transferred from remote to local.

How can i configure to delete the local file when service activator completes the job?

EDIT: payload delete from remote and local both are resolved with below changes:

<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>
1

1 Answers

3
votes

Inbound adapters never take any action (on their own) after the message is sent to the flow; it doesn't know anything about the downstream flow topology - async handoffs etc. The remote deletion is done after the file is fetched and before the message is sent.

Since you're already using a pseudo transaction, and doing everything on the poller thread, you can do the delete with an after-commit-expression.

The other technique is to add a request-handler-advice to the final consumer (service activator in your case). That is demonstrated in the retry-and-more sample app.

EDIT:

In response to your comments below; no it's not possible to do 2 things with SpEL - however, you can use

<int:after-commit expression="payload" channel="postProcess"/>

and do whatever you want on the flow downstream of the postProcess channel.

However, it's not clear to me why you want to remove the file from the filter for both success and failure - you should just use an AcceptAllFileListFilter instead.

By the way, I don't see your acceptOnceFilter being used anywhere here - did you intend to configure it into the local-filter attribute?