Example #1
0
  protected Void call(WorkflowStore store) throws StoreException, CommandException {
    WorkflowJobBean workflow = store.getWorkflow(jobId, false);
    setLogInfo(workflow);
    WorkflowActionBean action = store.getAction(id, false);
    setLogInfo(action);
    if (action.isPending()
        && (action.getStatus() == WorkflowActionBean.Status.DONE
            || action.getStatus() == WorkflowActionBean.Status.END_RETRY
            || action.getStatus() == WorkflowActionBean.Status.END_MANUAL)) {
      if (workflow.getStatus() == WorkflowJob.Status.RUNNING) {

        ActionExecutor executor =
            Services.get().get(ActionService.class).getExecutor(action.getType());
        Configuration conf = workflow.getWorkflowInstance().getConf();
        int maxRetries = conf.getInt(OozieClient.ACTION_MAX_RETRIES, executor.getMaxRetries());
        long retryInterval =
            conf.getLong(OozieClient.ACTION_RETRY_INTERVAL, executor.getRetryInterval());
        executor.setMaxRetries(maxRetries);
        executor.setRetryInterval(retryInterval);

        if (executor != null) {
          boolean isRetry = false;
          if (action.getStatus() == WorkflowActionBean.Status.END_RETRY
              || action.getStatus() == WorkflowActionBean.Status.END_MANUAL) {
            isRetry = true;
          }
          ActionExecutorContext context =
              new ActionCommand.ActionExecutorContext(workflow, action, isRetry);
          try {

            XLog.getLog(getClass())
                .debug(
                    "End, name [{0}] type [{1}] status[{2}] external status [{3}] signal value [{4}]",
                    action.getName(),
                    action.getType(),
                    action.getStatus(),
                    action.getExternalStatus(),
                    action.getSignalValue());
            WorkflowInstance wfInstance = workflow.getWorkflowInstance();
            DagELFunctions.setActionInfo(wfInstance, action);
            workflow.setWorkflowInstance(wfInstance);
            incrActionCounter(action.getType(), 1);

            Instrumentation.Cron cron = new Instrumentation.Cron();
            cron.start();
            executor.end(context, action);
            cron.stop();
            addActionCron(action.getType(), cron);

            if (!context.isEnded()) {
              XLog.getLog(getClass())
                  .warn(
                      XLog.OPS,
                      "Action Ended, ActionExecutor [{0}] must call setEndData()",
                      executor.getType());
              action.setErrorInfo(
                  END_DATA_MISSING, "Execution Ended, but End Data Missing from Action");
              failJob(context);
              store.updateAction(action);
              store.updateWorkflow(workflow);
              return null;
            }
            action.setRetries(0);
            action.setEndTime(new Date());
            store.updateAction(action);
            store.updateWorkflow(workflow);
            Status slaStatus = null;
            switch (action.getStatus()) {
              case OK:
                slaStatus = Status.SUCCEEDED;
                break;
              case KILLED:
                slaStatus = Status.KILLED;
                break;
              case FAILED:
                slaStatus = Status.FAILED;
                break;
              case ERROR:
                XLog.getLog(getClass()).info("ERROR is considered as FAILED for SLA");
                slaStatus = Status.KILLED;
                break;
              default: // TODO: What will happen for other Action
                // status
                slaStatus = Status.FAILED;
                break;
            }
            SLADbOperations.writeStausEvent(
                action.getSlaXml(), action.getId(), store, slaStatus, SlaAppType.WORKFLOW_ACTION);
            queueCallable(new NotificationCommand(workflow, action));
            XLog.getLog(getClass())
                .debug(
                    "Queuing commands for action "
                        + id
                        + " status "
                        + action.getStatus()
                        + ", Set pending="
                        + action.getPending());
            queueCallable(new SignalCommand(workflow.getId(), id));
          } catch (ActionExecutorException ex) {
            XLog.getLog(getClass())
                .warn(
                    "Error ending action [{0}]. ErrorType [{1}], ErrorCode [{2}], Message [{3}]",
                    action.getName(), ex.getErrorType(), ex.getErrorCode(), ex.getMessage());
            action.setErrorInfo(ex.getErrorCode(), ex.getMessage());
            action.setEndTime(null);
            switch (ex.getErrorType()) {
              case TRANSIENT:
                if (!handleTransient(context, executor, WorkflowAction.Status.END_RETRY)) {
                  handleNonTransient(context, executor, WorkflowAction.Status.END_MANUAL);
                  action.setPendingAge(new Date());
                  action.setRetries(0);
                }
                action.setEndTime(null);
                break;
              case NON_TRANSIENT:
                handleNonTransient(context, executor, WorkflowAction.Status.END_MANUAL);
                action.setEndTime(null);
                break;
              case ERROR:
                handleError(context, executor, COULD_NOT_END, false, WorkflowAction.Status.ERROR);
                queueCallable(new SignalCommand(workflow.getId(), id));
                break;
              case FAILED:
                failJob(context);
                break;
            }
            store.updateAction(action);
            store.updateWorkflow(workflow);
          }
        } else {
          throw new CommandException(ErrorCode.E0802, action.getType());
        }
      } else {
        XLog.getLog(getClass())
            .warn(
                "Job state is not {0}. Skipping ActionEnd Execution",
                WorkflowJob.Status.RUNNING.toString());
      }
    } else {
      XLog.getLog(getClass())
          .debug(
              "Action pending={0}, status={1}. Skipping ActionEnd Execution",
              action.getPending(), action.getStatusStr());
    }
    return null;
  }