Package sos.scheduler.job

Source Code of sos.scheduler.job.JobSchedulerSCPJob

/********************************************************* begin of preamble
**
** Copyright (C) 2003-2010 Software- und Organisations-Service GmbH.
** All rights reserved.
**
** This file may be used under the terms of either the
**
**   GNU General Public License version 2.0 (GPL)
**
**   as published by the Free Software Foundation
**   http://www.gnu.org/licenses/gpl-2.0.txt and appearing in the file
**   LICENSE.GPL included in the packaging of this file.
**
** or the
** 
**   Agreement for Purchase and Licensing
**
**   as offered by Software- und Organisations-Service GmbH
**   in the respective terms of supply that ship with this file.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
********************************************************** end of preamble*/
package sos.scheduler.job;


import com.trilead.ssh2.SCPClient;
import com.trilead.ssh2.StreamGobbler;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Vector;

import sos.spooler.Order;
import sos.spooler.Variable_set;
import sos.util.SOSFile;


/**
* @author andreas.pueschel@sos-berlin.com
* @author ghassan.beydoun@sos-berlin.com
* $Id: JobSchedulerSCPJob.java 3178 2008-01-04 13:49:31Z al $
*
* see job documentation in the package jobdoc for details
*/

public class JobSchedulerSCPJob extends JobSchedulerSSHBaseJob {

   
    /** action specifies the copy direction: get, put */
    protected String action                     = "";
   
    /** list of files to be copied */
    protected String fileList                   = "";
   
    /** regular expression specifying file names for transfer */
    protected String fileSpec                   = "";
   
    /** local directory for files specified with the attribute fileSpec */
    protected String localDir                   = "";
   
    /** remote directory */
    protected String remoteDir                  = "";
   
    /** create directories if needed */
    protected boolean createDir                 = true;
   
    /** enable recursive processing of directories */
    protected boolean recursive                 = false;
   
    /** create files with explicit permissions */
    protected int permissions                   = 0;

   
    private Vector filenames                    = null;
   
   
    /**
     * Processing
     *
     */
   
