簡體   English   中英

Spring 生成消息后集成移動文件到kafka

[英]Spring integration move file after produce message to kafka

首先,您可以在https://github.com/keiseithunder/spring-sftp-xml-to-json/blob/main/src/main/java/com/demo/sftp/SftpApplication.java找到我的代碼

我有一個 spring 集成,它將文件從 SFTP 服務器讀取到 stream 並發送到 kafka,然后在成功生成消息后嘗試將遠程文件移動到同一遠程服務器中的其他目錄。 但是,文件根本沒有移動,也沒有拋出任何錯誤

我嘗試使用此代碼將文件從upload/test.xmlupload/file/test.xml中的文件是我用來復制到upload目錄的備份)移動到upload/processed/test.xml

  @Bean
  @ServiceActivator(inputChannel = "success")
  public MessageHandler handler() {
    return new SftpOutboundGateway(sftpSessionFactory(), "mv", "");
  }

我已經在headers中設置file_renameTo=upload/processed/test.xml 不確定,我做錯了什么。 或者有一種方法可以使用advice.setOnSuccessExpressionString("@template.copy(headers['file_remoteDirectory']+'/'+headers['file_remoteFile'])"); 移動文件?

我的留言是

"GenericMessage [payload=Note(to=Toves, from=Jani, heading=Reminder, body=Don't forget me this weekend!!!!!), headers={file_remoteHostPort=localhost:2222, file_remoteFileInfo={"directory":false,"filename":"test.xml","link":false,"modified":1674550080000,"permissions":"rw-r--r--","remoteDirectory":"upload","size":122}, kafka_messageKey=test.xml, file_remoteDirectory=upload, kafka_recordMetadata=test-0@298, file_renameTo=upload/processed/test.xml, id=708d04c4-5abc-9f45-e83b-1fea7ffa5e8d, closeableResource=org.springframework.integration.file.remote.session.CachingSessionFactory$CachedSession@2e0aa05, file_remoteFile=test.xml, timestamp=1674556856288}]"

附言。 我嘗試使用調試器查看錯誤並發現它似乎在以下位置引發錯誤

    private String obtainRemoteFilePath(Message<?> requestMessage) {
Error here----> String remoteFilePath = this.fileNameProcessor.processMessage(requestMessage);
        Assert.state(remoteFilePath != null,
                () -> "The 'fileNameProcessor' evaluated to null 'remoteFilePath' from message: " + requestMessage);
        return remoteFilePath;
    }

“類 com.demo.sftp.models.Note 無法轉換為 class java.lang.String(com.demo.sftp.models.Note 在加載器 org.springframework.boot.devtools.restart.classloader.RestartClassLoader 的未命名模塊中@387f9ed2;java.lang.String 位於加載程序“bootstrap”的模塊 java.base 中)”

編輯 1:添加解決方案

  1. 需要將 InboundChannelAdapter 定義為 PublishSubscribeChannel 之類的
  @Bean
  public MessageChannel streamChannel() {
    return new PublishSubscribeChannel();
  }
  1. 然后將 OutboundGateway 添加為 LOWEST_PRECEDENCE 訂單,例如
  @Bean
  @Order(Ordered.LOWEST_PRECEDENCE)
  @ServiceActivator(inputChannel = "streamChannel")
  public MessageHandler moveFile() {
    SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sftpSessionFactory(), Command.MV.getCommand(),
        "headers['file_remoteDirectory'] + '/' + headers['file_remoteFile']");
    sftpOutboundGateway
        .setRenameExpressionString(
            "headers['file_remoteDirectory'] + '/processed/' +headers['timestamp'] + '-' + headers['file_remoteFile']");
    sftpOutboundGateway.setRequiresReply(false);
    sftpOutboundGateway.setUseTemporaryFileName(true);
    sftpOutboundGateway.setOutputChannelName("nullChannel");
    sftpOutboundGateway.setOrder(Ordered.LOWEST_PRECEDENCE);
    sftpOutboundGateway.setAsync(true);
    return sftpOutboundGateway;
  }
  1. 額外:如果我們想移動有錯誤的文件(來自 errorChannel)。 我們需要更改setRenameExpressionString以匹配ErrorMessage結構。 例如。
  @Bean
  @Order(Ordered.LOWEST_PRECEDENCE)
  @ServiceActivator(inputChannel = IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)
  public MessageHandler moveErrorFile() {
    SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sftpSessionFactory(), Command.MV.getCommand(),
        "payload['failedMessage']['headers']['file_remoteDirectory'] + '/' + payload['failedMessage']['headers']['file_remoteFile']");
    sftpOutboundGateway
        .setRenameExpressionString(
            "payload['failedMessage']['headers']['file_remoteDirectory'] + '/error/' + payload['failedMessage']['headers']['timestamp'] + '-' + payload['failedMessage']['headers']['file_remoteFile']");
    sftpOutboundGateway.setRequiresReply(false);
    sftpOutboundGateway.setUseTemporaryFileName(true);
    sftpOutboundGateway.setOutputChannelName("nullChannel");
    sftpOutboundGateway.setOrder(Ordered.HIGHEST_PRECEDENCE);
    sftpOutboundGateway.setAsync(true);
    return sftpOutboundGateway;
  }

作為Spring 集成中的 artem-bilan回答- SFTP 在復制后重命名或移動遠程服務器中的文件我可以通過將InboundChannelAdapter更改為PublishSubscribeChannel並創建新訂閱者來解決問題

 @Bean
  @Order(Ordered.LOWEST_PRECEDENCE)
  @ServiceActivator(inputChannel = "streamChannel")
  public MessageHandler moveFile() {
    SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sftpSessionFactory(), Command.MV.getCommand(),
        "headers['file_remoteDirectory'] + '/' + headers['file_remoteFile']");
    sftpOutboundGateway
        .setRenameExpressionString("headers['file_remoteDirectory'] + '/processed/' +headers['timestamp'] + '-' + headers['file_remoteFile']");
    sftpOutboundGateway.setRequiresReply(false);
    sftpOutboundGateway.setUseTemporaryFileName(true);
    sftpOutboundGateway.setOutputChannelName("nullChannel");
    sftpOutboundGateway.setOrder(Ordered.LOWEST_PRECEDENCE);
    sftpOutboundGateway.setAsync(true);
    return sftpOutboundGateway;
  }

當您處理ErrorMessage時,您應該遵循一些不同的路徑來訪問原始消息及其標頭。

我們將在下一個版本中減輕這種不便: https://github.com/spring-projects/spring-integration/issues/3984

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM