1
votes

We are working on a Spring Batch project (spring boot 1.2.2.RELEASE) with a requirement to read files from a server location by polling at a certain frequency using Spring SFTP integration. We have implemented Spring Batch using java config and in the process of using Spring Integration java config. I am unable to find examples that depict the above scenario. I have gone through various links but I see mostly XML configuration examples.

http://spring.io/blog/2010/02/15/practical-use-of-spring-batch-and-spring-integration https://github.com/spring-projects/spring-integration-samples/tree/master/basic/sftp

Is it possible to poll for files using spring integration java config? Any help /guidance would be appreciated.

Edit 1:

SftpConfiguration class

@Configuration
public class SftpConfiguration {

    @Autowired
    SftpProperties sftpProperties;

    @Bean
    public SessionFactory<LsEntry> getSftpSessionFactory() {
        Resource resource = new FileSystemResource(
                sftpProperties.privateKeyLocation);
        DefaultSftpSessionFactory sftpSessionFactory = new DefaultSftpSessionFactory();
        sftpSessionFactory.setHost(sftpProperties.hostName);
        sftpSessionFactory.setPort(sftpProperties.port);
        sftpSessionFactory.setUser(sftpProperties.username);
        sftpSessionFactory.setPrivateKey(resource);
        return sftpSessionFactory;
    }

    @Bean
    @InboundChannelAdapter(value = "sftpChannel", poller = @Poller(fixedDelay = "1000", maxMessagesPerPoll = "1"))
    public MessageSource<File> sftp() {
        SftpInboundFileSynchronizingMessageSource source = null;
        SftpInboundFileSynchronizer sftpInboundFileSynchronizer = null;
        File localDirectory = new File(sftpProperties.localDirectory);

        try {
            sftpInboundFileSynchronizer = new SftpInboundFileSynchronizer(getSftpSessionFactory());
            sftpInboundFileSynchronizer.setFilter(new SftpSimplePatternFileListFilter(sftpProperties.fileNamePattern));
            sftpInboundFileSynchronizer.setRemoteDirectory(sftpProperties.remoteDirectory);
            sftpInboundFileSynchronizer.setPreserveTimestamp(Boolean.TRUE);
            sftpInboundFileSynchronizer.synchronizeToLocalDirectory(localDirectory);
            sftpInboundFileSynchronizer.setDeleteRemoteFiles(Boolean.FALSE);
            sftpInboundFileSynchronizer.setTemporaryFileSuffix(".copy");
            source = new SftpInboundFileSynchronizingMessageSource(sftpInboundFileSynchronizer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return source;
    }
}

Main class

@SpringBootApplication
@EnableIntegration
@IntegrationComponentScan
public class SpringIntegrationApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringIntegrationApplication.class, args);
    }
}

The project is a spring boot starter project.

  • pom.xml

    org.springframework.boot spring-boot-starter-parent 1.2.3.RELEASE
    UTF-8 com.spring.integration.test.SpringIntegrationApplication 1.7 org.springframework.boot spring-boot-starter-integration org.springframework.integration spring-integration-sftp org.springframework.boot spring-boot-starter-web

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.integration</groupId>
        <artifactId>spring-integration-sftp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-batch</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-collections</groupId>
        <artifactId>commons-collections</artifactId>
        </dependency>
    
    <dependency>
        <groupId>org.scala-lang</groupId>
        <artifactId>scala-library</artifactId>
        <version>2.10.4</version>
    </dependency>
    <dependency>
        <groupId>org.neo4j</groupId>
        <artifactId>neo4j-cypher-compiler-2.1</artifactId>
        <version>2.1.5</version>
    </dependency>
    

Stacktrace

Exception encountered during context initialization - cancelling refresh attempt org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sftpConfiguration' defined in file [/var/opt/vmware/vfabric-tc-server-standard/inst1/webapps/spring-integration-0.0.1-SNAPSHOT/WEB-INF/classes/com/spring/integration/test/config/SftpConfiguration.class]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: The 'interface org.springframework.integration.annotation.InboundChannelAdapter' on @Bean method level is allowed only for: org.springframework.integration.core.MessageSourcebeans Object of class [null] must be an instance of interface org.springframework.integration.core.MessageSource at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) [spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686) [spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) [spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:117) [spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:108) [spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:68) [spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5423) [catalina.jar:7.0.47.A] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.47.A] at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) [catalina.jar:7.0.47.A] at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) [catalina.jar:7.0.47.A] at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633) [catalina.jar:7.0.47.A] at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:983) [catalina.jar:7.0.47.A] at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1660) [catalina.jar:7.0.47.A] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_45] at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_45] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_45] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_45] at java.lang.Thread.run(Thread.java:744) [na:1.7.0_45] Caused by: java.lang.IllegalArgumentException: The 'interface org.springframework.integration.annotation.InboundChannelAdapter' on @Bean method level is allowed only for: org.springframework.integration.core.MessageSourcebeans Object of class [null] must be an instance of interface org.springframework.integration.core.MessageSource at org.springframework.util.Assert.isInstanceOf(Assert.java:339) ~[spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.integration.config.annotation.InboundChannelAdapterAnnotationPostProcessor.createMessageSource(InboundChannelAdapterAnnotationPostProcessor.java:77) ~[spring-integration-core-4.1.2.RELEASE.jar:na] at org.springframework.integration.config.annotation.InboundChannelAdapterAnnotationPostProcessor.postProcess(InboundChannelAdapterAnnotationPostProcessor.java:62) ~[spring-integration-core-4.1.2.RELEASE.jar:na] at org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor$1.doWith(MessagingAnnotationPostProcessor.java:151) ~[spring-integration-core-4.1.2.RELEASE.jar:na] at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:494) ~[spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:501) ~[spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor.postProcessAfterInitialization(MessagingAnnotationPostProcessor.java:131) ~[spring-integration-core-4.1.2.RELEASE.jar:na] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] ... 27 common frames omitted 20 Apr 2015;20:01:35 ERROR o.s.boot.SpringApplication - Application startup failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sftpConfiguration' defined in file [/var/opt/vmware/vfabric-tc-server-standard/inst1/webapps/spring-integration-0.0.1-SNAPSHOT/WEB-INF/classes/com/spring/integration/test/config/SftpConfiguration.class]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: The 'interface org.springframework.integration.annotation.InboundChannelAdapter' on @Bean method level is allowed only for: org.springframework.integration.core.MessageSourcebeans Object of class [null] must be an instance of interface org.springframework.integration.core.MessageSource at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) ~[spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:117) [spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:108) [spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:68) [spring-boot-1.2.3.RELEASE.jar:1.2.3.RELEASE] at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5423) [catalina.jar:7.0.47.A] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.47.A] at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) [catalina.jar:7.0.47.A] at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) [catalina.jar:7.0.47.A] at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633) [catalina.jar:7.0.47.A] at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:983) [catalina.jar:7.0.47.A] at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1660) [catalina.jar:7.0.47.A] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_45] at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_45] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_45] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_45] at java.lang.Thread.run(Thread.java:744) [na:1.7.0_45] Caused by: java.lang.IllegalArgumentException: The 'interface org.springframework.integration.annotation.InboundChannelAdapter' on @Bean method level is allowed only for: org.springframework.integration.core.MessageSourcebeans Object of class [null] must be an instance of interface org.springframework.integration.core.MessageSource at org.springframework.util.Assert.isInstanceOf(Assert.java:339) ~[spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.integration.config.annotation.InboundChannelAdapterAnnotationPostProcessor.createMessageSource(InboundChannelAdapterAnnotationPostProcessor.java:77) ~[spring-integration-core-4.1.2.RELEASE.jar:na] at org.springframework.integration.config.annotation.InboundChannelAdapterAnnotationPostProcessor.postProcess(InboundChannelAdapterAnnotationPostProcessor.java:62) ~[spring-integration-core-4.1.2.RELEASE.jar:na] at org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor$1.doWith(MessagingAnnotationPostProcessor.java:151) ~[spring-integration-core-4.1.2.RELEASE.jar:na] at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:494) ~[spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:501) ~[spring-core-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor.postProcessAfterInitialization(MessagingAnnotationPostProcessor.java:131) ~[spring-integration-core-4.1.2.RELEASE.jar:na] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE] ... 27 common frames omitted

1
Let us know if you solved this problemHinotori

1 Answers

0
votes

See Appendix F of the reference manual.

@Bean
@InboundChannelAdapter( ... , poller = @Poller(...))
public MessageSource sftp() {
    SftpInboundFileSynchronizingMessageSource source = new ...;
    ...
    return source;
}

The source needs a SftpInboundFileSynchronizer bean, which needs a SessionFactory (usually a DefaultSftpSessionFactory).