Search in sources :

Example 61 with ActionExecutorException

use of org.apache.oozie.action.ActionExecutorException in project oozie by apache.

the class ActionStartXCommand method execute.

@Override
protected ActionExecutorContext execute() throws CommandException {
    LOG.debug("STARTED ActionStartXCommand for wf actionId=" + actionId);
    Configuration conf = wfJob.getWorkflowInstance().getConf();
    int maxRetries = 0;
    long retryInterval = 0;
    boolean execSynchronous = false;
    if (!(executor instanceof ControlNodeActionExecutor)) {
        maxRetries = conf.getInt(OozieClient.ACTION_MAX_RETRIES, executor.getMaxRetries());
        retryInterval = conf.getLong(OozieClient.ACTION_RETRY_INTERVAL, executor.getRetryInterval());
    }
    executor.setMaxRetries(maxRetries);
    executor.setRetryInterval(retryInterval);
    try {
        boolean isRetry = false;
        if (wfAction.getStatus() == WorkflowActionBean.Status.START_RETRY || wfAction.getStatus() == WorkflowActionBean.Status.START_MANUAL) {
            isRetry = true;
            prepareForRetry(wfAction);
        }
        boolean isUserRetry = false;
        if (wfAction.getStatus() == WorkflowActionBean.Status.USER_RETRY) {
            isUserRetry = true;
            prepareForRetry(wfAction);
        }
        context = getContext(isRetry, isUserRetry);
        boolean caught = false;
        try {
            if (!(executor instanceof ControlNodeActionExecutor)) {
                String tmpActionConf = XmlUtils.removeComments(wfAction.getConf());
                String actionConf = context.getELEvaluator().evaluate(tmpActionConf, String.class);
                wfAction.setConf(actionConf);
                LOG.debug("Start, name [{0}] type [{1}] configuration{E}{E}{2}{E}", wfAction.getName(), wfAction.getType(), actionConf);
            }
        } catch (ELEvaluationException ex) {
            caught = true;
            throw new ActionExecutorException(ActionExecutorException.ErrorType.TRANSIENT, EL_EVAL_ERROR, ex.getMessage(), ex);
        } catch (ELException ex) {
            caught = true;
            context.setErrorInfo(EL_ERROR, ex.getMessage());
            LOG.warn("ELException in ActionStartXCommand ", ex.getMessage(), ex);
            handleError(context, wfJob, wfAction);
        } catch (org.jdom.JDOMException je) {
            caught = true;
            context.setErrorInfo("ParsingError", je.getMessage());
            LOG.warn("JDOMException in ActionStartXCommand ", je.getMessage(), je);
            handleError(context, wfJob, wfAction);
        } catch (Exception ex) {
            caught = true;
            context.setErrorInfo(EL_ERROR, ex.getMessage());
            LOG.warn("Exception in ActionStartXCommand ", ex.getMessage(), ex);
            handleError(context, wfJob, wfAction);
        }
        if (!caught) {
            wfAction.setErrorInfo(null, null);
            incrActionCounter(wfAction.getType(), 1);
            LOG.info("Start action [{0}] with user-retry state : userRetryCount [{1}], userRetryMax [{2}], userRetryInterval" + " [{3}]", wfAction.getId(), wfAction.getUserRetryCount(), wfAction.getUserRetryMax(), wfAction.getUserRetryInterval());
            Instrumentation.Cron cron = new Instrumentation.Cron();
            cron.start();
            // do not override starttime for retries
            if (wfAction.getStartTime() == null) {
                context.setStartTime();
            }
            context.setVar(JobUtils.getRetryKey(wfAction, JsonTags.WORKFLOW_ACTION_START_TIME), String.valueOf(new Date().getTime()));
            executor.start(context, wfAction);
            cron.stop();
            FaultInjection.activate("org.apache.oozie.command.SkipCommitFaultInjection");
            addActionCron(wfAction.getType(), cron);
            wfAction.setRetries(0);
            if (wfAction.isExecutionComplete()) {
                if (!context.isExecuted()) {
                    LOG.warn(XLog.OPS, "Action Completed, ActionExecutor [{0}] must call setExecutionData()", executor.getType());
                    wfAction.setErrorInfo(EXEC_DATA_MISSING, "Execution Complete, but Execution Data Missing from Action");
                    failJob(context);
                } else {
                    wfAction.setPending();
                    if (!(executor instanceof ControlNodeActionExecutor)) {
                        queue(new ActionEndXCommand(wfAction.getId(), wfAction.getType()));
                    } else {
                        execSynchronous = true;
                    }
                }
            } else {
                if (!context.isStarted()) {
                    LOG.warn(XLog.OPS, "Action Started, ActionExecutor [{0}] must call setStartData()", executor.getType());
                    wfAction.setErrorInfo(START_DATA_MISSING, "Execution Started, but Start Data Missing from Action");
                    failJob(context);
                } else {
                    queue(new WorkflowNotificationXCommand(wfJob, wfAction));
                }
            }
            LOG.info(XLog.STD, "[***" + wfAction.getId() + "***]" + "Action status=" + wfAction.getStatusStr());
            updateList.add(new UpdateEntry<WorkflowActionQuery>(WorkflowActionQuery.UPDATE_ACTION_START, wfAction));
            updateJobLastModified();
            // Add SLA status event (STARTED) for WF_ACTION
            SLAEventBean slaEvent = SLADbXOperations.createStatusEvent(wfAction.getSlaXml(), wfAction.getId(), Status.STARTED, SlaAppType.WORKFLOW_ACTION);
            if (slaEvent != null) {
                insertList.add(slaEvent);
            }
            LOG.info(XLog.STD, "[***" + wfAction.getId() + "***]" + "Action updated in DB!");
        }
    } catch (ActionExecutorException ex) {
        LOG.warn("Error starting action [{0}]. ErrorType [{1}], ErrorCode [{2}], Message [{3}]", wfAction.getName(), ex.getErrorType(), ex.getErrorCode(), ex.getMessage(), ex);
        wfAction.setErrorInfo(ex.getErrorCode(), ex.getMessage());
        switch(ex.getErrorType()) {
            case TRANSIENT:
                if (!handleTransient(context, executor, WorkflowAction.Status.START_RETRY)) {
                    handleNonTransient(context, executor, WorkflowAction.Status.START_MANUAL);
                    wfAction.setPendingAge(new Date());
                    wfAction.setRetries(0);
                    wfAction.setStartTime(null);
                }
                break;
            case NON_TRANSIENT:
                handleNonTransient(context, executor, WorkflowAction.Status.START_MANUAL);
                break;
            case ERROR:
                handleError(context, executor, WorkflowAction.Status.ERROR.toString(), true, WorkflowAction.Status.DONE);
                break;
            case FAILED:
                try {
                    failJob(context);
                    endWF();
                    SLAEventBean slaEvent1 = SLADbXOperations.createStatusEvent(wfAction.getSlaXml(), wfAction.getId(), Status.FAILED, SlaAppType.WORKFLOW_ACTION);
                    if (slaEvent1 != null) {
                        insertList.add(slaEvent1);
                    }
                } catch (XException x) {
                    LOG.warn("ActionStartXCommand - case:FAILED ", x.getMessage());
                }
                break;
        }
        updateList.add(new UpdateEntry<WorkflowActionQuery>(WorkflowActionQuery.UPDATE_ACTION_START, wfAction));
        updateJobLastModified();
    } finally {
        try {
            BatchQueryExecutor.getInstance().executeBatchInsertUpdateDelete(insertList, updateList, null);
            if (!(executor instanceof ControlNodeActionExecutor) && EventHandlerService.isEnabled()) {
                generateEvent(wfAction, wfJob.getUser());
            }
            if (execSynchronous) {
                // Changing to synchronous call from asynchronous queuing to prevent
                // undue delay from ::start:: to action due to queuing
                callActionEnd();
            }
        } catch (JPAExecutorException e) {
            throw new CommandException(e);
        }
    }
    LOG.debug("ENDED ActionStartXCommand for wf actionId=" + actionId + ", jobId=" + jobId);
    return null;
}
Also used : UpdateEntry(org.apache.oozie.executor.jpa.BatchQueryExecutor.UpdateEntry) Configuration(org.apache.hadoop.conf.Configuration) ActionExecutorException(org.apache.oozie.action.ActionExecutorException) Instrumentation(org.apache.oozie.util.Instrumentation) ELEvaluationException(org.apache.oozie.util.ELEvaluationException) JPAExecutorException(org.apache.oozie.executor.jpa.JPAExecutorException) XException(org.apache.oozie.XException) ControlNodeActionExecutor(org.apache.oozie.action.control.ControlNodeActionExecutor) ELException(javax.servlet.jsp.el.ELException) WorkflowActionQuery(org.apache.oozie.executor.jpa.WorkflowActionQueryExecutor.WorkflowActionQuery) CommandException(org.apache.oozie.command.CommandException) JPAExecutorException(org.apache.oozie.executor.jpa.JPAExecutorException) ActionExecutorException(org.apache.oozie.action.ActionExecutorException) ELEvaluationException(org.apache.oozie.util.ELEvaluationException) ELException(javax.servlet.jsp.el.ELException) XException(org.apache.oozie.XException) CommandException(org.apache.oozie.command.CommandException) PreconditionException(org.apache.oozie.command.PreconditionException) Date(java.util.Date) SLAEventBean(org.apache.oozie.SLAEventBean)

