View Javadoc

1   /*
2    * $Id: FTPTestClient.java 20320 2010-11-24 15:03:31Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport.ftp.server;
12  
13  import org.mule.util.IOUtils;
14  
15  import java.io.File;
16  import java.io.IOException;
17  
18  import org.apache.commons.logging.Log;
19  import org.apache.commons.logging.LogFactory;
20  import org.apache.commons.net.ftp.FTPClient;
21  import org.apache.commons.net.ftp.FTPFile;
22  
23  /**
24   * Ftp client wrapper for working with an FTP server.
25   */
26  public class FTPTestClient
27  {
28      protected final transient Log logger = LogFactory.getLog(this.getClass());
29      FTPClient ftpClient = null;   
30      String server = null;
31      int port;
32      String user = null;
33      String password = null;
34      public static final int TIMEOUT = 5000; // just to make sure we don't hang the test on invalid connection attempts
35          
36      public FTPTestClient(String server, int port, String user, String password)
37      {
38          super();
39          this.server = server;
40          this.port = port;
41          this.user = user;
42          this.password = password;
43          ftpClient = new FTPClient();
44      }
45  
46      public boolean testConnection() throws IOException
47      {
48          connect();
49          return verifyStatusCode(ftpClient.noop());        
50      }
51      
52      /**
53       * Get a list of file names in a given directory for admin
54       * @return List of files/directories
55       * @throws IOException
56       */
57      public String[] getFileList(String path) throws IOException
58      {
59          connect();
60          return ftpClient.listNames(path);
61      }
62  
63      /**
64       * Create a directory
65       * @param dir
66       * @return true if successful, false if not
67       * @throws IOException
68       */
69      public boolean makeDir(String dir) throws IOException
70      {
71          connect();
72          return verifyStatusCode(ftpClient.mkd(dir));
73      }
74      
75      /**
76       * Delete a directory
77       * @param dir The directory to delete
78       * @return true if successful, false if not
79       * @throws IOException
80       */
81      public boolean deleteDir(String dir) throws IOException
82      {
83          connect();
84          return verifyStatusCode(ftpClient.rmd(dir));
85      }
86      
87      /**
88       * Check that the status code is successful (between 200 and 299)
89       * @param status The status code to check
90       * @return true if status is successful, false if not
91       */ 
92      private boolean verifyStatusCode(int status)
93      {
94          if(status >= 200 && status < 300)
95          {
96              return true;
97          }
98          return false;
99      }
100 
101     /**
102      * Upload a file to the ftp server
103      * @param fileName The file to upload
104      * @return true if successful, false if not
105      * @throws IOException
106      */
107     public boolean putFile(String fileName, String targetDir) throws IOException
108     {
109         connect();       
110         File file = new File(IOUtils.getResourceAsUrl(fileName, getClass()).getFile()); //hacky way to get the file shortname        
111         return ftpClient.storeFile(targetDir + "/" + file.getName(), IOUtils.getResourceAsStream(fileName, getClass()));
112     }
113     
114     /**
115      * Check if a directory exists by trying to go to it
116      * @param path The directory to try
117      * @return True if the directory exists, false if not
118      * @throws IOException
119      */
120     public boolean dirExists(String path) throws IOException
121     {
122         connect();
123         String cwd = ftpClient.printWorkingDirectory(); //store the current working dir so we can go back to it
124         boolean dirExists = ftpClient.changeWorkingDirectory(path);
125         ftpClient.changeWorkingDirectory(cwd); // go back to the cwd
126         return dirExists;
127     }
128     
129     /**
130      * Delete all files and subdirectories. Note: extra slashes are ignored by the
131      * ftp server, so I didn't bother to filter them out
132      * 
133      */
134     public void recursiveDelete(String path) throws IOException
135     {
136         connect();
137         String cwd = ftpClient.printWorkingDirectory(); //store the current working dir so we can go back to it
138         System.out.println("CWD: " + cwd);
139         ftpClient.changeWorkingDirectory(path);
140         System.out.println("Changed CWD: " + path);
141         
142         FTPFile[] fileObjs = ftpClient.listFiles();
143         for(int i = 0; i < fileObjs.length; i++)
144         {
145             if(fileObjs[i].isFile()) //delete the file
146             {
147                 ftpClient.deleteFile(fileObjs[i].getName());
148             }
149             else if(fileObjs[i].isDirectory() && (getFileList(ftpClient.printWorkingDirectory() + "/" + fileObjs[i].getName()).length > 0))
150             {
151                 recursiveDelete(ftpClient.printWorkingDirectory() + "/" + fileObjs[i].getName());
152                 deleteDir(ftpClient.printWorkingDirectory() + "/" + fileObjs[i].getName()); //safe to delete dir now that it's empty
153             }
154             else if(fileObjs[i].isDirectory()) //delete the empty directory
155             {
156                 deleteDir(ftpClient.printWorkingDirectory() + "/" + fileObjs[i].getName());                
157             }
158             // ignore file if not a file or a dir
159         }
160         ftpClient.changeWorkingDirectory(cwd); // go back to the cwd
161     }
162     
163     /**
164      * Initiate a connection to the ftp server
165      * @throws IOException
166      */
167     protected void connect() throws IOException
168     {
169         if(!ftpClient.isConnected())
170         {
171             ftpClient = new FTPClient();
172             ftpClient.setDefaultTimeout(TIMEOUT);
173             ftpClient.connect(server, port);
174             ftpClient.login(user, password);
175         }
176     }
177 
178     /**
179      * Check if the ftp client is connected
180      * @return true if connected, false if not
181      */
182     public boolean isConnected()
183     {
184         return ftpClient.isConnected();
185     }
186 
187     /**
188      * Disconnect the ftp client
189      * @throws IOException
190      */
191     public void disconnect() throws IOException
192     {
193         ftpClient.disconnect();
194     }
195 
196     /**
197      * Check if a file exists on the ftp server
198      * @param file The name of the file to check
199      * @return true if file exists, false if not
200      * @throws IOException
201      */
202     public boolean fileExists(String file) throws IOException
203     {
204         return (ftpClient.listFiles(file).length > 0);
205     }
206 
207     /**
208      * Delete a single file.
209      * @param name The file to delete
210      * @return true if successful, false if not
211      * @throws IOException
212      */
213     public boolean deleteFile(String name) throws IOException
214     {
215         return ftpClient.deleteFile(name);
216     }
217 
218     /**
219      * Verify that a number of files exist on the ftp server
220      * @param directory The remote directory to check
221      * @param timeout The max time to wait
222      * @return true if the file count matches before the timeout, false if not
223      */
224     public boolean expectFileCount(String directory, int count, long timeout) throws InterruptedException, IOException
225     {
226         long endTime = System.currentTimeMillis() + timeout;
227         int iteration = 1;
228         while(System.currentTimeMillis() < endTime)
229         {
230             logger.debug("checking file list, iteration :" + iteration);
231             if (getFileList(directory).length == count)
232             {
233                 logger.debug("found expected file count : " + count);
234                 return true;
235             }            
236             Thread.sleep(1000);
237             ++iteration;
238         }
239         return false;
240     }
241 }