All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.soitoolkit.commons.mule.sftp.SftpUtil Maven / Gradle / Ivy

There is a newer version: 2.0.0-M6
Show newest version
/* 
 * Licensed to the soi-toolkit project under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The soi-toolkit project licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.soitoolkit.commons.mule.sftp;

import static org.soitoolkit.commons.mule.util.MuleUtil.getImmutableEndpoint;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.mule.api.MuleContext;
import org.mule.api.MuleException;
import org.mule.api.endpoint.EndpointURI;
import org.mule.api.endpoint.ImmutableEndpoint;
import org.mule.api.lifecycle.Lifecycle;
import org.mule.api.service.Service;
import org.mule.transport.sftp.SftpClient;
import org.mule.transport.sftp.SftpConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.soitoolkit.commons.mule.util.MiscUtil;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;

/**
 * Helper methods for the SFTP-transport.
 * TODO: These methods should be moved to the SFTP-transport's SftpUtil-class!
 * 
 * @author Magnus Larsson
 *
 */
public class SftpUtil {

	private static final Logger logger = LoggerFactory.getLogger(SftpUtil.class);

	/**
	 * Hidden constructor.
	 */
	private SftpUtil() {
		throw new UnsupportedOperationException(
				"Not allowed to create an instance of this class");
	}

	/**
	 * Initiates a list of sftp-endpoint-directories. Ensures that affected
	 * services are stopped during the initiation.
	 * 
	 * @param serviceNames
	 * @param endpointNames
	 * @param muleContext
	 * @throws Exception
	 */
	public static void initEndpointDirectories(MuleContext muleContext, String[] serviceNames, String[] endpointNames) throws Exception {

		// Stop all named services (either Flows or services
		List services = new ArrayList();
		for (String serviceName : serviceNames) {
			try {
				Lifecycle service = muleContext.getRegistry().lookupObject(serviceName);
//				logServiceStatus(service);
//				service.stop();
//				logServiceStatus(service);
				services.add(service);
			} catch (Exception e) {
				logger.error("Error '" + e.getMessage()
						+ "' occured while stopping the service " + serviceName
						+ ". Perhaps the service did not exist in the config?");
				throw e;
			}
		}

		// Now init the directory for each named endpoint, one by one
		for (String endpointName : endpointNames) {
			initEndpointDirectory(muleContext, endpointName);
		}

		// We are done, startup the services again so that the test can begin...
		for (@SuppressWarnings("unused") Lifecycle service : services) {
//			logServiceStatus(service);
//			service.start();
//			logServiceStatus(service);
		}
	}

	@SuppressWarnings("unused")
	private static void logServiceStatus(Service service) {
		System.err.println(service.getName() + " started: " + service.isStarted() + ", stopped: " + service.isStopped() + ", paused: " + service.isPaused());
	}

	/**
	 * Ensures that the directory exists and is writable by deleting the
	 * directory and then recreate it.
	 * 
	 * @param muleContext 
	 * @param endpointName
	 * @throws org.mule.api.MuleException
	 * @throws java.io.IOException
	 * @throws com.jcraft.jsch.SftpException
	 */
	public static void initEndpointDirectory(MuleContext muleContext, String endpointName) throws MuleException, IOException, SftpException {
		SftpClient sftpClient = getSftpClient(muleContext, endpointName);
		try {
			ChannelSftp channelSftp = sftpClient.getChannelSftp();
			try {
				recursiveDelete(muleContext, sftpClient, endpointName, "");
			} catch (IOException e) {
				if (logger.isErrorEnabled())
					logger.error("Failed to recursivly delete endpoint " + endpointName, e);
			}

			String path = getPathByEndpoint(muleContext, sftpClient, endpointName);
			mkDirs(channelSftp, path);
		} finally {
			sftpClient.disconnect();
			if (logger.isDebugEnabled())
				logger.debug("Done init endpoint directory: " + endpointName);
		}
	}

	
	public static String[] getFilesInEndpoint(MuleContext muleContext, String endpointName, String subDirectory) throws IOException, MuleException {
    	SftpClient sftpClient = getSftpClient(muleContext, endpointName);
        ImmutableEndpoint tEndpoint = getImmutableEndpoint(muleContext, endpointName);
        try {
      	String path = tEndpoint.getEndpointURI().getPath();
      	if (subDirectory != null) {
      		path += '/' + subDirectory;
      	}
          String[] files = getFilesInPath(sftpClient, path);
          return files;
          
        } finally {
          sftpClient.disconnect();
        }
      }

	public static String[] getFilesInPath(SftpClient sftpClient, String path) throws IOException {
      sftpClient.changeWorkingDirectory(sftpClient.getAbsolutePath(path));
      String[] files = sftpClient.listFiles();

      return files;
    }
    