    public boolean spooler_process() {

        Order order = null;
        Variable_set params = null;
        SCPClient scpClient = null;

        try {
            try { // to fetch parameters from orders that have precedence over job parameters
                params = spooler_task.params();
               
                if (spooler_task.job().order_queue() != null) {
                    order = spooler_task.order();
                    if ( order.params() != null)
                      params.merge(order.params());
                }
               
                // get basic authentication parameters
                this.getBaseParameters();
               
                if (params.value("action") != null && params.value("action").length() > 0) {
                    if (!params.value("action").equalsIgnoreCase("get") && !params.value("action").equalsIgnoreCase("put"))
                        throw new Exception("invalid action parameter [action] specified, expected get, put: " + params.value("action"));
                    this.setAction(params.value("action").toLowerCase());
                    spooler_log.info(".. parameter [action]: " + this.getAction());
                } else {
                    throw new Exception("no action parameter [action] was specified");
                }

                if (params.value("file_list") != null && params.value("file_list").length() > 0) {
                    this.setFileList(params.value("file_list"));
                    spooler_log.info(".. parameter [file_list]: " + this.getFileList());
                } else {
                    if (this.getAction().equals("get")) throw new Exception("action [get] requires filenames being specified as parameter [file_list]");
                    this.setFileList("");
                }

               if (params.value("file_spec") != null && params.value("file_spec").length() > 0) {
                   this.setFileSpec(params.value("file_spec"));
                   spooler_log.info(".. parameter [file_spec]: " + this.getFileSpec());
               } else {
                   this.setFileSpec("^(.*)$");
               }

               if (params.value("local_dir") != null && params.value("local_dir").length() > 0) {
                   this.setLocalDir(this.normalizePath(params.value("local_dir")));
                   spooler_log.info(".. parameter [local_dir]: " + this.getLocalDir());
               } else {
                   this.setLocalDir(".");
               }

               if (params.value("remote_dir") != null && params.value("remote_dir").length() > 0) {
                   this.setRemoteDir(this.normalizePath(params.value("remote_dir")));
                   spooler_log.info(".. parameter [remote_dir]: " + this.getRemoteDir());
               } else {
                   this.setRemoteDir(".");
               }

               if (params.value("create_dir") != null && params.value("create_dir").length() > 0) {
                   if (params.value("create_dir").equalsIgnoreCase("true") || params.value("create_dir").equalsIgnoreCase("yes") || params.value("create_dir").equals("1")) {
                       this.setCreateDir(true);
                   } else {
                       this.setCreateDir(false);
                   }
                   spooler_log.info(".. parameter [create_dir]: " + this.isCreateDir());
               } else {
                   this.setCreateDir(true);
               }

               if (params.value("recursive") != null && params.value("recursive").length() > 0) {
                   if (params.value("recursive").equalsIgnoreCase("true") || params.value("recursive").equalsIgnoreCase("yes") || params.value("recursive").equals("1")) {
                       this.setRecursive(true);
                   } else {
                       this.setRecursive(false);
                   }
                   spooler_log.info(".. parameter [recursive]: " + this.isRecursive());
               } else {
                   this.setRecursive(false);
               }

               if (params.value("permissions") != null && params.value("permissions").length() > 0) {
                   try {
                       this.setPermissions(Integer.parseInt(params.value("permissions")));
                       spooler_log.info(".. parameter [permissions]: " + this.getPermissions());
                   } catch (Exception e) {
                       throw new Exception("illegal octal value for parameter [permissions]: " + params.value("permissions"));  
                   }
               } else {
                   this.setPermissions(0);
               }

           } catch (Exception e) {
               throw new Exception("error occurred processing parameters: " + e.getMessage());
           }
           
       
            try { // to connect, authenticate and process files
                this.getBaseAuthentication();
               
               
                scpClient = new SCPClient(this.getSshConnection());
               
               
                File localCheckDir = new File(this.getLocalDir());
                if (!localCheckDir.exists()) {
                    if (this.isCreateDir()) {
                        try {
                            // TODO use permissions: should no explicit permissions have been set then use the default permissions of the users home directory
                            localCheckDir.mkdirs();
                        } catch (Exception e) {
                            throw new Exception("error occurred creating local directory [" + this.getLocalDir() + "]: " + e.getMessage());
                        }
                    } else {
                        throw new Exception("local directory does not exist: " + this.getLocalDir());
                    }
                }
               
               
                // we know what we do: either String or File objects are stored in this Vector
                if (this.getFileList() != null && this.getFileList().length() > 0) {
                    // list of files for get or put operations
                    this.setFilenames(new Vector(Arrays.asList(this.getFileList().split(";"))));
                } else {
                    // list of files for put operations only
                  this.setFilenames(SOSFile.getFilelist( new File(this.getLocalDir()).getAbsolutePath(), this.getFileSpec(), java.util.regex.Pattern.MULTILINE,this.isRecursive()));
                }
               
               
                int count = 0;
                for(int i=0; i<this.getFilenames().size(); i++) {
                    try {
                        String filename = null;
                       
                        if (this.getFileList() != null && this.getFileList().length() > 0) {
                            filename = (String) this.getFilenames().get(i);
                        } else {
                            filename = ((File) this.getFilenames().get(i)).getAbsolutePath();
                        }
                       
                        if (this.getAction().equals("get")) {
                            if (this.getRemoteDir() != null && !this.getRemoteDir().equals(".")
                                && !filename.startsWith("/") && !filename.startsWith(":\\", 1))
                                filename = this.getRemoteDir() + "/" + filename;
                            spooler_log.info("file to receive: " + filename);
                        } else {
                            if (this.getLocalDir() != null && !this.getLocalDir().equals(".")
                                && !filename.startsWith("/") && !filename.startsWith(":\\", 1))
                                filename = this.getLocalDir() + "/" + filename;
                            spooler_log.info("file to send: " + filename);
                        }
                        this.getFilenames().setElementAt(filename, i);
                        count++;
                   
                    } catch (Exception e) {
                        throw new Exception(e.getMessage());
                    }
                }
               
                String[] files = new String[this.getFilenames().size()];
                this.getFilenames().toArray(files);
                if (this.getAction().equals("get")) {
                    scpClient.get(files, this.getLocalDir());
                } else {
                    if (this.getPermissions() > 0) {
                      if ( isRecursive() )
                           scp_recursive(new File(this.getLocalDir()),this.getRemoteDir(), scpClient);
                      else
                      scpClient.put(files, this.getRemoteDir());
                    } else {
                      if ( isRecursive() )
                      scp_recursive(new File(this.getLocalDir()),this.getRemoteDir(), scpClient);
                      else
                          scpClient.put(files, this.getRemoteDir());
                    }
                }
               
                switch (count) {
                    case 0:     throw new Exception("no matching files found");
                    case 1:     spooler_log.info("1 file transferred"); break;
                    default:    spooler_log.info(count + " files transferred"); break;
                }
               
               
            } catch (Exception e) {
                throw new Exception("error occurred processing files: " + e.getMessage());               
            } finally {
                if (this.getSshConnection() != null) try { this.getSshConnection().close(); this.setSshConnection(null); } catch (Exception ex) {} // gracefully ignore this error
            }
           
            // return value for classic and order driven processing
            return (spooler_task.job().order_queue() != null);

        } catch (Exception e) {
        spooler_log.warn(e.getMessage());
        return false;
        }
    }


    /**
     *
     * @param sourceFile
     * @param scpClient
     * @throws Exception
     */
    private void scp_recursive(File sourceFile , String targetFile,  SCPClient scpClient)
    throws Exception {

        if (sourceFile.isDirectory()) {
          // create target directory if does not exist
          targetFile += "/" + sourceFile.getName();
            execCommand("if [ ! -d " + targetFile + " ]; then mkdir " + targetFile + "; fi");

            String[] children = sourceFile.list();
           
            for (int i=0; i<children.length; i++) {
                scp_recursive(new File(sourceFile,   children[i]), targetFile, scpClient);
            }
        } else {
          if ( this.getFileSpec() != null && this.getFileSpec().length() > 0) {
            // copy matching file only if asked
          if ( sourceFile.getName().matches(this.getFileSpec()) )
            scpClient.put(sourceFile.getAbsolutePath(), targetFile);
          } else {
            scpClient.put(sourceFile.getAbsolutePath(), targetFile);
          }
        }
    }
   
