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