Ошибка FakeFtpServer: отказано в подключении (отказано в подключении)

#java #ftp

#java #ftp

Вопрос:

У меня есть класс, который загружает файлы с FTP-серверов с помощью FTP-клиента Apache, и я хочу его протестировать. Для этого я решил использовать класс FakeFtpServer из MockFtpServer, но он всегда завершается с той же ошибкой : Connection refused (Connection refused) .

Мой тестовый класс:

 public class FTPConnectionTest {
        /** Mock FTP Server */
        private static FakeFtpServer FAKE_FTP_SERVER;
        
        /** Mock FTP Server address */
        private static String ADDRESS = "localhost";
        
        /** Mock FTP server user name */
        private static String USERNAME = "ftpuser";
        
        /** Mock FTP Server password */
        private static String PASSWORD = "ftppasswd";
        
        /** Mock FTP Server default root */
        private static String ROOT;
        
        /** Mock FTP Server port */
        private static int PORT = 0;
        
        /** Test directory in the mock server */
        private static String DIRECTORY = "/directory";
        
        /** Test file 1*/
        private static String FILE1 = "/Human_satellite.txt";
        
        /** Content of test file 1 */
        private static String FILE1_CONTENT = "Ground control to Major Tom...";
        
        /** Test file 1*/
        private static String FILE2 = "/wall-e.txt";
        
        /** Content of test file 1 */
        private static String FILE2_CONTENT = "If lost in space, use fire extinguisher";
        
        /** Test file 1*/
        private static String FILE3 = "/buzz_lightyear.txt";
        
        /** Content of test file 1 */
        private static String FILE3_CONTENT = "To infinity, and beyond !";
        

        /**
         * Set up a mock FTP server before running the tests
         */
        @BeforeClass
        public static void setupMock() {
            // Create Mock server
            FAKE_FTP_SERVER = new FakeFtpServer();
            FAKE_FTP_SERVER.setServerControlPort(0);    // Automatically finds available port
            PORT = FAKE_FTP_SERVER.getServerControlPort();
            FAKE_FTP_SERVER.addUserAccount(new UserAccount(USERNAME, PASSWORD, ROOT));
            
            // Get the path to the resources folder where to run the mock FTP
            File mockDir = new File("src/test/resources/ftp/mock");
            ROOT = mockDir.getAbsolutePath();

            // Create mock files
            FileSystem fileSystem = new UnixFakeFileSystem();
            fileSystem.add(new DirectoryEntry(ROOT));
            fileSystem.add(new FileEntry(ROOT   FILE1, FILE1_CONTENT));
            fileSystem.add(new DirectoryEntry(ROOT   DIRECTORY));
            fileSystem.add(new FileEntry(ROOT   DIRECTORY   FILE2, FILE2_CONTENT));
            fileSystem.add(new FileEntry(ROOT   DIRECTORY   FILE3, FILE3_CONTENT));
            FAKE_FTP_SERVER.setFileSystem(fileSystem);

            FAKE_FTP_SERVER.start();
        }
        
        /**
         * The the mock FTP Server once the tests are done
         */
        @AfterClass
        public static void stop() {
            FAKE_FTP_SERVER.stop();
        }
        
        /**
         * Test
         */
        @Test
        public void testFetchNewFiles () {
            // Get output path
            String outputPath = "src/test/resources/ftp/result";
            File output = new File(outputPath);
            outputPath = output.getAbsolutePath();
            
            // Create the connection and get the files
            FTPConnection conn = new FTPConnection(ADDRESS, PORT, USERNAME, PASSWORD, outputPath);
            conn.fetchNewFiles();
            
            // Check that the files have bin downloaded
            File file1 = new File(outputPath   FILE1);
            assertTrue(file1.exists());
        }
}
  

И вот часть класса FTP, которая завершается с ошибкой:

 public class FTPConnection {
    
    /** Logger */
    private Logger logger;
    
    /** The FTP Client used to connect to the server */
    private FTPClient client;
    
    /** The address of the server */
    private String server;
    
    /** The port of the server (default 21) */
    private int port;
    
    /** The user name to use to connect to the server */
    private String user;
    
    /** The password to use to connect to the server */
    private String password;
    
    /** The directory where to save the downloaded files */
    private String output;

    /**
     * Constructor
     * @param server            the address of the FTP server
     * @param port              the port of the FTP server
     * @param user              the user name to use to connect to the server
     * @param password      the password to use to connect to the server
     * @param output            the output directory where to download the files
     */
    public FTPConnection (String server, int port, String user, String password, String output) {
        this.logger = LoggerFactory.getLogger(FTPConnection.class);
        this.server = server;
        this.port = port;
        this.user = user;
        this.password = password;
        this.output = output;
        this.client = new FTPClient();
    }
    
    /**
     * Constructor
     * @param server            the address of the FTP server
     * @param user              the user name to use to connect to the server
     * @param password      the password to use to connect to the server
     * @param output            the output directory where to download the files
     */
    public FTPConnection (String server, String user, String password, String output) {
        this(server, 21, user, password, output);
    }

    public void fetchNewFiles() {
        // Connect to the server
        try {
            this.client.connect(server, port);    // That's the line that fails
            this.client.login(user, password);
        } catch (IOException e) {
            logger.error("Error while connecting to FTP server '"   this.server   "': "   e.getMessage());
            e.printStackTrace();
            return;
        }
    }
}
  

И, наконец, выдержка из того, что происходит в консоли:

 19:24:31.417 [Thread-1] INFO org.mockftpserver.fake.FakeFtpServer - Starting the server on port 0
19:24:31.419 [Thread-1] INFO org.mockftpserver.fake.FakeFtpServer - Actual server port is 34003
19:24:31.444 [main] ERROR com.my.project.importHandler.FTPConnection - Error while connecting to FTP server 'localhost': Connection refused (Connection refused)
  ***   STACK TRACE   ***
19:24:31.457 [Thread-1] DEBUG org.mockftpserver.fake.FakeFtpServer - Cleaning up server...
19:24:31.457 [Thread-1] INFO org.mockftpserver.fake.FakeFtpServer - Server stopped.
  

Ответ №1:

Хорошо, я нашел это: FAKE_FTP_SERVER.setServerControlPort(0); устанавливает значение порта сервера равным 0, и автоматический выбор доступного порта происходит только во FAKE_FTP_SERVER.start(); время . Я переместил строку PORT = FAKE_FTP_SERVER.getServerControlPort(); после FAKE_FTP_SERVER.start(); , и теперь она работает.