	public static String getSftpFileContent(MuleContext muleContext, String endpointName, String file) throws MuleException, IOException {
    	SftpClient sftpClient = getSftpClient(muleContext, endpointName);
        ImmutableEndpoint tEndpoint = getImmutableEndpoint(muleContext, endpointName);
        try {
          	String path = tEndpoint.getEndpointURI().getPath();
            sftpClient.changeWorkingDirectory(sftpClient.getAbsolutePath(path));      	

            InputStream is = sftpClient.retrieveFile(file);
            return MiscUtil.convertStreamToString(is);

        } finally {
          sftpClient.disconnect();
        }
	}

	/*
	 * Private parts...
	 */	
	
	/**
	 * TODO: Optimize to only create not existing folders and skip trying to create already existing ones...
	 * 
	 * @param channelSftp
	 * @param path
	 */
	private static void mkDirs(ChannelSftp channelSftp, String path) {
//		System.err.println("### CREATE SFTP-PATH: " + path);
		int lastSepPos = path.lastIndexOf('/');
		if (lastSepPos > 0) {
			String parentPath = path.substring(0, lastSepPos);
			mkDirs(channelSftp, parentPath);
		}
		try {
			channelSftp.mkdir(path);
		} catch(SftpException e) {
//			System.err.println("### FAILD TO CREATE PATH FOR: " + path + ", ERROR: " + e.getMessage());			
		}
	}

	/**
	 * Returns a SftpClient that is logged in to the sftp server that the
	 * endpoint is configured against.
	 * 
	 * @param muleContext
	 * @param endpointName
	 * @return
	 * @throws IOException
	 */
	static protected SftpClient getSftpClient(MuleContext muleContext,
			String endpointName) throws IOException {
		ImmutableEndpoint endpoint = getImmutableEndpoint(muleContext,
				endpointName);
		
		try {
			SftpClient sftpClient = SftpConnectionFactory.createClient(endpoint);
			return sftpClient;
		} catch (Exception e) {
			throw new RuntimeException("Login failed", e);
		}

/*		
		EndpointURI endpointURI = endpoint.getEndpointURI();
		SftpClient sftpClient = new SftpClient(endpointURI.getHost());

		SftpConnector sftpConnector = (SftpConnector) endpoint.getConnector();

		if (sftpConnector.getIdentityFile() != null) {
			try {
				sftpClient.login(endpointURI.getUser(),
						sftpConnector.getIdentityFile(),
						sftpConnector.getPassphrase());
			} catch (Exception e) {
				throw new RuntimeException("Login failed", e);
			}
		} else {
			try {
				sftpClient.login(endpointURI.getUser(),
						endpointURI.getPassword());
			} catch (Exception e) {
				throw new RuntimeException("Login failed", e);
			}
		}
		return sftpClient;
*/
	}

	static protected String getPathByEndpoint(MuleContext muleContext, SftpClient sftpClient, String endpointName) throws IOException {
		ImmutableEndpoint endpoint = getImmutableEndpoint(muleContext, endpointName);
		EndpointURI endpointURI = endpoint.getEndpointURI();

		return sftpClient.getAbsolutePath(endpointURI.getPath());
	}

	/**
	 * Deletes a directory with all its files and sub-directories. The reason it
	 * do a "chmod 700" before the delete is that some tests changes the
	 * permission, and thus we have to restore the right to delete it...
	 * 
	 * @param muleClient
	 * @param endpointName
	 * @param relativePath
	 * @throws IOException
	 */
	static protected void recursiveDelete(MuleContext muleContext, SftpClient sftpClient, String endpointName, String relativePath) throws IOException {
		EndpointURI endpointURI = getImmutableEndpoint(muleContext, endpointName).getEndpointURI();
		String path = endpointURI.getPath() + relativePath;

		try {
			// Ensure that we can delete the current directory and the below
			// directories (if write is not permitted then delete is either)
			sftpClient.chmod(path, 00700);

			sftpClient.changeWorkingDirectory(sftpClient.getAbsolutePath(path));

			// Delete all sub-directories
			String[] directories = sftpClient.listDirectories();
			for (String directory : directories) {
				recursiveDelete(muleContext, sftpClient, endpointName,
						relativePath + "/" + directory);
			}

			// Needs to change the directory back after the recursiveDelete
			sftpClient.changeWorkingDirectory(sftpClient.getAbsolutePath(path));

			// Delete all files
			String[] files = sftpClient.listFiles();
			for (String file : files) {
				sftpClient.deleteFile(file);
			}

			// Delete the directory
			try {
				sftpClient.deleteDirectory(path);
			} catch (Exception e) {
				if (logger.isDebugEnabled())
					logger.debug("Failed delete directory " + path, e);
			}

		} catch (Exception e) {
			if (logger.isDebugEnabled())
				logger.debug("Failed to recursivly delete directory " + path, e);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy