Package org.apache.oozie.command.wf

Source Code of org.apache.oozie.command.wf.SignalCommand

/**
* Copyright (c) 2010 Yahoo! Inc. All rights reserved.
* 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. See accompanying LICENSE file.
*/
package org.apache.oozie.command.wf;

import org.apache.hadoop.conf.Configuration;
import org.apache.oozie.client.CoordinatorAction;
import org.apache.oozie.client.WorkflowJob;
import org.apache.oozie.client.SLAEvent.SlaAppType;
import org.apache.oozie.client.SLAEvent.Status;
import org.apache.oozie.CoordinatorActionBean;
import org.apache.oozie.WorkflowActionBean;
import org.apache.oozie.WorkflowJobBean;
import org.apache.oozie.ErrorCode;
import org.apache.oozie.XException;
import org.apache.oozie.command.CommandException;
import org.apache.oozie.command.coord.CoordActionReadyCommand;
import org.apache.oozie.command.coord.CoordActionUpdateCommand;
import org.apache.oozie.coord.CoordELFunctions;
import org.apache.oozie.coord.CoordinatorJobException;
import org.apache.oozie.service.ELService;
import org.apache.oozie.service.SchemaService;
import org.apache.oozie.service.Services;
import org.apache.oozie.service.StoreService;
import org.apache.oozie.service.UUIDService;
import org.apache.oozie.service.WorkflowStoreService;
import org.apache.oozie.store.CoordinatorStore;
import org.apache.oozie.store.StoreException;
import org.apache.oozie.store.WorkflowStore;
import org.apache.oozie.workflow.WorkflowException;
import org.apache.oozie.workflow.WorkflowInstance;
import org.apache.oozie.util.ELEvaluator;
import org.apache.oozie.util.XConfiguration;
import org.apache.oozie.util.XLog;
import org.apache.oozie.util.ParamChecker;
import org.apache.oozie.util.XmlUtils;
import org.apache.oozie.util.db.SLADbOperations;
import org.apache.openjpa.lib.log.Log;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;

