Как скопировать файл с ftp-сервера в локальный каталог, используя sftp и весеннюю загрузку, Java - PullRequest
0 голосов
/ 17 октября 2019

У меня есть коды для адаптера входящего и исходящего канала через SFTP. Я хочу вызвать этот метод через планировщик весенней загрузки, не используя опрос. Посмотрим, например, как вызвать метод resultFileHandler ()

public class SftpConfig {
    @Value("${nodephone.directory.sftp.host}")
    private String sftpHost;
    @Value("${nodephone.directory.sftp.port}")
    private int sftpPort;
    @Value("${nodephone.directory.sftp.user}")
    private String sftpUser;
    @Value("${nodephone.directory.sftp.password}")
    private String sftpPasword;
    @Value("${nodephone.directory.sftp.remote.directory.download}")
    private String sftpRemoteDirectoryDownload;
    @Value("${nodephone.directory.sftp.remote.directory.upload}")
    private String sftpRemoteDirectoryUpload;
    @Value("${nodephone.directory.sftp.remote.directory.filter}")
    private String sftpRemoteDirectoryFilter;
    @Value("${nodephone.directory.sftp.remote.directory.localDirectory}")
    private String sftpLocalDirectory;

    // private FtpOrderRequestHandler handler;

    @Bean
    public SessionFactory<LsEntry> sftpSessionFactory() {
        DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
        factory.setHost(sftpHost);
        factory.setPort(sftpPort);
        factory.setUser(sftpUser);
        factory.setPassword(sftpPasword);
        factory.setAllowUnknownKeys(true);
        return new CachingSessionFactory<LsEntry>(factory);
    }

    @Bean
    public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
        SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
        fileSynchronizer.setDeleteRemoteFiles(true);
        fileSynchronizer.setRemoteDirectory(sftpRemoteDirectoryDownload);
        fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter(sftpRemoteDirectoryFilter));
        return fileSynchronizer;
    }

    @Bean
    @InboundChannelAdapter(channel = "fromSftpChannel", poller = @Poller(cron = "0/5 * * * * *"))
    public MessageSource<File> sftpMessageSource() {
        SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
                sftpInboundFileSynchronizer());
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new AcceptOnceFileListFilter<File>());
        source.setLocalDirectory(new File("/local"));
        return source;
    }

    @Bean
    @ServiceActivator(inputChannel = "fromSftpChannel")
    public MessageHandler resultFileHandler() {
        return new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {

                System.out.println("********************** " + message.getPayload());

            }
        };
    }

Я проверил аннотацию конфигурации, и она читает файл с сервера, но я хочу запустить его из Cron вместо опроса, как мне вызватьметод resultFileHandler ()

1 Ответ

0 голосов
/ 21 октября 2019

Я никогда не делал этого, используя Spring Integration в каком-либо производственном коде, хотя я делал что-то подобное ниже, чтобы загружать файлы с удаленных серверов с помощью sftp / ftp.

Я использую только SftpOutboundGateway ( могут быть более эффективные способы ) для вызова метода "mget" и извлечения полезной нагрузки (файла).

@Configuration
@ConfigurationProperties(prefix = "sftp")
@Setter
@Getter
@EnableIntegration
public class RemoteFileConfiguration {

  private String clients;
  private String hosts;
  private int ports;
  private String users;
  private String passwords;


  @Bean(name = "clientSessionFactory")
  public SessionFactory<LsEntry> clientSessionFactory() {
    DefaultSftpSessionFactory sf = new DefaultSftpSessionFactory();
    sf.setHost(hosts);
    sf.setPort(ports);
    sf.setUser(users);
    sf.setPassword(passwords);
    sf.setAllowUnknownKeys(true);
    return new CachingSessionFactory<>(sf);
  }

  @Bean
  @ServiceActivator(inputChannel = "sftpChannel")
  public MessageHandler clientMessageHandler() {

    SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(
        clientSessionFactory(), "mget", "payload");
    sftpOutboundGateway.setAutoCreateLocalDirectory(true);
    sftpOutboundGateway.setLocalDirectory(new File("/users/localPath/client/INPUT/"));
    sftpOutboundGateway.setFileExistsMode(FileExistsMode.REPLACE_IF_MODIFIED);
    sftpOutboundGateway.setFilter(new AcceptOnceFileListFilter<>());
    return sftpOutboundGateway;
  }

}
@MessagingGateway
public interface SFTPGateway {

  @Gateway(requestChannel = "sftpChannel")
  List<File> get(String dir);

}

Чтобы убедиться, что мы используем cron длявыполнить это, я использовал тасклет, который выполняется Spring Batch, когда мне нужно использовать выражение cron.

@Slf4j
@Getter
@Setter
public class RemoteFileInboundTasklet implements Tasklet {

  private RemoteFileTemplate remoteFileTemplate;
  private String remoteClientDir;
  private String clientName;

  private SFTPGateway sftpGateway;

  @Override
  public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext)
      throws Exception {

    List<File> files = sftpGateway.get(remoteClientDir);

    if (CollectionUtils.isEmpty(files)) {
      log.warn("No file was downloaded for client {}.", clientName);
      return RepeatStatus.FINISHED;
    }

    log.info("Total file: {}", files.size());
    return RepeatStatus.FINISHED;
  }

}

ПРИМЕЧАНИЕ: Если вы не хотитеиспользуйте Tasklet Batch, вы можете использовать класс @Component и ввести шлюз для вызова метода get.

@Autowired
private SFTPGateway sftpGateway;
...