Определение, когда FileWrittenEvent завершил запись всего файла - PullRequest
0 голосов
/ 29 января 2020

Это мой первый вопрос, поэтому, пожалуйста, потерпите меня. В недавнем выпуске Spring 5.2 в Spring Integration были добавлены определенные и чрезвычайно полезные компоненты, как видно по этой ссылке: https://docs.spring.io/spring-integration/reference/html/sftp.html#sftp -server-события Apache MINA была интегрирована с новым слушателем "ApacheMinaSftpEventListener", который

прослушивает определенные Apache события сервера SFTP Mina и публикует их как ApplicationEvents

Пока что мой Приложение может захватывать события приложения, как отмечено в документации по предоставленной ссылке, но я не могу понять, когда событие заканчивается ... если это имеет смысл (вероятно, нет). В потоке процесса приложение запускается и активируется как SFTP-сервер на указанном порту. Я могу использовать имя пользователя и пароль для подключения и «поместить» файл в систему, которая инициирует передачу. Когда я вхожу в систему, я могу захватить «SessionOpenedEvent» Когда я передаю файл, я могу захватить «FileWrittenEvent» Когда я завершаю соединение или разрываю соединение, я могу перехватить «SessionClosedEvent» Когда размер файла больше, я могу перехватить ВСЕ события «FileWrittenEvent», которые сообщают мне, что передача происходит в потоке буфера заранее определенного или рассчитанного размера. Я пытаюсь определить, «Как я могу узнать, когда этот поток закончится». Это поможет мне ответить «Как SFTP-сервер принимает файл, когда я могу получить доступ к завершенному файлу?» Бин My ​​Listener (который подключается к Apache Mina при запуске через SubSystemFactory)

@Configuration
public class SftpConfiguration {
    @Bean
    public ApacheMinaSftpEventListener apacheMinaSftpEventListener() {
        return new ApacheMinaSftpEventListener();
    }   
}
SftpSubsystemFactory subSystem = new SftpSubsystemFactory();
subSystem.addSftpEventListener(listener);

Мой прослушиватель событий: это здесь, так что я могу видеть некоторые результаты в регистраторе, когда я понял, что файл размером в несколько ГБ FileWrittenEvent немного сошел с ума.

@Async
@EventListener
public void sftpEventListener(ApacheMinaSftpEvent sftpEvent) {
    log.info("Capturing Event: ", sftpEvent.getClass().getSimpleName());
    log.info("Event Details: ", sftpEvent.toString());
}

Эти несколько частей были всем, что мне действительно нужно, чтобы начать захват событий Я думал, что мне нужно будет переопределить метод, чтобы помочь мне захватить, когда поток заканчивается, чтобы я мог двигаться дальше с бизнес-логикой c, но я не уверен, какой именно. Кажется, я могу получить доступ к файлу (чтение / запись) до того, как будет сделан поток, поэтому я не могу использовать logi c, который пытается "переместить" файл и ждать, пока он выбросит ошибка, хотя такой подход казался мне плохой практикой. Любое руководство будет с благодарностью, спасибо. Информация о версии

  • Пружина 5.2.3
  • Пружинный ботинок 2.2.3
  • Apache Мина 2.1.3
  • Java 1.8

1 Ответ

0 голосов
/ 07 февраля 2020

Это может быть не полезно для других, но я нашел способ обойти мою первоначальную проблему, интегрировав соответствующее решение в сочетании с новыми классами Apache MINA, найденными в этом ответе: { ссылка } Мое решение: Создайте класс, который расширяет новый ApacheMinaSftpEventListener, переопределяя методы 'open' и 'close', чтобы гарантировать, что бизнес-логи SFTP-сервера будут знать, когда запись файла завершится.

public class WatcherSftpEventListener extends ApacheMinaSftpEventListener {
    ...
    ...
    @Override public void open(ServerSession session, String remoteHandle, Handle localHandle) throws IOException {
        File file = localHandle.getFile().toFile();
        if (file.isFile() && file.exists()) {
            log.debug("File Open: {}", file.toString());
        }
        // Keep around the super call for now
        super.open(session, remoteHandle, localHandle);
    }

    @Override
    public void close(ServerSession session, String remoteHandle, Handle localHandle) {
        File file = localHandle.getFile().toFile();
        if (file.isFile() && file.exists()) {
            log.debug("RemoteHandle: {}", remoteHandle);
            log.debug("File Closed: {}", file.toString());
            for (SftpFileUploadCompleteListener listener : fileReadyListeners) {
                try {
                    listener.onFileReady(file);
                } catch (Exception e) {
                    String msg = String.format("File '%s' caused an error in processing '%s'", file.getName(), e.getMessage());
                    log.error(msg);
                    try {
                        session.disconnect(0, msg);
                    } catch (IOException io) {
                        log.error("Could not properly disconnect from session {}; closing future state", session);
                        session.close(false);
                    }
                }
            }
        }
        // Keep around the super call for now
        super.close(session, remoteHandle, localHandle);
    }

}

Когда я запускаю Сервер SSHD Я добавил свой новый компонент-слушатель в SftpSubsystemFactory, который использует настраиваемый класс обработчика событий для применения моей бизнес-логики c к входящим файлам.

        watcherSftpEventListener.addFileReadyListener(new SftpFileUploadCompleteListener() {
            @Override
            public void onFileReady(File file) throws Exception {
                new WatcherSftpEventHandler(file, properties.getSftphost());
            }
        });
        subSystem.addSftpEventListener(watcherSftpEventListener);

В этом решении было немного больше, но, поскольку этот вопрос не так уж много траффи c, и теперь это больше для моей справки и изучения, чем что-либо еще, я не буду давать ничего большего, если его не спросить.

...