1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.sftp;
12
13 import java.io.File;
14 import java.io.FileOutputStream;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.text.SimpleDateFormat;
18 import java.util.Date;
19
20 import org.apache.commons.io.IOUtils;
21 import org.apache.log4j.Logger;
22 import org.mule.api.endpoint.ImmutableEndpoint;
23
24
25
26
27
28
29
30 public class SftpUtil
31 {
32
33 private static final Logger logger = Logger.getLogger(SftpUtil.class);
34
35 private SftpConnector connector;
36 private ImmutableEndpoint endpoint;
37
38 private static final String DUPLICATE_HANDLING_DEFAULT = SftpConnector.PROPERTY_DUPLICATE_HANDLING_THROW_EXCEPTION;
39 private static final boolean KEEP_FILE_ON_ERROR_DEFAULT = true;
40 private static final boolean USE_TEMP_FILE_TIMESTAMP_SUFFIX_DEFAULT = false;
41 private static final long SIZE_CHECK_WAIT_TIME_DEFAULT = -1;
42
43 private final static Object lock = new Object();
44
45 public SftpUtil(ImmutableEndpoint endpoint)
46 {
47 this.endpoint = endpoint;
48 this.connector = (SftpConnector) endpoint.getConnector();
49 }
50
51 public String createUniqueSuffix(String filename)
52 {
53
54
55 int fileTypeIdx = filename.lastIndexOf('.');
56 String fileType = filename.substring(fileTypeIdx);
57
58
59 filename = filename.substring(0, fileTypeIdx);
60
61
62 SimpleDateFormat timestampFormatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
63 String timstampStr = '_' + timestampFormatter.format(new Date());
64
65 return filename + timstampStr + fileType;
66 }
67
68 public String getTempDirInbound()
69 {
70 String endpointValue = (String) endpoint.getProperty(SftpConnector.PROPERTY_TEMP_DIR);
71 if (endpointValue != null)
72 {
73 return endpointValue;
74 }
75
76 String connectorValue = connector.getTempDirInbound();
77 if (connectorValue != null)
78 {
79 return connectorValue;
80 }
81
82 return null;
83 }
84
85 public boolean isUseTempDirInbound()
86 {
87 return getTempDirInbound() != null;
88 }
89
90 public String getTempDirOutbound()
91 {
92 String endpointValue = (String) endpoint.getProperty(SftpConnector.PROPERTY_TEMP_DIR);
93 if (endpointValue != null)
94 {
95 return endpointValue;
96 }
97
98 String connectorValue = connector.getTempDirOutbound();
99 if (connectorValue != null)
100 {
101 return connectorValue;
102 }
103
104 return null;
105 }
106
107 public boolean isUseTempDirOutbound()
108 {
109 return getTempDirOutbound() != null;
110 }
111
112 public void cleanupTempDir(SftpClient sftpClient, String transferFileName, String tempDir)
113 {
114 String tempDirAbs = sftpClient.getAbsolutePath(endpoint.getEndpointURI().getPath() + "/" + tempDir);
115 try
116 {
117 sftpClient.changeWorkingDirectory(tempDirAbs);
118 sftpClient.deleteFile(transferFileName);
119 }
120 catch (Exception e)
121 {
122 logger.error("Could not delete the file '" + transferFileName + "' from the temp directory '"
123 + tempDirAbs + "'", e);
124 }
125 }
126
127 public long getSizeCheckWaitTime()
128 {
129 Object endpointValue = endpoint.getProperty(SftpConnector.PROPERTY_SIZE_CHECK_WAIT_TIME);
130 if (endpointValue != null)
131 {
132 return Long.valueOf((String) endpointValue);
133 }
134
135 Long connectorValue = connector.getSizeCheckWaitTime();
136 if (connectorValue != null)
137 {
138 return connectorValue;
139 }
140
141 return SIZE_CHECK_WAIT_TIME_DEFAULT;
142 }
143
144 public String getArchiveDir()
145 {
146 String endpointValue = (String) endpoint.getProperty(SftpConnector.PROPERTY_ARCHIVE_DIR);
147 if (endpointValue != null)
148 {
149 return endpointValue;
150 }
151
152 String connectorValue = connector.getArchiveDir();
153 if (connectorValue != null)
154 {
155 return connectorValue;
156 }
157
158 return null;
159 }
160
161 public String getArchiveTempReceivingDir()
162 {
163 String endpointValue = (String) endpoint.getProperty(SftpConnector.PROPERTY_ARCHIVE_TEMP_RECEIVING_DIR);
164 if (endpointValue != null)
165 {
166 return endpointValue;
167 }
168
169 String connectorValue = connector.getArchiveTempReceivingDir();
170 if (connectorValue != null)
171 {
172 return connectorValue;
173 }
174
175 return null;
176 }
177
178 public String getArchiveTempSendingDir()
179 {
180 String endpointValue = (String) endpoint.getProperty(SftpConnector.PROPERTY_ARCHIVE_TEMP_SENDING_DIR);
181 if (endpointValue != null)
182 {
183 return endpointValue;
184 }
185
186 String connectorValue = connector.getArchiveTempSendingDir();
187 if (connectorValue != null)
188 {
189 return connectorValue;
190 }
191
192 return null;
193 }
194
195 public boolean isUseTempFileTimestampSuffix()
196 {
197 Object endpointValue = endpoint.getProperty(SftpConnector.PROPERTY_USE_TEMP_FILE_TIMESTAMP_SUFFIX);
198 if (endpointValue != null)
199 {
200 return Boolean.valueOf((String) endpointValue);
201 }
202
203 Boolean connectorValue = connector.isUseTempFileTimestampSuffix();
204 if (connectorValue != null)
205 {
206 return connectorValue;
207 }
208
209 return USE_TEMP_FILE_TIMESTAMP_SUFFIX_DEFAULT;
210 }
211
212 public String getDuplicateHandling()
213 {
214 String endpointValue = (String) endpoint.getProperty(SftpConnector.PROPERTY_DUPLICATE_HANDLING);
215 if (endpointValue != null)
216 {
217 return endpointValue;
218 }
219
220 String connectorValue = connector.getDuplicateHandling();
221 if (connectorValue != null)
222 {
223 return connectorValue;
224 }
225
226 return DUPLICATE_HANDLING_DEFAULT;
227 }
228
229 public String getIdentityFile()
230 {
231 String endpointValue = (String) endpoint.getProperty(SftpConnector.PROPERTY_IDENTITY_FILE);
232 if (endpointValue != null)
233 {
234 return endpointValue;
235 }
236
237 String connectorValue = connector.getIdentityFile();
238 if (connectorValue != null)
239 {
240 return connectorValue;
241 }
242
243 return null;
244 }
245
246 public String getPassphrase()
247 {
248 String endpointValue = (String) endpoint.getProperty(SftpConnector.PROPERTY_PASS_PHRASE);
249 if (endpointValue != null)
250 {
251 return endpointValue;
252 }
253
254 String connectorValue = connector.getPassphrase();
255 if (connectorValue != null)
256 {
257 return connectorValue;
258 }
259
260 return null;
261 }
262
263
264
265
266
267
268
269
270
271
272
273
274 public void cwdToTempDirOnOutbound(SftpClient sftpClient, String endpointDir) throws IOException
275 {
276 String tempDir = getTempDirOutbound();
277 String tempDirAbs = sftpClient.getAbsolutePath(endpointDir + "/" + tempDir);
278
279
280
281 synchronized (lock)
282 {
283
284 try
285 {
286
287
288 sftpClient.changeWorkingDirectory(tempDirAbs);
289 }
290 catch (IOException e)
291 {
292 logger.info("Got an exception when trying to change the working directory to the temp dir. "
293 + "Will try to create the directory " + tempDirAbs);
294 sftpClient.changeWorkingDirectory(endpointDir);
295 sftpClient.mkdir(tempDir);
296
297 sftpClient.changeWorkingDirectory(tempDirAbs);
298 }
299 }
300 }
301
302 public boolean isKeepFileOnError()
303 {
304 Object endpointValue = endpoint.getProperty(SftpConnector.PROPERTY_KEEP_FILE_ON_ERROR);
305 if (endpointValue != null)
306 {
307 return Boolean.valueOf((String) endpointValue);
308 }
309
310 Boolean connectorValue = connector.isKeepFileOnError();
311 if (connectorValue != null)
312 {
313 return connectorValue;
314 }
315
316 return KEEP_FILE_ON_ERROR_DEFAULT;
317 }
318
319
320
321
322
323
324
325
326
327 public synchronized void copyStreamToFile(InputStream input, File destination) throws IOException
328 {
329 try
330 {
331 File folder = destination.getParentFile();
332 if (!folder.exists())
333 {
334 throw new IOException("Destination folder does not exist: " + folder);
335 }
336
337 if (!folder.canWrite())
338 {
339 throw new IOException("Destination folder is not writeable: " + folder);
340 }
341
342 FileOutputStream output = new FileOutputStream(destination);
343 try
344 {
345 IOUtils.copy(input, output);
346 }
347 finally
348 {
349 if (output != null) output.close();
350 }
351 }
352 catch (IOException ex)
353 {
354 setErrorOccurredOnInputStream(input);
355 throw ex;
356 }
357 catch (RuntimeException ex)
358 {
359 setErrorOccurredOnInputStream(input);
360 throw ex;
361 }
362 finally
363 {
364 if (input != null) input.close();
365 }
366 }
367
368 public void setErrorOccurredOnInputStream(InputStream inputStream)
369 {
370
371 if (isKeepFileOnError())
372 {
373
374
375
376
377 if (inputStream != null)
378 {
379 if (inputStream instanceof ErrorOccurredDecorator)
380 {
381
382
383
384 ((ErrorOccurredDecorator) inputStream).setErrorOccurred();
385
386 }
387 else
388 {
389 logger.warn("Class "
390 + inputStream.getClass().getName()
391 + " did not implement the 'ErrorOccurred' decorator, errorOccured=true could not be set.");
392 }
393 }
394 }
395 }
396 }