    /**
     * executes a command on thge remote host
     *
     * @param command
     * @throws Exception
     */
    private void execCommand( String command) throws Exception {
        try {
            Integer exitStatus = null;
            String exitSignal = null;
           
            spooler_log.debug5("executing remote command: " + command);
            this.setSshSession(this.getSshConnection().openSession());
            this.getSshSession().execCommand(command);

            spooler_log.debug5("output to stdout for remote command: " + command);
            InputStream stdout = new StreamGobbler(this.getSshSession().getStdout());
            BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(stdout));
            while (true) {
                String line = stdoutReader.readLine();
                if (line == null) break;
                spooler_log.info(line);
            }

            spooler_log.debug5("output to stderr for remote command: " + command);
            InputStream stderr = new StreamGobbler(this.getSshSession().getStderr());
            BufferedReader stderrReader = new BufferedReader(new InputStreamReader(stderr));
            String stderrOutput = "";
            while (true) {
                String line = stderrReader.readLine();
                if (line == null) break;
                spooler_log.debug5(line);
                stderrOutput += line + "\n";
            }
            if (stderrOutput != null && stderrOutput.length() > 0) {
                    throw new Exception("remote execution reports error: " + stderrOutput);
            }
           

            try {
                exitStatus = this.getSshSession().getExitStatus();
            } catch (Exception e) {
                spooler_log.info("could not retrieve exit status, possibly not supported by remote ssh server");
            }

            if (exitStatus != null) {
                if (!exitStatus.equals(new Integer(0))) {
                        throw new Exception("remote command terminated with exit status: " + exitStatus);
                }
            }

           
            try {
                exitSignal = this.getSshSession().getExitSignal();
            } catch (Exception e) {
                spooler_log.info("could not retrieve exit signal, possibly not supported by remote ssh server");
            }
           
            if (exitSignal != null) {
                if (exitSignal.length() > 0) {
                        throw new Exception("remote command terminated with exit signal: " + exitSignal);
                }
            }

        } catch (Exception e) {
            throw new Exception(e.getMessage());
        } finally {
            if (this.getSshSession() != null) try { this.getSshSession().close(); this.setSshSession(null); } catch (Exception ex) {} // gracefully ignore this error
        }

    }//executeCommand
   
   
    /**
     * @return Returns the fileSpec.
     */
    public String getFileSpec() {
        return fileSpec;
    }


    /**
     * @param fileSpec The fileSpec to set.
     */
    public void setFileSpec(String fileSpec) {
        this.fileSpec = fileSpec;
    }


    /**
     * @return Returns the localDir.
     */
    public String getLocalDir() {
        return localDir;
    }


    /**
     * @param localDir The localDir to set.
     */
    public void setLocalDir(String localDir) {
        this.localDir = localDir;
    }


    /**
     * @return Returns the remoteDir.
     */
    public String getRemoteDir() {
        return remoteDir;
    }


    /**
     * @param remoteDir The remoteDir to set.
     */
    public void setRemoteDir(String remoteDir) {
        this.remoteDir = remoteDir;
    }


    /**
     * @return Returns the permissions.
     */
    public int getPermissions() {
        return permissions;
    }


    /**
     * @param permissions The permissions to set.
     */
    public void setPermissions(int permissions) {
        this.permissions = permissions;
    }


    /**
     * @return Returns the action.
     */
    public String getAction() {
        return action;
    }


    /**
     * @param action The action to set.
     */
    public void setAction(String action) {
        this.action = action;
    }


    /**
     * @return Returns the fileList.
     */
    public String getFileList() {
        return fileList;
    }


    /**
     * @param fileList The fileList to set.
     */
    public void setFileList(String fileList) {
        this.fileList = fileList;
    }


    /**
     * @return Returns the createDir.
     */
    public boolean isCreateDir() {
        return createDir;
    }


    /**
     * @param createDir The createDir to set.
     */
    public void setCreateDir(boolean createDir) {
        this.createDir = createDir;
    }


    /**
     * @return Returns the filenames.
     */
    public Vector getFilenames() {
        return filenames;
    }


    /**
     * @param filenames The filenames to set.
     */
    public void setFilenames(Vector filenames) {
        this.filenames = filenames;
    }


    /**
     * @return Returns the recursive.
     */
    public boolean isRecursive() {
        return recursive;
    }


    /**
     * @param recursive The recursive to set.
     */
    public void setRecursive(boolean recursive) {
        this.recursive = recursive;
    }

}
TOP

Related Classes of sos.scheduler.job.JobSchedulerSCPJob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.