Example 62 with ActionExecutorException

use of org.apache.oozie.action.ActionExecutorException in project oozie by apache.

the class SqoopActionExecutor method end.

/**
 * We will gather counters from all executed action Hadoop jobs (e.g. jobs
 * that moved data, not the launcher itself) and merge them together. There
 * will be only one job most of the time. The only exception is
 * import-all-table option that will execute one job per one exported table.
 *
 * @param context Action context
 * @param action Workflow action
 * @throws ActionExecutorException
 */
@Override
public void end(Context context, WorkflowAction action) throws ActionExecutorException {
    super.end(context, action);
    JobClient jobClient = null;
    boolean exception = false;
    try {
        if (action.getStatus() == WorkflowAction.Status.OK) {
            Element actionXml = XmlUtils.parseXml(action.getConf());
            Configuration jobConf = createBaseHadoopConf(context, actionXml);
            jobClient = createJobClient(context, jobConf);
            // Cumulative counters for all Sqoop mapreduce jobs
            Counters counters = null;
            // Sqoop do not have to create mapreduce job each time
            String externalIds = action.getExternalChildIDs();
            if (externalIds != null && !externalIds.trim().isEmpty()) {
                String[] jobIds = externalIds.split(",");
                for (String jobId : jobIds) {
                    RunningJob runningJob = jobClient.getJob(JobID.forName(jobId));
                    if (runningJob == null) {
                        throw new ActionExecutorException(ActionExecutorException.ErrorType.FAILED, "SQOOP001", "Unknown hadoop job [{0}] associated with action [{1}].  Failing this action!", action.getExternalId(), action.getId());
                    }
                    Counters taskCounters = runningJob.getCounters();
                    if (taskCounters != null) {
                        if (counters == null) {
                            counters = taskCounters;
                        } else {
                            counters.incrAllCounters(taskCounters);
                        }
                    } else {
                        XLog.getLog(getClass()).warn("Could not find Hadoop Counters for job: [{0}]", jobId);
                    }
                }
            }
            if (counters != null) {
                ActionStats stats = new MRStats(counters);
                String statsJsonString = stats.toJSON();
                context.setVar(MapReduceActionExecutor.HADOOP_COUNTERS, statsJsonString);
                // do not store the action stats
                if (Boolean.parseBoolean(evaluateConfigurationProperty(actionXml, OOZIE_ACTION_EXTERNAL_STATS_WRITE, "true")) && (statsJsonString.getBytes().length <= getMaxExternalStatsSize())) {
                    context.setExecutionStats(statsJsonString);
                    LOG.debug("Printing stats for sqoop action as a JSON string : [{0}]", statsJsonString);
                }
            } else {
                context.setVar(MapReduceActionExecutor.HADOOP_COUNTERS, "");
                XLog.getLog(getClass()).warn("Can't find any associated Hadoop job counters");
            }
        }
    } catch (Exception ex) {
        exception = true;
        throw convertException(ex);
    } finally {
        if (jobClient != null) {
            try {
                jobClient.close();
            } catch (Exception e) {
                if (exception) {
                    LOG.error("JobClient error: ", e);
                } else {
                    throw convertException(e);
                }
            }
        }
    }
}
Also used : XConfiguration(org.apache.oozie.util.XConfiguration) Configuration(org.apache.hadoop.conf.Configuration) Element(org.jdom.Element) RunningJob(org.apache.hadoop.mapred.RunningJob) ActionExecutorException(org.apache.oozie.action.ActionExecutorException) Counters(org.apache.hadoop.mapred.Counters) JobClient(org.apache.hadoop.mapred.JobClient) ActionExecutorException(org.apache.oozie.action.ActionExecutorException) IOException(java.io.IOException)

