View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.sftp;
8   
9   import org.mule.module.client.MuleClient;
10  
11  import java.io.File;
12  import java.io.IOException;
13  import java.util.ResourceBundle;
14  
15  import org.junit.Test;
16  
17  import static org.junit.Assert.assertEquals;
18  import static org.junit.Assert.assertNotNull;
19  import static org.junit.Assert.assertTrue;
20  import static org.junit.Assert.fail;
21  
22  /**
23   * Test the archive features.
24   */
25  public class SftpArchiveFunctionalTestCase extends AbstractSftpTestCase
26  {
27  
28      private static final long TIMEOUT = 15000;
29  
30      private static final String FILE1_TXT = "file1.txt";
31      private static final String FILE2_TXT = "file2.txt";
32      private static final String FILE3_TXT = "file3.txt";
33      private static final String FILE4_TXT = "file4.txt";
34  
35      private static final String FILE2_TMP_REGEXP = "file2_.+";
36      private static final String FILE3_TMP_REGEXP = "file3_.+";
37  
38      private static final String TMP_SENDING = "tmp_sending";
39      private static final String TMP_RECEIVING = "tmp_receiving";
40  
41      private static final String INBOUND_ENDPOINT1 = "inboundEndpoint1";
42      private static final String INBOUND_ENDPOINT2 = "inboundEndpoint2";
43      private static final String INBOUND_ENDPOINT3 = "inboundEndpoint3";
44      private static final String INBOUND_ENDPOINT4 = "inboundEndpoint4";
45  
46      // Size of the generated stream - 2 Mb
47      final static int SEND_SIZE = 1024 * 1024 * 2;
48  
49      private String archive = null;
50      private String archiveCanonicalPath = null;
51  
52      @Override
53      protected String getConfigResources()
54      {
55          return "mule-sftp-archive-test-config.xml";
56      }
57  
58      @Override
59      protected void doSetUp() throws Exception
60      {
61          super.doSetUp();
62  
63          // this block moved from the constructor to allow this test to be skipped if
64          // the resource isn't found via
65          // AbstractMuleTestCase.isDisabledInThisEnvironment 
66          ResourceBundle rb = ResourceBundle.getBundle("sftp-settings");
67          archive = rb.getString("ARCHIVE");
68          archiveCanonicalPath = new File(archive).getCanonicalPath();        
69          
70          recursiveDeleteInLocalFilesystem(new File(archive));
71          initEndpointDirectories(new String[]{"receiving1", "receiving2", "receiving3", "receiving4"},
72              new String[]{INBOUND_ENDPOINT1, INBOUND_ENDPOINT2, INBOUND_ENDPOINT3, INBOUND_ENDPOINT4});
73      }
74  
75      /**
76       * Test plain archive functionality with no extra features enabled
77       */
78      @Test
79      public void testArchive1() throws Exception
80      {
81          executeBaseTest(INBOUND_ENDPOINT1, "vm://test.upload1", FILE1_TXT, SEND_SIZE, "receiving1", TIMEOUT);
82  
83          // Assert that the file now exists in the archive
84          assertFilesInLocalFilesystem(archive, FILE1_TXT);
85  
86          // And that the file is gone from the inbound endpoint
87          assertNoFilesInEndpoint(new MuleClient(muleContext), INBOUND_ENDPOINT1);
88      }
89  
90      /**
91       * Test archive functionality with full usage of temp-dir and creation of unique
92       * names of temp-files
93       */
94      @Test
95      public void testArchive2() throws Exception
96      {
97          executeBaseTest(INBOUND_ENDPOINT2, "vm://test.upload2", FILE2_TXT, SEND_SIZE, "receiving2", TIMEOUT);
98  
99          // Assert that the file now exists in the archive
100         // (with some unknown timestamp in the filename)
101         // and that the tmp-archive-folders are empty
102         assertFilesInLocalFilesystem(archive, new String[]{TMP_RECEIVING, TMP_SENDING, FILE2_TMP_REGEXP});
103         assertNoFilesInLocalFilesystem(archive + File.separatorChar + TMP_RECEIVING);
104         assertNoFilesInLocalFilesystem(archive + File.separatorChar + TMP_SENDING);
105 
106         // Assert that the file is gone from the inbound endpoint (including its
107         // tmp-folders)
108         // Note that directories are not returned in this listing
109         MuleClient mc = new MuleClient(muleContext);
110         assertNoFilesInEndpoint(mc, INBOUND_ENDPOINT2);
111         assertNoFilesInEndpoint(new MuleClient(muleContext), INBOUND_ENDPOINT2, TMP_RECEIVING);
112         assertNoFilesInEndpoint(new MuleClient(muleContext), INBOUND_ENDPOINT2, TMP_SENDING);
113     }
114 
115     /**
116      * Test archive functionality with usage of temp-dir for inbound and outbound
117      * endpoints with creation of unique names of temp-files but not for the archive
118      */
119     @Test
120     public void testArchive3() throws Exception
121     {
122         executeBaseTest(INBOUND_ENDPOINT3, "vm://test.upload3", FILE3_TXT, SEND_SIZE, "receiving3", TIMEOUT);
123 
124         // Assert that the file now exists in the archive
125         // (with some unknown timestamp in the filename)
126         assertFilesInLocalFilesystem(archive, FILE3_TMP_REGEXP);
127 
128         // Assert that the file is gone from the inbound endpoint (including its
129         // tmp-folders)
130         // Note that directories are not returned in this listing
131         MuleClient mc = new MuleClient(muleContext);
132         assertNoFilesInEndpoint(mc, INBOUND_ENDPOINT3);
133         assertNoFilesInEndpoint(new MuleClient(muleContext), INBOUND_ENDPOINT3, TMP_RECEIVING);
134         assertNoFilesInEndpoint(new MuleClient(muleContext), INBOUND_ENDPOINT3, TMP_SENDING);
135     }
136 
137     /**
138      * Test archive functionality with usage of temp-dir for archive but not for
139      * inbound and outbound endpoints
140      */
141     @Test
142     public void testArchive4() throws Exception
143     {
144         executeBaseTest(INBOUND_ENDPOINT4, "vm://test.upload4", FILE4_TXT, SEND_SIZE, "receiving4", TIMEOUT);
145 
146         // Assert that the file now exists in the archive
147         // and that the tmp-archive-folders are empty
148         assertFilesInLocalFilesystem(archive, new String[]{TMP_RECEIVING, TMP_SENDING, FILE4_TXT});
149         assertNoFilesInLocalFilesystem(archive + File.separatorChar + TMP_RECEIVING);
150         assertNoFilesInLocalFilesystem(archive + File.separatorChar + TMP_SENDING);
151 
152         // Assert that the file is gone from the inbound endpoint
153         MuleClient mc = new MuleClient(muleContext);
154         assertNoFilesInEndpoint(mc, INBOUND_ENDPOINT4);
155     }
156 
157     /**
158      * Test error handling with plain archive functionality with no extra features
159      * enabled
160      */
161     @Test
162     public void testCantWriteToArchive1() throws Exception
163     {
164         makeArchiveReadOnly();
165         try
166         {
167             executeBaseTest(INBOUND_ENDPOINT1, "vm://test.upload1", FILE1_TXT, SEND_SIZE, "receiving1",
168                 TIMEOUT, "sftp");
169             fail("Expected error");
170         }
171         catch (Exception e)
172         {
173             assertNotNull(e);
174             assertTrue(e instanceof IOException);
175             assertEquals("Destination folder is not writeable: " + archiveCanonicalPath, e.getMessage());
176         }
177 
178         // Assert that file still exists in the inbound endpoint after the failure
179         assertFilesInEndpoint(new MuleClient(muleContext), INBOUND_ENDPOINT1, FILE1_TXT);
180 
181         // Assert that no files exists in the archive after the error
182         assertNoFilesInLocalFilesystem(archive);
183     }
184 
185     /**
186      * Test error handling with archive functionality with full usage of temp-dir and
187      * creation of unique names of temp-files
188      */
189     @Test
190     public void testCantWriteToArchive2() throws Exception
191     {
192         makeArchiveTmpFolderReadOnly();
193         makeArchiveReadOnly();
194         try
195         {
196             executeBaseTest(INBOUND_ENDPOINT2, "vm://test.upload2", FILE2_TXT, SEND_SIZE, "receiving2",
197                 TIMEOUT, "sftp");
198             fail("Expected error");
199         }
200         catch (Exception e)
201         {
202             assertNotNull(e);
203             assertTrue(e instanceof IOException);
204             assertEquals("Destination folder is not writeable: " + archiveCanonicalPath + File.separatorChar
205                          + TMP_RECEIVING, e.getMessage());
206         }
207 
208         // Assert that the file still exists in the inbound endpoint's tmp-folder
209         // after the failure
210         // (with some unknown timestamp in the filename)
211         // Note that directories are not returned in this listing
212         MuleClient mc = new MuleClient(muleContext);
213         assertNoFilesInEndpoint(mc, INBOUND_ENDPOINT2);
214         assertNoFilesInEndpoint(mc, INBOUND_ENDPOINT2, TMP_RECEIVING);
215         assertFilesInEndpoint(mc, INBOUND_ENDPOINT2, TMP_SENDING, FILE2_TMP_REGEXP);
216 
217         // Assert that no files exists in the archive after the error except from the
218         // temp-folders
219         assertFilesInLocalFilesystem(archive, new String[]{TMP_RECEIVING, TMP_SENDING});
220     }
221 
222     /**
223      * Test error handling with archive functionality with usage of temp-dir for
224      * inbound and outbound endpoints with creation of unique names of temp-files but
225      * not for the archive
226      */
227     @Test
228     public void testCantWriteToArchive3() throws Exception
229     {
230         makeArchiveReadOnly();
231         try
232         {
233             executeBaseTest(INBOUND_ENDPOINT3, "vm://test.upload3", FILE3_TXT, SEND_SIZE, "receiving3",
234                 TIMEOUT, "sftp");
235             fail("Expected error");
236         }
237         catch (Exception e)
238         {
239             assertNotNull(e);
240             assertTrue(e instanceof IOException);
241             assertEquals("Destination folder is not writeable: " + archiveCanonicalPath, e.getMessage());
242         }
243 
244         // Assert that the file still exists in the inbound endpoint's tmp-folder
245         // after the failure
246         // (with some unknown timestamp in the filename)
247         // Note that directories are not returned in this listing
248         MuleClient mc = new MuleClient(muleContext);
249         assertNoFilesInEndpoint(mc, INBOUND_ENDPOINT3);
250         assertNoFilesInEndpoint(mc, INBOUND_ENDPOINT3, TMP_RECEIVING);
251         assertFilesInEndpoint(mc, INBOUND_ENDPOINT3, TMP_SENDING, FILE3_TMP_REGEXP);
252 
253         // Assert that no files exists in the archive after the error
254         assertNoFilesInLocalFilesystem(archive);
255     }
256 
257     /**
258      * Test error handling with archive functionality with usage of temp-dir for
259      * archive but not for inbound and outbound endpoints
260      */
261     @Test
262     public void testCantWriteToArchive4() throws Exception
263     {
264         makeArchiveTmpFolderReadOnly();
265         makeArchiveReadOnly();
266         try
267         {
268             executeBaseTest(INBOUND_ENDPOINT4, "vm://test.upload4", FILE4_TXT, SEND_SIZE, "receiving4",
269                 TIMEOUT, "sftp");
270             fail("Expected error");
271         }
272         catch (Exception e)
273         {
274             assertNotNull(e);
275             assertTrue(e instanceof IOException);
276             assertEquals("Destination folder is not writeable: " + archiveCanonicalPath + File.separatorChar
277                          + TMP_RECEIVING, e.getMessage());
278         }
279 
280         // Assert that file still exists in the inbound endpoint after the failure
281         assertFilesInEndpoint(new MuleClient(muleContext), INBOUND_ENDPOINT4, FILE4_TXT);
282 
283         // Assert that no files exists in the archive after the error except from the
284         // temp-folders
285         assertFilesInLocalFilesystem(archive, new String[]{TMP_RECEIVING, TMP_SENDING});
286     }
287 
288     private void makeArchiveReadOnly() throws IOException
289     {
290         makeFolderReadOnly(archive);
291     }
292 
293     private void makeArchiveTmpFolderReadOnly() throws IOException
294     {
295         makeFolderReadOnly(archive + File.separator + TMP_SENDING);
296         makeFolderReadOnly(archive + File.separator + TMP_RECEIVING);
297     }
298 
299     private void makeFolderReadOnly(String folderName) throws IOException
300     {
301         File folder = new File(folderName);
302         if (!folder.exists())
303         {
304             if (!folder.mkdirs())
305             {
306                 throw new IOException("Failed to create folder: " + folderName);
307             }
308         }
309         if (!folder.setReadOnly())
310         {
311             throw new IOException("Failed to make folder readonly: " + folderName);
312         }
313     }
314 
315 }