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;
}
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);
}
}
}
}
}
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);
}
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);
}
}
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));
}
Aggregations