Example 63 with ActionExecutorException

use of org.apache.oozie.action.ActionExecutorException in project oozie by apache.

the class SshActionExecutor method check.

/**
 * Check ssh action status.
 *
 * @param context action execution context.
 * @param action action object.
 * @throws org.apache.oozie.action.ActionExecutorException
 */
@Override
public void check(Context context, WorkflowAction action) throws ActionExecutorException {
    LOG.trace("check() start for action={0}", action.getId());
    Status status = getActionStatus(context, action);
    boolean captureOutput = false;
    try {
        Element eConf = XmlUtils.parseXml(action.getConf());
        Namespace ns = eConf.getNamespace();
        captureOutput = eConf.getChild("capture-output", ns) != null;
    } catch (JDOMException ex) {
        throw new ActionExecutorException(ActionExecutorException.ErrorType.ERROR, "ERR_XML_PARSE_FAILED", "unknown error", ex);
    }
    LOG.debug("Capture Output: {0}", captureOutput);
    if (status == Status.OK) {
        if (captureOutput) {
            String outFile = getRemoteFileName(context, action, "stdout", false, true);
            String dataCommand = SSH_COMMAND_BASE + action.getTrackerUri() + " cat " + outFile;
            LOG.debug("Ssh command [{0}]", dataCommand);
            try {
                final Process process = Runtime.getRuntime().exec(dataCommand.split("\\s"));
                final StringBuffer outBuffer = new StringBuffer();
                final StringBuffer errBuffer = new StringBuffer();
                boolean overflow = false;
                drainBuffers(process, outBuffer, errBuffer, maxLen);
                LOG.trace("outBuffer={0}", outBuffer);
                LOG.trace("errBuffer={0}", errBuffer);
                if (outBuffer.length() > maxLen) {
                    overflow = true;
                }
                if (overflow) {
                    throw new ActionExecutorException(ActionExecutorException.ErrorType.ERROR, "ERR_OUTPUT_EXCEED_MAX_LEN", "unknown error");
                }
                context.setExecutionData(status.toString(), PropertiesUtils.stringToProperties(outBuffer.toString()));
                LOG.trace("Execution data set. status={0}, properties={1}", status, PropertiesUtils.stringToProperties(outBuffer.toString()));
            } catch (Exception ex) {
                throw new ActionExecutorException(ActionExecutorException.ErrorType.ERROR, "ERR_UNKNOWN_ERROR", "unknown error", ex);
            }
        } else {
            LOG.trace("Execution data set to null. status={0}", status);
            context.setExecutionData(status.toString(), null);
        }
    } else {
        if (status == Status.ERROR) {
            LOG.warn("Execution data set to null in ERROR");
            context.setExecutionData(status.toString(), null);
        } else {
            LOG.warn("Execution data not set");
            context.setExternalStatus(status.toString());
        }
    }
    LOG.trace("check() end for action={0}", action);
}
Also used : Status(org.apache.oozie.client.WorkflowAction.Status) Element(org.jdom.Element) ActionExecutorException(org.apache.oozie.action.ActionExecutorException) JDOMException(org.jdom.JDOMException) Namespace(org.jdom.Namespace) ActionExecutorException(org.apache.oozie.action.ActionExecutorException) JDOMException(org.jdom.JDOMException) IOException(java.io.IOException)