import java.io.StringReader;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class SignalCommand extends WorkflowCommand<Void> {

    protected static final String INSTR_SUCCEEDED_JOBS_COUNTER_NAME = "succeeded";

    private String jobId;
    private String actionId;

    protected SignalCommand(String name, int priority, String jobId) {
        super(name, name, priority, XLog.STD);
        this.jobId = ParamChecker.notEmpty(jobId, "jobId");
    }

    public SignalCommand(String jobId, String actionId) {
        super("signal", "signal", 1, XLog.STD);
        this.jobId = ParamChecker.notEmpty(jobId, "jobId");
        this.actionId = ParamChecker.notEmpty(actionId, "actionId");
    }

    @Override
    protected Void call(WorkflowStore store) throws CommandException, StoreException {

        WorkflowJobBean workflow = store.getWorkflow(jobId, false);
        setLogInfo(workflow);
        WorkflowActionBean action = null;
        boolean skipAction = false;
        if (actionId != null) {
            action = store.getAction(actionId, false);
            setLogInfo(action);
        }
        if ((action == null) || (action.isComplete() && action.isPending())) {
            try {
                if (workflow.getStatus() == WorkflowJob.Status.RUNNING
                        || workflow.getStatus() == WorkflowJob.Status.PREP) {
                    WorkflowInstance workflowInstance = workflow.getWorkflowInstance();
                    workflowInstance.setTransientVar(WorkflowStoreService.WORKFLOW_BEAN, workflow);
                    boolean completed;
                    if (action == null) {
                        if (workflow.getStatus() == WorkflowJob.Status.PREP) {
                            completed = workflowInstance.start();
                            workflow.setStatus(WorkflowJob.Status.RUNNING);
                            workflow.setStartTime(new Date());
                            workflow.setWorkflowInstance(workflowInstance);
                            // 1. Add SLA status event for WF-JOB with status
                            // STARTED
                            // 2. Add SLA registration events for all WF_ACTIONS
                            SLADbOperations.writeStausEvent(workflow.getSlaXml(), jobId, store, Status.STARTED,
                                                            SlaAppType.WORKFLOW_JOB);
                            writeSLARegistrationForAllActions(workflowInstance.getApp().getDefinition(), workflow
                                    .getUser(), workflow.getGroup(), workflow.getConf(), store);
                            queueCallable(new NotificationCommand(workflow));
                        }
                        else {
                            throw new CommandException(ErrorCode.E0801, workflow.getId());
                        }
                    }
                    else {
                        String skipVar = workflowInstance.getVar(action.getName() + WorkflowInstance.NODE_VAR_SEPARATOR
                                + ReRunCommand.TO_SKIP);
                        if (skipVar != null) {
                            skipAction = skipVar.equals("true");
                        }
                        completed = workflowInstance.signal(action.getExecutionPath(), action.getSignalValue());
                        workflow.setWorkflowInstance(workflowInstance);
                        action.resetPending();
                        if (!skipAction) {
                            action.setTransition(workflowInstance.getTransition(action.getName()));
                        }
                        store.updateAction(action);
                    }

                    if (completed) {
                        for (String actionToKillId : WorkflowStoreService.getActionsToKill(workflowInstance)) {
                            WorkflowActionBean actionToKill = store.getAction(actionToKillId, false);
                            actionToKill.setPending();
                            actionToKill.setStatus(WorkflowActionBean.Status.KILLED);
                            store.updateAction(actionToKill);
                            queueCallable(new ActionKillCommand(actionToKill.getId(), actionToKill.getType()));
                        }

                        for (String actionToFailId : WorkflowStoreService.getActionsToFail(workflowInstance)) {
                            WorkflowActionBean actionToFail = store.getAction(actionToFailId, false);
                            actionToFail.resetPending();
                            actionToFail.setStatus(WorkflowActionBean.Status.FAILED);
                            SLADbOperations.writeStausEvent(action.getSlaXml(), action.getId(), store, Status.FAILED,
                                                            SlaAppType.WORKFLOW_ACTION);
                            store.updateAction(actionToFail);
                        }

                        workflow.setStatus(WorkflowJob.Status.valueOf(workflowInstance.getStatus().toString()));
                        workflow.setEndTime(new Date());
                        workflow.setWorkflowInstance(workflowInstance);
                        Status slaStatus = Status.SUCCEEDED;
                        switch (workflow.getStatus()) {
                            case SUCCEEDED:
                                slaStatus = Status.SUCCEEDED;
                                break;
                            case KILLED:
                                slaStatus = Status.KILLED;
                                break;
                            case FAILED:
                                slaStatus = Status.FAILED;
                                break;
                            default: // TODO about SUSPENDED

                        }
                        SLADbOperations.writeStausEvent(workflow.getSlaXml(), jobId, store, slaStatus,
                                                        SlaAppType.WORKFLOW_JOB);
                        queueCallable(new NotificationCommand(workflow));
                        if (workflow.getStatus() == WorkflowJob.Status.SUCCEEDED) {
                            incrJobCounter(INSTR_SUCCEEDED_JOBS_COUNTER_NAME, 1);
                        }
                    }
                    else {
                        for (WorkflowActionBean newAction : WorkflowStoreService.getStartedActions(workflowInstance)) {
                            String skipVar = workflowInstance.getVar(newAction.getName()
                                    + WorkflowInstance.NODE_VAR_SEPARATOR + ReRunCommand.TO_SKIP);
                            boolean skipNewAction = false;
                            if (skipVar != null) {
                                skipNewAction = skipVar.equals("true");
                            }
                            if (skipNewAction) {
                                WorkflowActionBean oldAction = store.getAction(newAction.getId(), false);
                                oldAction.setPending();
                                store.updateAction(oldAction);
                                queueCallable(new SignalCommand(jobId, oldAction.getId()));
                            }
                            else {
                                newAction.setPending();
                                String actionSlaXml = getActionSLAXml(newAction.getName(), workflowInstance.getApp()
                                        .getDefinition(), workflow.getConf());
                                // System.out.println("111111 actionXml " +
                                // actionSlaXml);
                                // newAction.setSlaXml(workflow.getSlaXml());
                                newAction.setSlaXml(actionSlaXml);
                                XLog.getLog(getClass()).debug("SignalCOmmand: Name: "+ newAction.getName() +"Id: " +newAction.getId()+ " Authcode:" + newAction.getCred());
                                store.insertAction(newAction);
                                queueCallable(new ActionStartCommand(newAction.getId(), newAction.getType()));
                            }
                        }
                    }

                    store.updateWorkflow(workflow);
                    XLog.getLog(getClass()).debug(
                            "Updated the workflow status to " + workflow.getId() + "  status ="
                                    + workflow.getStatusStr());
                    if (workflow.getStatus() != WorkflowJob.Status.RUNNING
                            && workflow.getStatus() != WorkflowJob.Status.SUSPENDED) {
                        queueCallable(new CoordActionUpdateCommand(workflow));
                    }
                }
                else {
                    XLog.getLog(getClass()).warn("Workflow not RUNNING, current status [{0}]", workflow.getStatus());
                }
            }
            catch (WorkflowException ex) {
                throw new CommandException(ex);
            }
        }
        else {
            XLog.getLog(getClass()).warn(
                    "SignalCommand for action id :" + actionId + " is already processed. status=" + action.getStatus()
                            + ", Pending=" + action.isPending());
        }
        return null;
    }

    public static ELEvaluator createELEvaluatorForGroup(Configuration conf, String group) {
        ELEvaluator eval = Services.get().get(ELService.class).createEvaluator(group);
        for (Map.Entry<String, String> entry : conf) {
            eval.setVariable(entry.getKey(), entry.getValue());
        }
        return eval;
    }

    private String getActionSLAXml(String actionName, String wfXml, String wfConf) throws CommandException {
        String slaXml = null;
        // TODO need to fill-out the code
        // Get the appropriate action:slaXml and resolve that.
        try {
            // Configuration conf = new XConfiguration(new
            // StringReader(wfConf));
            Element eWfJob = XmlUtils.parseXml(wfXml);
            // String prefix = XmlUtils.getNamespacePrefix(eWfJob,
            // SchemaService.SLA_NAME_SPACE_URI);
            for (Element action : (List<Element>) eWfJob.getChildren("action", eWfJob.getNamespace())) {
                if (action.getAttributeValue("name").equals(actionName) == false) {
                    continue;
                }
                Element eSla = action.getChild("info", Namespace.getNamespace(SchemaService.SLA_NAME_SPACE_URI));
                if (eSla != null) {
                    // resolveSla(eSla, conf);
                    slaXml = XmlUtils.prettyPrint(eSla).toString();// Could use
                    // any
                    // non-null
                    // string
                    break;
                }
            }
        }
        catch (Exception e) {
            throw new CommandException(ErrorCode.E1004, e.getMessage(), e);
        }
        return slaXml;
    }

    private String resolveSla(Element eSla, Configuration conf) throws CommandException {
        String slaXml = null;
        try {
            ELEvaluator evalSla = SubmitCommand.createELEvaluatorForGroup(conf, "wf-sla-submit");
            slaXml = SubmitCommand.resolveSla(eSla, evalSla);
        }
        catch (Exception e) {
            throw new CommandException(ErrorCode.E1004, e.getMessage(), e);
        }
        return slaXml;
    }

    private void writeSLARegistrationForAllActions(String wfXml, String user, String group, String strConf,
                                                   WorkflowStore store) throws CommandException {
        try {
            Element eWfJob = XmlUtils.parseXml(wfXml);
            // String prefix = XmlUtils.getNamespacePrefix(eWfJob,
            // SchemaService.SLA_NAME_SPACE_URI);
            Configuration conf = new XConfiguration(new StringReader(strConf));
            for (Element action : (List<Element>) eWfJob.getChildren("action", eWfJob.getNamespace())) {
                Element eSla = action.getChild("info", Namespace.getNamespace(SchemaService.SLA_NAME_SPACE_URI));
                if (eSla != null) {
                    String slaXml = resolveSla(eSla, conf);
                    eSla = XmlUtils.parseXml(slaXml);
                    String actionId = Services.get().get(UUIDService.class).generateChildId(jobId,
                                                                                            action.getAttributeValue("name") + "");
                    SLADbOperations.writeSlaRegistrationEvent(eSla, store, actionId, SlaAppType.WORKFLOW_ACTION, user,
                                                              group);
                }
            }
        }
        catch (Exception e) {
            throw new CommandException(ErrorCode.E1007, "workflow:Actions " + jobId, e);
        }

    }

    @Override
    protected Void execute(WorkflowStore store) throws CommandException, StoreException {
        XLog.getLog(getClass()).debug("STARTED SignalCommand for jobid=" + jobId + ", actionId=" + actionId);
        try {
            if (lock(jobId)) {
                call(store);
            }
            else {
                queueCallable(new SignalCommand(jobId, actionId), LOCK_FAILURE_REQUEUE_INTERVAL);
                XLog.getLog(getClass()).warn("SignalCommand lock was not acquired - failed {0}", jobId);
            }
        }
        catch (InterruptedException e) {
            queueCallable(new SignalCommand(jobId, actionId), LOCK_FAILURE_REQUEUE_INTERVAL);
            XLog.getLog(getClass()).warn("SignalCommand lock not acquired - interrupted exception failed {0}", jobId);
        }
        XLog.getLog(getClass()).debug("ENDED SignalCommand for jobid=" + jobId + ", actionId=" + actionId);
        return null;
    }
}
TOP

Related Classes of org.apache.oozie.command.wf.SignalCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.