简体   繁体   English

Spring 使用入站适配器消息处理程序中的出站网关的 Sftp 获取文件

[英]Spring Sftp fetch file using outbound gateway within inbound adapter message handler

I am using Inbound Adapter using Java DSL to poll pdf files from the SFTP server.我正在使用使用 Java DSL 的入站适配器从 SFTP 服务器轮询 pdf 文件。 I have a use case where after fetching the pdf file application will fetch the config file present in CSV format with the same name on the SFTP server.我有一个用例,在获取 pdf 文件后,应用程序将获取 SFTP 服务器上具有相同名称的 CSV 格式的配置文件。 After fetching the config file, the application will process the original pdf file using the properties defined in the config file and upload it back to SFTP server using the outbound adapter.获取配置文件后,应用程序将使用配置文件中定义的属性处理原始 pdf 文件,并使用出站适配器将其上传回 SFTP 服务器。

I am facing problems with fetching config files within the handler on the same thread using the outbound gateway.我在使用出站网关在同一线程上的处理程序中获取配置文件时遇到问题。

Here is my code:这是我的代码:

Register Integration Flows:注册集成流程:

  for (String client : clientsArr) {
      this.flowContext.registration(getInboundIntegrationFlow(client)).register();
  }

  this.flowContext.registration(getOutboundIntegrationFlow()).register();
  this.flowContext.registration(sftpGatewayGetIntegrationFlow()).register();

Inbound Adapter Integration Flow:入站适配器集成流程:


  @Autowired
  private SftpPdfMessageHandler messageHandler;

  private IntegrationFlow getInboundIntegrationFlow(String client) {

    String remoteDirectory = getRemoteDirectory(client);
    String localDirectory = getLocalDirectory(client);
    String inboundAdapterId = getInboundAdapterId(client);

    return IntegrationFlows
        .from(Sftp.inboundAdapter(sftpSessionFactory())
                .preserveTimestamp(true)
                .remoteDirectory(remoteDirectory)
                .autoCreateLocalDirectory(true)
                .localDirectory(new File(localDirectory))
                .maxFetchSize(Integer.parseInt(sftpProperties.getMaxFetchSize()))
                .filter(new SftpSimplePatternFileListFilter(sftpProperties.getRemoteFileFilter()))
                .deleteRemoteFiles(true),
            e -> e.id(inboundAdapterId)
                .autoStartup(true)
                .poller(Pollers
                    .fixedDelay(Long.parseLong(sftpProperties.getPollPeriodInSeconds()), TimeUnit.SECONDS)
                    .receiveTimeout(Long.parseLong(sftpProperties.getPollerTimeout()))
                    .maxMessagesPerPoll(Long.parseLong(sftpProperties.getMaxMessagesPerPoll()))
                ))
        .handle(inBoundHandler())
        .get();
  }

  public MessageHandler inBoundHandler() {
    return message -> {
      File file = (File) message.getPayload();
      messageHandler.handleMessage(file);
    };
  }

Outbound Adapter Integration Flow:出站适配器集成流程:

  private IntegrationFlow getOutboundIntegrationFlow() {

    return IntegrationFlows.from("sftpOutboundChannel")
        .handle(Sftp.outboundAdapter(sftpSessionFactory(), FileExistsMode.FAIL)
            .remoteDirectoryExpression(String.format("headers['%s']", FileHeaders.REMOTE_DIRECTORY))).get();
  }

  @Bean("sftpOutboundChannel")
  public MessageChannel sftpOutboundChannel() {
    return new DirectChannel();
  }

SFTP Message Handler: SFTP 消息处理程序:

  @Async("sftpHandlerAsyncExecutor")
  public void handleMessage(File originalFile) {

    File configFile = fetchConfigFile();

    /*
      process original file and store processed file in output file path on local directory
     */
      
    boolean success = uploadFileToSftpServer(outputFilePath, client, entity);

    if (success) {
      deleteFileFromLocal(originalFile);
    }
  }

Outbound Gateway GET Integration Flow:出站网关 GET 集成流程:

  private IntegrationFlow sftpGatewayGetIntegrationFlow() {
    return IntegrationFlows.from("sftpGetInputChannel")
        .handle(Sftp.outboundGateway(sftpSessionFactory(),
            AbstractRemoteFileOutboundGateway.Command.GET, "payload")
            .options(AbstractRemoteFileOutboundGateway.Option.DELETE,
                AbstractRemoteFileOutboundGateway.Option.PRESERVE_TIMESTAMP)
            .localDirectoryExpression(String.format("headers['%s']", Constants.HEADER_LOCAL_DIRECTORY_NAME))
            .autoCreateLocalDirectory(true))
        .channel("nullChannel")
        .get();
  }

  @Bean("sftpGetInputChannel")
  public MessageChannel sftpGetInputChannel() {
    return new DirectChannel();
  }