Example 64 with ActionExecutorException

use of org.apache.oozie.action.ActionExecutorException in project oozie by apache.

the class SshActionExecutor method start.

/**
 * Start the ssh action execution.
 *
 * @param context action execution context.
 * @param action action object.
 * @throws org.apache.oozie.action.ActionExecutorException
 */
@SuppressWarnings("unchecked")
@Override
public void start(final Context context, final WorkflowAction action) throws ActionExecutorException {
    LOG.info("Starting action");
    String confStr = action.getConf();
    Element conf;
    try {
        conf = XmlUtils.parseXml(confStr);
    } catch (Exception ex) {
        throw convertException(ex);
    }
    Namespace nameSpace = conf.getNamespace();
    Element hostElement = conf.getChild("host", nameSpace);
    String hostString = hostElement.getValue().trim();
    hostString = prepareUserHost(hostString, context);
    final String host = hostString;
    final String dirLocation = execute(new Callable<String>() {

        public String call() throws Exception {
            return setupRemote(host, context, action);
        }
    });
    String runningPid = execute(new Callable<String>() {

        public String call() throws Exception {
            return checkIfRunning(host, context, action);
        }
    });
    String pid = "";
    LOG.trace("runningPid={0}", runningPid);
    if (runningPid == null) {
        final Element commandElement = conf.getChild("command", nameSpace);
        final boolean ignoreOutput = conf.getChild("capture-output", nameSpace) == null;
        boolean preserve = false;
        if (commandElement != null) {
            String[] args = null;
            // Will either have <args>, <arg>, or neither (but not both)
            List<Element> argsList = conf.getChildren("args", nameSpace);
            // Arguments in an <args> are "flattened" (spaces are delimiters)
            if (argsList != null && argsList.size() > 0) {
                StringBuilder argsString = new StringBuilder("");
                for (Element argsElement : argsList) {
                    argsString = argsString.append(argsElement.getValue()).append(" ");
                }
                args = new String[] { argsString.toString() };
            } else {
                // Arguments in an <arg> are preserved, even with spaces
                argsList = conf.getChildren("arg", nameSpace);
                if (argsList != null && argsList.size() > 0) {
                    preserve = true;
                    args = new String[argsList.size()];
                    for (int i = 0; i < argsList.size(); i++) {
                        Element argsElement = argsList.get(i);
                        args[i] = argsElement.getValue();
                        // them or escape their space (because the scripts will split them up otherwise)
                        if (args[i].contains(" ") && !(args[i].startsWith("\"") && args[i].endsWith("\"") || args[i].startsWith("'") && args[i].endsWith("'"))) {
                            args[i] = StringUtils.escapeString(args[i], '\\', ' ');
                        }
                    }
                }
            }
            final String[] argsF = args;
            final String recoveryId = context.getRecoveryId();
            final boolean preserveF = preserve;
            pid = execute(new Callable<String>() {

                @Override
                public String call() throws Exception {
                    return doExecute(host, dirLocation, commandElement.getValue(), argsF, ignoreOutput, action, recoveryId, preserveF);
                }
            });
        }
        context.setStartData(pid, host, host);
    } else {
        pid = runningPid;
        context.setStartData(pid, host, host);
        check(context, action);
    }
}
Also used : Element(org.jdom.Element) ActionExecutorException(org.apache.oozie.action.ActionExecutorException) JDOMException(org.jdom.JDOMException) IOException(java.io.IOException) Namespace(org.jdom.Namespace) Callable(java.util.concurrent.Callable)

