[英]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.xml
( upload/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:添加解決方案
@Bean
public MessageChannel streamChannel() {
return new 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;
}
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.