0

I'm trying out FTP file upload and download example using spring integration. I want to manually upload a file to the outputChannel. I don't want invoke it when there is a change in inputChannel. So, the FTPApplication should just have a declaration for the outputChannel bean. Im refering this article Uploading files directly to specific folder in ftp server using spring spring for this purpose(Only for manually uploading and this way is common in most pages). Below is the Spring boot application code:

@SpringBootApplication
public class FtpApplication {

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

    @Bean
    public SessionFactory<FTPFile> ftpSessionFactory() {
        DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
        sf.setHost("localhost");
        sf.setPort(21);
        sf.setUsername("root");
        sf.setPassword("root");
        return new CachingSessionFactory<FTPFile>(sf);
    }

    @Bean
    public FtpInboundFileSynchronizer ftpInboundFileSynchronizer() {
        FtpInboundFileSynchronizer fileSynchronizer = new FtpInboundFileSynchronizer(ftpSessionFactory());
        fileSynchronizer.setDeleteRemoteFiles(false);
        fileSynchronizer.setRemoteDirectory("/");
        fileSynchronizer.setFilter(new FtpSimplePatternFileListFilter("*.xml"));
        return fileSynchronizer;
    }

    @Bean
    @InboundChannelAdapter(value="inputChannel", channel = "inputChannel")
    public MessageSource<File> ftpMessageSource() {
        FtpInboundFileSynchronizingMessageSource source = new FtpInboundFileSynchronizingMessageSource(
                ftpInboundFileSynchronizer());
        source.setLocalDirectory(new File("ftp-inbound"));
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new AcceptOnceFileListFilter<File>());
        return source;
    }

    @Bean
    @ServiceActivator(inputChannel = "inputChannel")
    public MessageHandler handler() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                System.out.println(message.getPayload());
            }
        };
    }

    @Bean(name = PollerMetadata.DEFAULT_POLLER)
    public PollerMetadata defaultPoller() {
        PollerMetadata pollerMetadata = new PollerMetadata();
        pollerMetadata.setTrigger(new PeriodicTrigger(10));
        return pollerMetadata;
    }

    @Bean
    @InboundChannelAdapter(value="outputChannel", channel = "outputChannel")
    public MessageSource<File> ftpMessageSource1() {
        FtpInboundFileSynchronizingMessageSource source = new FtpInboundFileSynchronizingMessageSource(
                ftpInboundFileSynchronizer());
        source.setLocalDirectory(new File("ftp-outbound"));
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new AcceptOnceFileListFilter<File>());
        return source;
    }

}

The controller code is as shown below:

@RestController
public class FTPController {

    @Autowired
    MessageChannel outputChannel;

    @RequestMapping(value = "/ftpuploadtest", method = RequestMethod.GET)
    public void getM36Messages() {
        File file = new File("ftp.txt");
        Message<File> fileMessage = MessageBuilder.withPayload(file).build();
        outputChannel.send(fileMessage);
    }
}

When I run the application I get the following error:

Description:
Field outputChannel in com.ftp.FTPController required a single bean, but 3 were found:
    - nullChannel: defined in null
    - errorChannel: defined in null
    - inputChannel: a programmatically registered singleton

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

Please help to resolve this.

Community
  • 1
  • 1
User1230321
  • 1,435
  • 4
  • 23
  • 39

2 Answers2

0

First of all I think you made some mistake around outputChannel component.

If that is about upload, so you have to use @ServiceActivator and FtpMessageHandler.

On the other hand for such a problem you have to declare @Bean for the outputChannel and together with the @Autowired, in the FTPController, you should add @Qualifier("outputChannel").

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • You also shouldn't use the same synchronizer in two inbound channel adapters. – Gary Russell Sep 27 '16 at 21:41
  • @Artem: If I use ServiceActivator annotation, I need to mention an inputChannel. Here I want to manually upload the file to an output channel. It shouldn't be called when there is a change in input channel. What am I supposed to do? That is the reason why I didn't go to SeviceActivator annotation. Pardon me, if I'm sounding you very stupid. – User1230321 Sep 28 '16 at 02:33
  • Please, explain the task then. It is fully unclear why you treat message channel as something for upload. – Artem Bilan Sep 28 '16 at 02:38
  • @ArtemBilan: Sorry Sir. Updated the question. – User1230321 Sep 28 '16 at 02:59
  • One more time `FtpInboundFileSynchronizingMessageSource` is for downloading files from FTP. You have to use `FtpMessageHandler` for uploading. Yes , for this purpose you can send message with file payload and `@ServiceActivator` will do the stuff for you. Please, read more about FTP support in the Reference Manual – Artem Bilan Sep 28 '16 at 03:04
  • If we are talking about that sample you refer, indeed `@ServiceActivator` is used in Java Config instead of`` – Artem Bilan Sep 28 '16 at 03:11
  • @ArtemBilan: Yes, the xml version I've got working for send. I don't want to rewrite the reading portion in xml. So, I'm trying to write the send/write portion in java config. As I see, there is less hep available for java config. – User1230321 Sep 28 '16 at 05:13
  • Here http://docs.spring.io/spring-integration/docs/4.3.2.RELEASE/reference/html/ftp.html#ftp-outbound. As you see help is there... – Artem Bilan Sep 28 '16 at 11:37
0

use @Qualifier , with @Autowired . and keep the variable name same as bean name.

Praveen Jain
  • 77
  • 3
  • 13