Example 65 with ActionExecutorException

use of org.apache.oozie.action.ActionExecutorException in project oozie by apache.

the class TestFsActionExecutor method testMove.

public void testMove() throws Exception {
    FsActionExecutor ae = new FsActionExecutor();
    FileSystem fs = getFileSystem();
    Path source = new Path(getFsTestCaseDir(), "source");
    Path target = new Path(getFsTestCaseDir(), "target");
    Context context = createContext("<fs/>");
    fs.mkdirs(source);
    fs.createNewFile(new Path(source + "/newfile1"));
    fs.mkdirs(target);
    String dest = target.toUri().getPath();
    Path destPath = new Path(dest);
    ae.move(context, new Path(source + "/newfile1"), destPath, false);
    assertTrue(!fs.exists(new Path(source + "/newfile1")));
    assertTrue(fs.exists(target));
    try {
        ae.move(context, new Path(source + "/newfile1"), destPath, false);
        fail();
    } catch (ActionExecutorException ex) {
        assertEquals("FS006", ex.getErrorCode());
    }
    fs.mkdirs(source);
    fs.createNewFile(new Path(source + "/newfile"));
    Path complexTarget = new Path(target + "/a/b");
    fs.mkdirs(complexTarget);
    ae.move(context, source, complexTarget, false);
    assertTrue(fs.exists(new Path(complexTarget + "/" + source.getName())));
    fs.mkdirs(source);
    try {
        ae.move(context, source, new Path(target.toUri().getScheme() + "://foo/" + destPath), false);
        fail();
    } catch (ActionExecutorException ex) {
        assertEquals("FS007", ex.getErrorCode());
    }
    fs.delete(source, true);
    ae.move(context, source, new Path(target.toUri().getPath()), true);
    fs.mkdirs(source);
    fs.delete(target, true);
    ae.move(context, source, new Path(target.toUri().getPath()), true);
    assertTrue(!fs.exists(source));
    assertTrue(fs.exists(target));
}
Also used : Path(org.apache.hadoop.fs.Path) FileSystem(org.apache.hadoop.fs.FileSystem) ActionExecutorException(org.apache.oozie.action.ActionExecutorException)

Aggregations

ActionExecutorException (org.apache.oozie.action.ActionExecutorException)75 Path (org.apache.hadoop.fs.Path)41 IOException (java.io.IOException)39 Element (org.jdom.Element)28 URISyntaxException (java.net.URISyntaxException)27 FileSystem (org.apache.hadoop.fs.FileSystem)25 HadoopAccessorException (org.apache.oozie.service.HadoopAccessorException)24 XConfiguration (org.apache.oozie.util.XConfiguration)23 Configuration (org.apache.hadoop.conf.Configuration)20 AccessControlException (org.apache.hadoop.security.AccessControlException)20 Namespace (org.jdom.Namespace)13 WorkflowActionBean (org.apache.oozie.WorkflowActionBean)12 WorkflowJobBean (org.apache.oozie.WorkflowJobBean)12 JDOMException (org.jdom.JDOMException)12 FileNotFoundException (java.io.FileNotFoundException)10 ELEvaluationException (org.apache.oozie.util.ELEvaluationException)10 ConnectException (java.net.ConnectException)9 UnknownHostException (java.net.UnknownHostException)9 RemoteException (org.apache.hadoop.ipc.RemoteException)9 ArrayList (java.util.ArrayList)8