1

I am trying to use ftp-inbound-adapter to poll files based on the the current date.And my inbound adapter uses a filter which refers to bean myfilter .The problem here is the current date is initailized at the startup and is not been processed dynamically..I would like to get the current date for every new message

    <int-ftp:inbound-channel-adapter id="ftpInbound"
                    channel="ftpChannel"
                    session-factory="ftpsClientFactory"
                    filter="myFilter"
    </int-ftp:inbound-channel-adapter>

    <bean id="myFilter" class="org.springframework.integration.ftp.filters.FtpRegexPatternFileListFilter" scope="prototype">
        <constructor-arg value="#{T(java.time.LocalDateTime).now().format(T(java.time.format.DateTimeFormatter).ofPattern('MMddyy'))}.(xls|xlsx)"/>
        <aop:scoped-proxy/>
        </bean>

UPDATE

I changed from this

    <bean id="currentDate" class="java.util.Date" factory-bean="fastDateFormat"
        scope="prototype" factory-method="format" >
        <aop:scoped-proxy/> 
        <constructor-arg>
            <bean class="java.util.Date" />
        </constructor-arg>
    </bean>


<bean id="myFilter" class="org.springframework.integration.ftp.filters.FtpRegexPatternFileListFilter" scope="prototype">
        <constructor-arg value="#{currentDate}.(xls|xlsx)"/>
        </bean>

And my inbound adapter uses a filter which refers to bean myFilter .. The problem here is the current date is initailized at the startup and is not been processed dynamically..I would like to get the current date for every new message

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118

2 Answers2

2

This impossible with your current configuration because that filter is just a singleton bean created only once at start up pulling that your currentDate for injection only once as well.

You may try to add <aop:scoped-proxy/> into your currentDate bean definition, though: https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#beans-factory-scopes-other-injection, but I would suggest to inject BeanFactorty into your filter and call getBean("currentDate", Date.class) every time you need a new instance of that prototype.

UPDATE

You inject BeanFactory into your filter instead of that currentDate bean. And then when filter logic is called you do Date currentDate = this.beanFactory.getBean("currentDate", Date.class);.

UPDATE2

Here is what I think should work for you:

public class DynamicRegexPatternFilter extends AbstractFileListFilter<File> {

    @Autowired
    private BeanFactory beanFactory;

    @Override
    public boolean accept(File file) {
        return Pattern.compile(this.beanFactory.getBean("currentDate", String.class) + ".(xls|xlsx)")
                .matcher(file.getName())
                .matches();
    }

}
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
0

You can make custom filter. Implement FileListFilter and override filterFiles method which takes input argument as array of LsEntry. LsEntry is nothing but a small metadata object of a File present at (S)FTP. It comprises of File Name and the date on which it was modified.

@Override
public List<LsEntry> filterFiles(LsEntry[] files) {
    List<LsEntry> result = new ArrayList<LsEntry>();
    Vector<LsEntry> list = new Vector<LsEntry>();
    Collections.addAll(list, files);
    ChannelSftp.LsEntry lastModifiedEntry = Collections.max(list,
            (Comparator.comparingInt(entry -> entry.getAttrs().getMTime())));
    result.add(lastModifiedEntry);
    return result;
}

Reference: https://stackoverflow.com/a/60635859/11325128

lavin249
  • 25
  • 6