#spring #spring-boot #sftp #jsch #spring-integration-sftp
Вопрос:
Мы используем Spring SFTP (исходящий) с помощью шлюза для передачи файлов в несколько мест назначения. Но часто несколько файлов отправляются не по назначению. Не могу найти никаких подсказок, так как мы не получаем никаких ошибок в нашем журнале, кроме ошибки подсчета файлов после отправки файлов.
Вот наша конфигурация:
@Configuration
public class BankWiseSFTPConfig {
private final ExpressionParser EXPRESSION_PARSER;
private final BankConfigService bankConfigService;
public BankWiseSFTPConfig(BankConfigService bankConfigService) {
this.EXPRESSION_PARSER = new SpelExpressionParser();
this.bankConfigService = bankConfigService;
}
@Bean
public DelegatingSessionFactory<LsEntry> sessionFactory() {
List<BankConfigEntity> bankList = bankConfigService.getAll();
Map<Object, SessionFactory<LsEntry>> factories = new LinkedHashMap<>();
for (BankConfigEntity bank : bankList) {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory();
factory.setHost(bank.getSftpHost());
factory.setUser(bank.getSftpUser());
factory.setPort(bank.getSftpPort());
factory.setPassword(bank.getSftpPass());
factory.setAllowUnknownKeys(true);
factories.put(bank.getBankName(), factory);
}
bankList.clear();
return new DelegatingSessionFactory<LsEntry>(factories, factories.values().iterator().next());
}
@ServiceActivator(inputChannel = "toSftp")
@Bean
public SftpMessageHandler handler() {
SftpMessageHandler handler = new SftpMessageHandler(new SftpRemoteFileTemplate(sessionFactory()));
handler.setRemoteDirectoryExpression(EXPRESSION_PARSER.parseExpression("headers['path']"));
return handler;
}
@MessagingGateway
public interface SFTPOutboundGateway {
@Gateway(requestChannel = "toSftp")
void push(File file, @Header("path") String path);
@Gateway(requestChannel = "sftpChannel")
List<String> executeCommand(String path);
}
@Bean
@ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler messageHandlerLs() {
SftpOutboundGateway sftpOutboundGateway = new SftpOutboundGateway(sessionFactory(), "ls", "payload");
sftpOutboundGateway.setOptions("-1 -R");
return sftpOutboundGateway;
}
}
Вот наши методы push и подсчета файлов:
private void pushReport(String bankName,
String destinationPath,
String sourcePath,
String refundType,
List<BankReportEntity> failedBankReportEntities,
List<BankReportEntity> pushedFiles,
BankReportEntity bankReportEntity) {
String sftpStatus = SlotBankStatus.BANK_SFTP_INITIATED.name();
String errorReason = StringUtils.EMPTY;
String fileName = bankReportEntity.getFileName();
String filePath = sourcePath fileName;
File file = new File(filePath);
bankReportEntity.setSftpStatus(sftpStatus);
log.debug("{} :: SFTP Push Initiated for {} and File {}", refundType, bankName, fileName);
try {
log.info("{} :: SFTP Push trying for {} and {}", refundType, bankName, file);
gateway.push(file, destinationPath);
sftpStatus = SlotBankStatus.BANK_SFTP_COMPLETED.name();
pushedFiles.add(bankReportEntity);
log.info("{} :: SFTP Push success for {} and {}", refundType, bankName, file);
} catch (Exception e) {
emailService.sendSFTPExceptionEmail(
"File push error for file : " fileName
" and FileTransferType " bankReportEntity.getFileTransferType()
". Error : " e.getLocalizedMessage(),
bankName);
sftpStatus = SlotBankStatus.BANK_SFTP_PENDING.name();
errorReason = ErrorCode.SFTP_PUSH_FAILED.name();
failedBankReportEntities.add(bankReportEntity);
log.error("{} :: File push error for file : {}, Bank {}, FileTransferType {}, Error : {}",
refundType,
fileName,
bankName,
bankReportEntity.getFileTransferType(),
e.getMessage(),
e
);
} finally {
log.info("{} :: SFTP to {} Status Updated for : {}", refundType, bankName, bankReportEntity);
bankReportEntity.setSftpStatus(sftpStatus);
bankReportEntity.setErrorReason(errorReason);
}
}
private SFTPPushFileCountDto getSFTPSuccessfulFileCount(
String bankName,
String path,
String refundType,
List<BankReportEntity> pushedFiles,
List<BankReportEntity> failedBankReports) {
int totalSuccessfulPush = pushedFiles.size();
int totalFailedPush = failedBankReports.size();
log.info("{} :: getSFTPSuccessfulFileCount() for {}, from {}", refundType, bankName, path);
try {
List<String> remoteFiles = gateway.executeCommand(path);
for (Iterator<BankReportEntity> pushedFilesIterator = pushedFiles.iterator(); pushedFilesIterator.hasNext(); ) {
BankReportEntity bankReport = pushedFilesIterator.next();
String fileName = bankReport.getFileName();
if (!remoteFiles.contains(fileName)) {
log.error("getSFTPSuccessfulFileCount() : File not found in remote {}. File: {}", path, fileName);
totalFailedPush ;
totalSuccessfulPush--;
bankReport.setSftpStatus(SlotBankStatus.BANK_SFTP_PENDING.name());
bankReport.setErrorReason(ErrorCode.UNKNOWN_ERROR_CODE.name());
pushedFilesIterator.remove();
failedBankReports.add(bankReport);
emailService.sendSFTPExceptionEmail(
"File push error for file : " fileName
" and FileTransferType " bankReport.getFileTransferType()
". Error : " ErrorCode.UNKNOWN_ERROR_CODE.description(),
bankName);
}
}
} catch (Exception ex) {
emailService.sendSFTPExceptionEmail("SFTP file count Failed from path " path, bankName);
log.error("{} :: getSFTPSuccessfulFileCount() Failed for {}. Error : {}",
refundType,
bankName,
ex.getMessage(),
ex);
}
return SFTPPushFileCountDto.builder()
.totalSuccessfulPush(totalSuccessfulPush)
.totalFailedPush(totalFailedPush)
.build();
}
Мы не можем воспроизвести проблему в нашей среде.
Кто-нибудь может помочь?
Комментарии:
1. несколько файлов отправляются не по назначению. , есть ли пример правильного и неправильного назначения?
2. Например, есть два пункта назначения sftp a,b, где файл a отправляется в местоположение b, когда не удалось выполнить подсчет для местоположения a
3. 1. Есть ли какой-либо конкретный пример
a
иb
? Имеет лиa
иb
имеет ли какое-либо отношение? 2. Можете ли вы также включить код, предоставляющий источникString destinationPath
ofpushReport
?4. a и b — это два разных сервера назначения, на которые передаются файлы. Пути назначения настраиваются в базе данных.