Home > Software design >  How to filter file by filename and route to corresponding channel in Spring Integration?
How to filter file by filename and route to corresponding channel in Spring Integration?

Time:10-05

I have remote FTP server to which I have mounted FtpStreamingMessageSource Inbound Channel Adapter and now I need to filter files by filename using regex and route to corresponding channels to launch batch job. The official documentation has PayloadTypeRouter, HeaderValueRouter but they are not suitable for this task. I can play with filters, but then I have to write several Inbound Channel Adapters for each file with specific filter. Is this normal approach or is there a better solution?

For example: I have A.csv, B.csv, C.csv, D.csv files on FTP. After reading I need to route A.csv to chanell A, B.csv to channel B and so on.

Below is the current working solution, feel free to comment and correct

 @Override
protected Object doTransform(Message<?> message) {
    IntegrationMessageHeaderAccessor accessor = new IntegrationMessageHeaderAccessor(message);
    MessageBuilder messageBuilder  = MessageBuilder.fromMessage(message);
    String fileName = accessor.getHeader("file_remoteFile").toString();
    if(fileName.contains("file_name1")){
        messageBuilder.setHeader("channel", "channel1");
    } else if (fileName.contains("file_name2")){
        messageBuilder.setHeader("channel", "channel2");
    } else if(fileName.contains("file_name3")) {
        messageBuilder.setHeader("channel", "channel3");
    } else if (fileName.contains("file_name4")){
        messageBuilder.setHeader("channel", "channel4");
    }
    return messageBuilder.build();
}

And here is Routing

@Bean
@org.springframework.integration.annotation.Transformer(inputChannel = CHANNEL_STREAMED_DATA, outputChannel = CHANNEL_DATA)
public CustomTransformer customTransformer() {
    return new CustomTransformer();
}

@ServiceActivator(inputChannel = CHANNEL_DATA)
@Bean
public HeaderValueRouter router() {
    HeaderValueRouter router = new HeaderValueRouter("channel");
    router.setChannelMapping("channel1", "channelA");
    router.setChannelMapping("channel2", "channelB");
    return router;
}    

CodePudding user response:

Well, you have already that file_remoteFile with all the info you need for routing.

Use a @Router instead and plain POJO method:

@Router(inputChannel = CHANNEL_STREAMED_DATA)
String routeByRemoteFile(@Header(FileHeaders.REMOTE_FILE) String remoteFile) {
    ...
}

And return a respective channel name according your file name matching logic.

See more info in docs: https://docs.spring.io/spring-integration/docs/current/reference/html/message-routing.html#router-annotation

  • Related