Ошибка загрузки файла по FTP в контейнере Docker - PullRequest
0 голосов
/ 15 марта 2020

У меня есть приложение весенней загрузки, использующее библиотеку apache commons- net У меня FTP-сервер работает на AWS EC2. Filezilla подключиться и загрузить файл в обычном режиме. Локальное приложение подключается и загружает файл нормально. Когда я запускаю это приложение, используя Docker, приложение подключается к FTP успешно, но не может загрузить файл. Код ответа: 500 Dockerfile :

FROM openjdk:11
RUN mkdir /app
COPY build/libs/aws-batch1-1.0.0.jar /app/aws-batch1.jar
ENTRYPOINT ["java","-jar","/app/aws-batch1.jar","Test"]

Команда построения образа :

docker build -t aws-batch1 .

Команда запуска образа :

docker run aws-batch1

Код подключения FTP :

private boolean connectFTPServer() throws IOException {
        LOGGER.info("CONNECT");
        boolean flg = true;
        try {
            ftpClient.connect(FTP_SERVER_ADDRESS, FTP_SERVER_PORT_NUMBER);
            ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
        } catch (IOException e) {
            LOGGER.error("CONNECT FAILED", e);
            flg = false;
        }

        int replyCode = ftpClient.getReplyCode();
        LOGGER.info("replyCode: " + replyCode);
        if (!FTPReply.isPositiveCompletion(replyCode)) {
            flg = false;
        }
        if (!flg) {
            throw new IOException();
        }
        return flg;
    }

Код загрузки файла :

public boolean uploadFile(byte[] content, String fileName)
            throws IOException {
        boolean flg = false;
        LOGGER.info("uploadFile");
        if (connectFTPServer()) {
            LOGGER.info("connectFTPServer success");
            LOGGER.info("content: " + new String(content));
            try (InputStream is = new ByteArrayInputStream(content)) {
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                boolean storeFile = ftpClient.storeFile(fileName, is);
                LOGGER.info("storeFile: " + storeFile);
                LOGGER.info("ftpClient.getReplyCode(): " + ftpClient.getReplyCode());

                flg = storeFile &&
                        ftpClient.getReplyCode() ==
                                FTPReply.CLOSING_DATA_CONNECTION;
                if (!flg) {
                    throw new IOException("FTP error");
                }
            } finally {
                closeConnectionFTPClient();
            }
        }
        return flg;
    }

Вход при загрузке на локально успешно :

uploadFile
CONNECT
replyCode: 230
connectFTPServer success
content: test
storeFile: true
ftpClient.getReplyCode(): 226

Журнал при загрузке Docker не удалось :

uploadFile
CONNECT
replyCode: 230
connectFTPServer success
content: test
storeFile: false
ftpClient.getReplyCode(): 500

Пожалуйста, помогите мне. Я пропускаю какие-либо шаги?

ОБНОВЛЕНИЕ : Спасибо @Metin Я обновил код для подключения к FTP-клиенту, как показано ниже:

private boolean connectFTPServer() throws IOException {
        LOGGER.info("CONNECT");
        boolean flg = true;
        try {
            ftpClient.connect(FTP_SERVER_ADDRESS, FTP_SERVER_PORT_NUMBER);
            ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
            ftpClient.enterLocalPassiveMode();
        } catch (IOException e) {
            LOGGER.error("CONNECT FAILED", e);
            flg = false;
        }

        int replyCode = ftpClient.getReplyCode();
        LOGGER.info("replyCode: " + replyCode);
        if (!FTPReply.isPositiveCompletion(replyCode)) {
            flg = false;
        }
        if (!flg) {
            throw new IOException();
        }
        return flg;
    }

, и он работает!

1 Ответ

1 голос
/ 15 марта 2020

Возможно, вы захотите прочитать о различиях активного и пассивного режима ftp: В чем разница между активным и пассивным FTP?

Следует прийти к выводу, что активный режим ftp не подходит для контейнерных ftp-клиентов из-за того, что сервер активно пытается инициировать соединение для передачи данных с ftp-клиентом, что невозможно для контейнера (если контейнер не использует network: host, что обычно нежелательно).

С другой стороны, в пассивном режиме ftp сервер сообщит вашему FTP-клиенту, какой порт необходимо использовать для следующего подключения к данным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...