messageHandler.handleMessage() method is called in async (with ThreadPoolTaskExecutor) which internally fetch config file using the outbound gateway. messageHandler.handleMessage()方法在异步中调用(使用 ThreadPoolTaskExecutor),该方法使用出站网关在内部获取配置文件。 But I couldn't find a single channel where I can send and receive a message payload in the same thread.但是我找不到可以在同一个线程中发送和接收消息有效负载的单个通道。 I found MessagingTemplate in spring docs but couldn't find a way to connect this with my outbound gateway integration flow.我在 spring 文档中找到了MessagingTemplate ,但找不到将其与我的出站网关集成流连接的方法。

sftpGetMessageTemplate.sendAndReceive(sftpGetInputChannel, new GenericMessage<>("/dir/file.csv", headers)) gives " Dispatcher has no subscribers for channel " exception with DirectChannel(). sftpGetMessageTemplate.sendAndReceive(sftpGetInputChannel, new GenericMessage<>("/dir/file.csv", headers))通过 DirectChannel() 给出“ Dispatcher has no subscribers for channel ”异常。

I am looking for a solution where I can fetch required file from the server with any of the following ways:我正在寻找一种解决方案,我可以通过以下任何方式从服务器获取所需的文件:

  • Integrate MessagingTemplate with IntegrationFlow (if possible) using an appropriate channel.使用适当的通道将 MessagingTemplate 与 IntegrationFlow 集成(如果可能)。
  • Some chaining of message handlers in the inbound adapter flow where after polling the original file it will fetch another file using sftp outbound gateway and then call final handler with both objects (original file and config file).入站适配器流中的一些消息处理程序链接,在轮询原始文件后,它将使用 sftp 出站网关获取另一个文件,然后使用两个对象(原始文件和配置文件)调用最终处理程序。 I am trying to achieve a similar thing using the custom code above.我正在尝试使用上面的自定义代码来实现类似的事情。
  • Any other way to use send and poller channels for GET command in a multi-threaded environment.在多线程环境中使用GET命令的发送和轮询通道的任何其他方式。

Application needs to decide the directory path on runtime while using the GET command.应用程序在使用 GET 命令时需要在运行时决定目录路径。

You probably need to learn what is a @MessagingGateway and how to make it to interact with channels on your outbound gateway.您可能需要了解什么是@MessagingGateway以及如何使其与出站网关上的通道进行交互。

See docs for more info: https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/messaging-endpoints.html#gateway有关更多信息,请参阅文档: https://docs.spring.io/spring-integration/docs/5.3.2.RELEASE/reference/html/messaging-endpoints.html#gateway

If you really would like to get a config file as a result, you should not do .channel("nullChannel") .如果你真的想得到一个配置文件,你不应该这样做.channel("nullChannel") With the gateway in hands there is going to be replyChannel header with a TemporaryReplyChannel instance populated by the gateway.有了网关, replyChannel header 就会有一个由网关填充的TemporaryReplyChannel实例。 Then in your code you just going to use that functional interface as an API to call.然后在您的代码中,您只需将该功能接口用作 API 来调用。

In fact that messaging gateway uses a mentioned MessagingTemplate.sendAndReceive() .事实上,消息传递网关使用提到的MessagingTemplate.sendAndReceive()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么SFTP入站/出站通道适配器有单独的通道声明,为什么没有简单文件入站/出站通道适配器的通道声明? - Why there is separate channel declaration for SFTP inbound/outbound channel adapter and why not for simple file inbound/outbound channel adapter? Spring SFTP入站适配器出现问题 - Problems with spring sftp inbound adapter 我可以从入站通道适配器处理程序中向Spring Integration Channel消息吗? - Can I Message Spring Integration Channel from within My Inbound Channel Adapter Handler? Spring SFTP入站chanel适配器删除本地文件 - Spring SFTP inbound chanel adapter delete local file Spring集成TCP入站/出站适配器与非Spring客户端 - Spring Integration TCP inbound/outbound adapter with non-Spring client 使用Spring Integration入站通道适配器时重新下载消息 - Re downloading of message when using spring integration inbound channel adapter 用于 Sftp 入站适配器的 LastModifiedFileListFilter - LastModifiedFileListFilter for Sftp inbound adapter 如何为 Spring Integration SFTP 入站适配器动态定义文件过滤器模式? - How to dynamically define file filter pattern for Spring Integration SFTP Inbound Adapter? 使用Spring Integration for Inbound Adapter时如何检查SFTP连接是否成功 - How to check whether the SFTP connection is successful or not when using Spring Integration for Inbound Adapter 将文件/文件从远程目录移动到另一个 Spring 集成 SFTP 出站网关 Java 配置/Java DSL - Moving file/files from remote directory to another Spring Integration SFTP Outbound Gateway Java Config/Java DSL
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM