org.waarp.openr66.context.task.ExecTask.java Source code

Java tutorial

Introduction

Here is the source code for org.waarp.openr66.context.task.ExecTask.java

Source

/**
 * This file is part of Waarp Project.
 * 
 * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
 * COPYRIGHT.txt in the distribution for a full listing of individual contributors.
 * 
 * All Waarp Project is free software: you can redistribute it and/or modify it under the terms of
 * the GNU General Public License as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * 
 * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with Waarp . If not, see
 * <http://www.gnu.org/licenses/>.
 */
package org.waarp.openr66.context.task;

import java.io.File;
import java.io.IOException;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.ExecuteWatchdog;
import org.apache.commons.exec.PumpStreamHandler;
import org.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;
import org.waarp.openr66.context.ErrorCode;
import org.waarp.openr66.context.R66Result;
import org.waarp.openr66.context.R66Session;
import org.waarp.openr66.context.task.localexec.LocalExecClient;
import org.waarp.openr66.protocol.configuration.Configuration;

/**
 * Execute an external command
 * 
 * 
 * @author Frederic Bregier
 * 
 */
public class ExecTask extends AbstractTask {

    /**
     * Internal Logger
     */
    private static final WaarpLogger logger = WaarpLoggerFactory.getLogger(ExecTask.class);

    /**
     * @param argRule
     * @param delay
     * @param argTransfer
     * @param session
     */
    public ExecTask(String argRule, int delay, String argTransfer, R66Session session) {
        super(TaskType.EXEC, delay, argRule, argTransfer, session);
    }

    @Override
    public void run() {
        /*
         * First apply all replacements and format to argRule from context and argTransfer. Will
         * call exec (from first element of resulting string) with arguments as the following value
         * from the replacements. Return 0 if OK, else 1 for a warning else as an error. No change
         * should be done in the FILENAME
         */
        logger.debug("Exec with " + argRule + ":" + argTransfer + " and {}", session);
        String finalname = argRule;
        finalname = getReplacedValue(finalname, argTransfer.split(" "));
        // Check if the execution will be done through LocalExec daemon
        if (Configuration.configuration.isUseLocalExec() && useLocalExec) {
            LocalExecClient localExecClient = new LocalExecClient();
            if (localExecClient.connect()) {
                localExecClient.runOneCommand(finalname, delay, waitForValidation, futureCompletion);
                localExecClient.disconnect();
                return;
            } // else continue
        }
        // Execution is done internally
        String[] args = finalname.split(" ");
        File exec = new File(args[0]);
        if (exec.isAbsolute()) {
            if (!exec.canExecute()) {
                logger.error("Exec command is not executable: " + finalname);
                R66Result result = new R66Result(session, false, ErrorCode.CommandNotFound, session.getRunner());
                futureCompletion.setResult(result);
                futureCompletion.cancel();
                return;
            }
        }
        CommandLine commandLine = new CommandLine(args[0]);
        for (int i = 1; i < args.length; i++) {
            commandLine.addArgument(args[i]);
        }
        DefaultExecutor defaultExecutor = new DefaultExecutor();
        PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(null, null);
        defaultExecutor.setStreamHandler(pumpStreamHandler);
        int[] correctValues = { 0, 1 };
        defaultExecutor.setExitValues(correctValues);
        ExecuteWatchdog watchdog = null;
        if (delay > 0 && waitForValidation) {
            watchdog = new ExecuteWatchdog(delay);
            defaultExecutor.setWatchdog(watchdog);
        }
        if (!waitForValidation) {
            // Do not wait for validation
            futureCompletion.setSuccess();
            logger.info("Exec will start but no WAIT with {}", commandLine);
        }
        int status = -1;
        try {
            status = defaultExecutor.execute(commandLine);
        } catch (ExecuteException e) {
            if (e.getExitValue() == -559038737) {
                // Cannot run immediately so retry once
                try {
                    Thread.sleep(Configuration.RETRYINMS);
                } catch (InterruptedException e1) {
                }
                try {
                    status = defaultExecutor.execute(commandLine);
                } catch (ExecuteException e1) {
                    try {
                        pumpStreamHandler.stop();
                    } catch (IOException e2) {
                    }
                    logger.error("Exception: " + e.getMessage() + " Exec in error with " + commandLine.toString());
                    if (waitForValidation) {
                        futureCompletion.setFailure(e);
                    }
                    return;
                } catch (IOException e1) {
                    try {
                        pumpStreamHandler.stop();
                    } catch (IOException e2) {
                    }
                    logger.error("Exception: " + e.getMessage() + " Exec in error with " + commandLine.toString());
                    if (waitForValidation) {
                        futureCompletion.setFailure(e);
                    }
                    return;
                }
            } else {
                try {
                    pumpStreamHandler.stop();
                } catch (IOException e2) {
                }
                logger.error("Exception: " + e.getMessage() + " Exec in error with " + commandLine.toString());
                if (waitForValidation) {
                    futureCompletion.setFailure(e);
                }
                return;
            }
        } catch (IOException e) {
            try {
                pumpStreamHandler.stop();
            } catch (IOException e2) {
            }
            logger.error("Exception: " + e.getMessage() + " Exec in error with " + commandLine.toString());
            if (waitForValidation) {
                futureCompletion.setFailure(e);
            }
            return;
        }
        try {
            pumpStreamHandler.stop();
        } catch (IOException e2) {
        }
        if (defaultExecutor.isFailure(status) && watchdog != null && watchdog.killedProcess()) {
            // kill by the watchdoc (time out)
            logger.error("Exec is in Time Out");
            status = -1;
        }
        if (status == 0) {
            if (waitForValidation) {
                futureCompletion.setSuccess();
            }
            logger.info("Exec OK with {}", commandLine);
        } else if (status == 1) {
            logger.warn("Exec in warning with " + commandLine.toString());
            if (waitForValidation) {
                futureCompletion.setSuccess();
            }
        } else {
            logger.error("Status: " + status + " Exec in error with " + commandLine.toString());
            if (waitForValidation) {
                futureCompletion.cancel();
            }
        }
    }

}