]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/RemoteExec.java
SLC Unit
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.simple / src / main / java / org / argeo / slc / jsch / RemoteExec.java
index 39305fcc4760e9c3e55cb45c06cf2e68f91dab18..691d0d63329914e6366d6409517c8a5e5152a2f7 100644 (file)
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.slc.jsch;
 
 import java.io.BufferedReader;
@@ -16,6 +31,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 
+import org.apache.commons.exec.ExecuteStreamHandler;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -50,6 +66,9 @@ public class RemoteExec extends AbstractJschTask {
 
        private String user;
 
+       private ExecuteStreamHandler streamHandler = null;
+
+       private Integer lastExitStatus = null;
        /**
         * If set, stdout is written to it as a list of lines. Cleared before each
         * run.
@@ -58,6 +77,14 @@ public class RemoteExec extends AbstractJschTask {
        private Boolean logEvenIfStdOutLines = false;
        private Boolean quiet = false;
 
+       public RemoteExec() {
+       }
+
+       public RemoteExec(SshTarget sshTarget, String cmd) {
+               setSshTarget(sshTarget);
+               setCommand(cmd);
+       }
+
        public void run(Session session) {
                List<String> commandsToUse = new ArrayList<String>(commands);
                String commandToUse = command;
@@ -82,8 +109,8 @@ public class RemoteExec extends AbstractJschTask {
                                throw new SlcException("Cannot specify commands and script");
                        BufferedReader reader = null;
                        try {
-                               reader = new BufferedReader(new InputStreamReader(script
-                                               .getInputStream()));
+                               reader = new BufferedReader(new InputStreamReader(
+                                               script.getInputStream()));
                                String line = null;
                                while ((line = reader.readLine()) != null) {
                                        if (!StringUtils.hasText(line))
@@ -228,29 +255,24 @@ public class RemoteExec extends AbstractJschTask {
                        // Standard Error
                        readStdErr(channel);
 
-                       if (log.isDebugEnabled())
-                               log.debug("Run '" + command + "' on " + getSshTarget() + "...");
+                       if (log.isTraceEnabled())
+                               log.trace("Run '" + command + "' on " + getSshTarget() + "...");
                        channel.connect();
 
-                       if (stdIn != null) {
-                               Thread stdInThread = new Thread("Stdin " + getSshTarget()) {
-                                       @Override
-                                       public void run() {
-                                               OutputStream out = null;
-                                               try {
-                                                       out = channel.getOutputStream();
-                                                       IOUtils.copy(stdIn.getInputStream(), out);
-                                               } catch (IOException e) {
-                                                       throw new SlcException("Cannot write stdin on "
-                                                                       + getSshTarget(), e);
-                                               } finally {
-                                                       IOUtils.closeQuietly(out);
-                                               }
+                       readStdIn(channel);
+                       readStdOut(channel);
+
+                       if (streamHandler != null) {
+                               streamHandler.start();
+                               while (!channel.isClosed()) {
+                                       try {
+                                               Thread.sleep(100);
+                                       } catch (Exception e) {
+                                               break;
                                        }
-                               };
-                               stdInThread.start();
+                               }
                        }
-                       readStdOut(channel);
+
                        checkExitStatus(channel);
                        channel.disconnect();
                } catch (Exception e) {
@@ -259,76 +281,117 @@ public class RemoteExec extends AbstractJschTask {
                }
        }
 
-       protected void readStdErr(final ChannelExec channel) {
-               new Thread("stderr " + getSshTarget()) {
-                       public void run() {
-                               BufferedReader stdErr = null;
+       protected void readStdOut(Channel channel) {
+               try {
+                       if (stdOut != null) {
+                               OutputStream localStdOut = createOutputStream(stdOut);
                                try {
-                                       InputStream in = channel.getErrStream();
-                                       stdErr = new BufferedReader(new InputStreamReader(in));
+                                       IOUtils.copy(channel.getInputStream(), localStdOut);
+                               } finally {
+                                       IOUtils.closeQuietly(localStdOut);
+                               }
+                       } else if (streamHandler != null) {
+                               if (channel.getInputStream() != null)
+                                       streamHandler.setProcessOutputStream(channel
+                                                       .getInputStream());
+                       } else {
+                               BufferedReader stdOut = null;
+                               try {
+                                       InputStream in = channel.getInputStream();
+                                       stdOut = new BufferedReader(new InputStreamReader(in));
                                        String line = null;
-                                       while ((line = stdErr.readLine()) != null) {
-                                               if (!line.trim().equals(""))
-                                                       log.error(line);
+                                       while ((line = stdOut.readLine()) != null) {
+                                               if (!line.trim().equals("")) {
+
+                                                       if (stdOutLines != null) {
+                                                               stdOutLines.add(line);
+                                                               if (logEvenIfStdOutLines && !quiet)
+                                                                       log.info(line);
+                                                       } else {
+                                                               if (!quiet)
+                                                                       log.info(line);
+                                                       }
+                                               }
                                        }
-                               } catch (IOException e) {
-                                       if (log.isDebugEnabled())
-                                               log.error("Cannot read stderr from " + getSshTarget(),
-                                                               e);
                                } finally {
-                                       IOUtils.closeQuietly(stdErr);
+                                       IOUtils.closeQuietly(stdOut);
                                }
                        }
-               }.start();
+               } catch (IOException e) {
+                       throw new SlcException("Cannot redirect stdout from "
+                                       + getSshTarget(), e);
+               }
        }
 
-       protected void readStdOut(Channel channel) {
-               if (stdOut != null) {
-                       OutputStream localStdOut = createOutputStream(stdOut);
+       protected void readStdErr(final ChannelExec channel) {
+               if (streamHandler != null) {
                        try {
-                               IOUtils.copy(channel.getInputStream(), localStdOut);
+                               streamHandler.setProcessOutputStream(channel.getErrStream());
                        } catch (IOException e) {
-                               throw new SlcException("Cannot redirect stdout", e);
-                       } finally {
-                               IOUtils.closeQuietly(localStdOut);
+                               throw new SlcException("Cannot read stderr from "
+                                               + getSshTarget(), e);
                        }
                } else {
-                       BufferedReader stdOut = null;
-                       try {
-                               InputStream in = channel.getInputStream();
-                               stdOut = new BufferedReader(new InputStreamReader(in));
-                               String line = null;
-                               while ((line = stdOut.readLine()) != null) {
-                                       if (!line.trim().equals("")) {
-
-                                               if (stdOutLines != null) {
-                                                       stdOutLines.add(line);
-                                                       if (logEvenIfStdOutLines && !quiet)
-                                                               log.info(line);
-                                               } else {
-                                                       if (!quiet)
-                                                               log.info(line);
+                       new Thread("stderr " + getSshTarget()) {
+                               public void run() {
+                                       BufferedReader stdErr = null;
+                                       try {
+                                               InputStream in = channel.getErrStream();
+                                               stdErr = new BufferedReader(new InputStreamReader(in));
+                                               String line = null;
+                                               while ((line = stdErr.readLine()) != null) {
+                                                       if (!line.trim().equals(""))
+                                                               log.error(line);
                                                }
+                                       } catch (IOException e) {
+                                               if (log.isDebugEnabled())
+                                                       log.error("Cannot read stderr from "
+                                                                       + getSshTarget(), e);
+                                       } finally {
+                                               IOUtils.closeQuietly(stdErr);
+                                       }
+                               }
+                       }.start();
+               }
+       }
+
+       protected void readStdIn(final ChannelExec channel) {
+               if (stdIn != null) {
+                       Thread stdInThread = new Thread("Stdin " + getSshTarget()) {
+                               @Override
+                               public void run() {
+                                       OutputStream out = null;
+                                       try {
+                                               out = channel.getOutputStream();
+                                               IOUtils.copy(stdIn.getInputStream(), out);
+                                       } catch (IOException e) {
+                                               throw new SlcException("Cannot write stdin on "
+                                                               + getSshTarget(), e);
+                                       } finally {
+                                               IOUtils.closeQuietly(out);
                                        }
                                }
+                       };
+                       stdInThread.start();
+               } else if (streamHandler != null) {
+                       try {
+                               streamHandler.setProcessInputStream(channel.getOutputStream());
                        } catch (IOException e) {
-                               if (log.isDebugEnabled())
-                                       log.error("Cannot read stdout from " + getSshTarget(), e);
-                       } finally {
-                               IOUtils.closeQuietly(stdOut);
+                               throw new SlcException("Cannot write stdin on "
+                                               + getSshTarget(), e);
                        }
                }
        }
 
        protected void checkExitStatus(Channel channel) {
                if (channel.isClosed()) {
-                       int exitStatus = channel.getExitStatus();
-                       if (exitStatus == 0) {
+                       lastExitStatus = channel.getExitStatus();
+                       if (lastExitStatus == 0) {
                                if (log.isTraceEnabled())
-                                       log.trace("Remote execution exit status: " + exitStatus);
+                                       log.trace("Remote execution exit status: " + lastExitStatus);
                        } else {
                                String msg = "Remote execution failed with " + " exit status: "
-                                               + exitStatus;
+                                               + lastExitStatus;
                                if (failOnBadExitStatus)
                                        throw new SlcException(msg);
                                else
@@ -355,6 +418,14 @@ public class RemoteExec extends AbstractJschTask {
                return out;
        }
 
+       public Integer getLastExitStatus() {
+               return lastExitStatus;
+       }
+
+       public void setStreamHandler(ExecuteStreamHandler executeStreamHandler) {
+               this.streamHandler = executeStreamHandler;
+       }
+
        public void setCommand(String command) {
                this.command = command;
        }