CAMEL-8887: SFTP operations is not thread safe
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9611cc4f Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9611cc4f Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9611cc4f Branch: refs/heads/camel-2.15.x Commit: 9611cc4f32eb946de69127e5eb47146fca5d0a66 Parents: 7390018 Author: Claus Ibsen <davscl...@apache.org> Authored: Wed Aug 5 13:26:04 2015 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Wed Aug 5 13:39:38 2015 +0200 ---------------------------------------------------------------------- .../component/file/remote/SftpOperations.java | 37 ++++++++++---------- 1 file changed, 19 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/9611cc4f/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java ---------------------------------------------------------------------- diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java index dab4b8d..9790ef9 100644 --- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java +++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java @@ -65,6 +65,8 @@ import static org.apache.camel.util.ObjectHelper.isNotEmpty; /** * SFTP remote file operations + * <p/> + * The JSCH session and channel are not thread-safe so we need to synchronize access to using this operation. */ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> { private static final Logger LOG = LoggerFactory.getLogger(SftpOperations.class); @@ -91,7 +93,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> this.endpoint = (SftpEndpoint) endpoint; } - public boolean connect(RemoteFileConfiguration configuration) throws GenericFileOperationFailedException { + public synchronized boolean connect(RemoteFileConfiguration configuration) throws GenericFileOperationFailedException { if (isConnected()) { // already connected return true; @@ -370,11 +372,11 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> } } - public boolean isConnected() throws GenericFileOperationFailedException { + public synchronized boolean isConnected() throws GenericFileOperationFailedException { return session != null && session.isConnected() && channel != null && channel.isConnected(); } - public void disconnect() throws GenericFileOperationFailedException { + public synchronized void disconnect() throws GenericFileOperationFailedException { if (session != null && session.isConnected()) { session.disconnect(); } @@ -383,7 +385,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> } } - public boolean deleteFile(String name) throws GenericFileOperationFailedException { + public synchronized boolean deleteFile(String name) throws GenericFileOperationFailedException { LOG.debug("Deleting file: {}", name); try { channel.rm(name); @@ -393,7 +395,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> } } - public boolean renameFile(String from, String to) throws GenericFileOperationFailedException { + public synchronized boolean renameFile(String from, String to) throws GenericFileOperationFailedException { LOG.debug("Renaming file: {} to: {}", from, to); try { channel.rename(from, to); @@ -403,7 +405,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> } } - public boolean buildDirectory(String directory, boolean absolute) throws GenericFileOperationFailedException { + public synchronized boolean buildDirectory(String directory, boolean absolute) throws GenericFileOperationFailedException { // must normalize directory first directory = endpoint.getConfiguration().normalizePath(directory); @@ -473,7 +475,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> return success; } - public String getCurrentDirectory() throws GenericFileOperationFailedException { + public synchronized String getCurrentDirectory() throws GenericFileOperationFailedException { LOG.trace("getCurrentDirectory()"); try { String answer = channel.pwd(); @@ -484,7 +486,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> } } - public void changeCurrentDirectory(String path) throws GenericFileOperationFailedException { + public synchronized void changeCurrentDirectory(String path) throws GenericFileOperationFailedException { LOG.trace("changeCurrentDirectory({})", path); if (ObjectHelper.isEmpty(path)) { return; @@ -548,7 +550,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> } } - public void changeToParentDirectory() throws GenericFileOperationFailedException { + public synchronized void changeToParentDirectory() throws GenericFileOperationFailedException { LOG.trace("changeToParentDirectory()"); String current = getCurrentDirectory(); @@ -561,11 +563,11 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> changeCurrentDirectory(parent); } - public List<ChannelSftp.LsEntry> listFiles() throws GenericFileOperationFailedException { + public synchronized List<ChannelSftp.LsEntry> listFiles() throws GenericFileOperationFailedException { return listFiles("."); } - public List<ChannelSftp.LsEntry> listFiles(String path) throws GenericFileOperationFailedException { + public synchronized List<ChannelSftp.LsEntry> listFiles(String path) throws GenericFileOperationFailedException { LOG.trace("listFiles({})", path); if (ObjectHelper.isEmpty(path)) { // list current directory if file path is not given @@ -589,7 +591,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> } } - public boolean retrieveFile(String name, Exchange exchange) throws GenericFileOperationFailedException { + public synchronized boolean retrieveFile(String name, Exchange exchange) throws GenericFileOperationFailedException { LOG.trace("retrieveFile({})", name); if (ObjectHelper.isNotEmpty(endpoint.getLocalWorkDirectory())) { // local work directory is configured so we should store file content as files in this local directory @@ -600,8 +602,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> } } - @Override - public void releaseRetreivedFileResources(Exchange exchange) throws GenericFileOperationFailedException { + public synchronized void releaseRetreivedFileResources(Exchange exchange) throws GenericFileOperationFailedException { InputStream is = exchange.getIn().getHeader(RemoteFileComponent.REMOTE_FILE_INPUT_STREAM, InputStream.class); if (is != null) { @@ -762,7 +763,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> return true; } - public boolean storeFile(String name, Exchange exchange) throws GenericFileOperationFailedException { + public synchronized boolean storeFile(String name, Exchange exchange) throws GenericFileOperationFailedException { // must normalize name first name = endpoint.getConfiguration().normalizePath(name); @@ -926,7 +927,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> } } - public boolean existsFile(String name) throws GenericFileOperationFailedException { + public synchronized boolean existsFile(String name) throws GenericFileOperationFailedException { LOG.trace("existsFile({})", name); if (endpoint.isFastExistsCheck()) { return fastExistsFile(name); @@ -986,7 +987,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> } - public boolean sendNoop() throws GenericFileOperationFailedException { + public synchronized boolean sendNoop() throws GenericFileOperationFailedException { if (isConnected()) { try { session.sendIgnore(); @@ -999,7 +1000,7 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> return false; } - public boolean sendSiteCommand(String command) throws GenericFileOperationFailedException { + public synchronized boolean sendSiteCommand(String command) throws GenericFileOperationFailedException { // is not implemented return true; }