Файлы отправляются в неправильное расположение sftp при использовании исходящего шлюза Spring SFTP

#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 of pushReport ?

4. a и b — это два разных сервера назначения, на которые передаются файлы. Пути назначения настраиваются в базе данных.