0
votes

I am trying to delete a single file from the remote SFTP bucket when a certain thing happens in my app (we save the file to blob storage). I have not been able to do this. All that I have been able to see how to do is to always delete a file via and outbound channel adapter after processing is done. I am using the Java configuration.

Here is my code:

@Bean
@ServiceActivator(inputChannel = "sftpDeleteChannel")
public MessageHandler deleteHandler(SftpInboundProperties properties) {
    SftpOutboundGateway SFTP = new SftpOutboundGateway(sftpSessionFactory(properties), "rm", "'" + properties.getRemoteDirectory() + "'");
    return SFTP;
}

@Gateway(requestChannel = "sftpDeleteChannel")
    Boolean delete(Message<File> file);

This is the service activator that facilitates the entering of the file:

@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handler(FileProcessingService fileProcessingService) {
    return message -> {
        fileProcessingService.processFile((Message<File> message);
    };
}

I am getting this error message:

Reply message received but the receiving thread has exited due to an exception while sending the request message: ErrorMessage [payload=org.springframework.messaging.MessageHandlingException: error occurred in message handler [bean 'deleteHandler'; defined in: 'class path resource [com/.../SftpInboundConfiguration.class]'; from source: 'org.springframework.core.type.classreading.SimpleMethodMetadata@6ff37443']; nested exception is org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is org.springframework.core.NestedIOException: Failed to remove file.; nested exception is 3: Permission denied, failedMessage=GenericMessage [payload=/REMOTE_FILE_PATH/COMPLETE_FILE_NAME, headers={file_remoteHostPort=127.0.0.1:2222, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@34d7c35d, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@34d7c35d, file_name=COMPLETE_FILE_NAME, file_remoteDirectory=//sftp_remote, file_originalFile=/REMOTE_FILE_PATH/COMPLETE_FILE_NAME, id=2252eee1-6086-c9d9-c421-403f8a0bfc28, file_relativePath=COMPLETE_FILE_NAME, file_remoteFile=COMPLETE_FILE_NAME, timestamp=1588177024991}], headers={id=0d2b19ca-0e7c-7ba8-58cf-f225c126048c, timestamp=1588177025001}] for original GenericMessage [payload=/REMOTE_FILE_PATH/COMPLETE_FILE_NAME, headers={file_remoteHostPort=127.0.0.1:2222, file_name=COMPLETE_FILE_NAME, file_remoteDirectory=//sftp_remote, file_originalFile=/REMOTE_FILE_PATH/COMPLETE_FILE_NAME, id=9f29dd04-362a-ae93-df97-b392572d8864, file_relativePath=COMPLETE_FILE_NAME, file_remoteFile=COMPLETE_FILE_NAME, timestamp=1588177023713}]

I'm not sure if I'm doing things incorrectly or if outbound gateways are not for specific, on-demand deletes, or both. Would love some help.

Thanks!

Edit:

I am able to delete files on the server using SftpInboundFileSynchronizer.setDeleteRemoteFiles(true), so as far as the sftp bucket is concerned, I can delete files. Do I need to change something in my InboundChannelAdapter? Here it is below:

@Bean
@InboundChannelAdapter(channel = "sftpChannel", poller = @Poller(fixedDelay = "${com.esrx.dhf.listener.sftp.inbound.poll-interval:5000}"))
    public MessageSource<File> sftpMessageSource(SftpInboundProperties properties, JdbcMetadataStore metadataStore) {
        SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
                sftpInboundFileSynchronizer(properties, metadataStore));
        source.setLocalDirectory(new File(System.getProperty("user.dir") + "/" + "sftp_local"));
        source.setAutoCreateLocalDirectory(true);
        source.setMaxFetchSize(1);
        source.setLocalFilter(new FileSystemPersistentAcceptOnceFileListFilter(metadataStore, SFTP_LOCAL_PERSISTENT_PREFIX));
        return source;
    }

EDIT: SOLVED

So the venerable Gary Russel's real answer was that I should specify the full path of the file in the SftpOutboundGateway. So now the working solution means the new OutboundGateway looks like this:

@Bean
@ServiceActivator(inputChannel = "sftpDeleteChannel")
public MessageHandler deleteHandler(SftpInboundProperties properties) {
    return new SftpOutboundGateway(
            sftpSessionFactory(properties),
            "rm", 
            "'" + properties.getRemoteDirectory() + "/'" + " + " + "headers['file_remoteFile']");
    }
1

1 Answers

0
votes

What you have is correct.

See the cause:

nested exception is 3: Permission denied,

You don't have permission to delete the file.