javaspringspring-integrationspring-dsl

Transformer, changing filename after ingestion in Spring Integration


I am completely new to Spring Integration package and found different advice on how to approach the problem. So far I only found one that worked, but I am unsure if it is correct or why it produces a logged Error (even though the file is ingested and re-named as I intended).

The use case for this is that my system expects a "temp_" prefix to ignore a partially downloaded file. I found that even though the default ".writing" can be changed, it only works as a suffix.

Here is the config I used:

SftpInboundChannelAdapterSpec integrationFlow = Sftp.inboundAdapter(sftpSessionFactory)
        .filter(chainFilter)
        .localFilename(temp_::concat)
        .remoteDirectory(remoteDirectory)
        .deleteRemoteFiles(false)
        .preserveTimestamp(true)
        .localDirectory(new File(localDirectory));
return IntegrationFlows
        .from(integrationFlow, pc -> pc.poller(pm -> pm.cron(cron).maxMessagesPerPoll(1).errorHandler(new SftpUtils.SftpErrorHandler())))
        .transform((File f) -> f.getName().contains(temp_) ?
                f.renameTo(new File(f.getParent(), f.getName().replace(temp_, ""))) :
                null)
        .handle((transformResult, messageHeaders) -> {
            log.info("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ({}): {}", localDirectory, transformResult);
            return null;
        })
        .get();

And the error being produced:

SftpErrorHandler: Error occured in SFTP ingestion flow, exception: nested exception is org.springframework.integration.handler.ReplyRequiredException: No reply produced by handler 'leapInboundFlow.org.springframework.integration.config.ConsumerEndpointFactoryBean#0', and its 'requiresReply' property is set to true., failedMessage=GenericMessage [payload=src\main\resources\input\genericfile.name, headers={file_originalFile=src\main\resources\input\genericfile.name, id=293a3e85-cd62-37f7-b701-bbacbf27a83f, file_name=genericfile.name, file_relativePath=genericfile.name, timestamp=1668518160014}]

Solution

  • Your problem is here:

        .transform((File f) -> f.getName().contains(temp_) ?
                f.renameTo(new File(f.getParent(), f.getName().replace(temp_, ""))) :
                null)
    

    The transformer is a request-reply endpoint which does not tolerate null as a reply.

    Your logic over here is not fully clear. Let's forget that you cannot return null! It's definitely wrong and has to be fixed this or other way.

    What exactly do you want to return from this transformer? Probably your wish is just to rename the file and go ahead downstream with that renamed file already?

    Probably you wanted something like this:

        .transform((File f) -> 
             { 
                if (f.getName().contains(temp_)) {
                    f.renameTo(new File(f.getParent(), f.getName().replace(temp_, "")));
                }
                return f;
              })
    

    ?

    Sorry, it is not clear what is a business task from a content of your quesiton, but I hope I explained why your error appears.