001    /**
002     * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *   http://www.apache.org/licenses/LICENSE-2.0
008     *
009     *  Unless required by applicable law or agreed to in writing, software
010     *  distributed under the License is distributed on an "AS IS" BASIS,
011     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     *  See the License for the specific language governing permissions and
013     *  limitations under the License. See accompanying LICENSE file.
014     */
015    package org.apache.oozie.service;
016    
017    import org.apache.oozie.command.wf.ReRunCommand;
018    
019    import org.apache.oozie.client.WorkflowAction;
020    import org.apache.oozie.WorkflowActionBean;
021    import org.apache.oozie.WorkflowJobBean;
022    import org.apache.oozie.ErrorCode;
023    import org.apache.oozie.workflow.WorkflowException;
024    import org.apache.oozie.workflow.WorkflowInstance;
025    import org.apache.oozie.workflow.lite.ActionNodeHandler;
026    import org.apache.oozie.workflow.lite.DecisionNodeHandler;
027    import org.apache.oozie.workflow.lite.NodeHandler;
028    import org.apache.oozie.util.XLog;
029    import org.apache.oozie.util.XmlUtils;
030    import org.jdom.Element;
031    import org.jdom.JDOMException;
032    
033    import java.util.ArrayList;
034    import java.util.List;
035    
036    public abstract class LiteWorkflowStoreService extends WorkflowStoreService {
037    
038        /**
039         * Delegation method used by the Action and Decision {@link NodeHandler} on start. <p/> This method provides the
040         * necessary information to create ActionExecutors.
041         *
042         * @param context NodeHandler context.
043         * @throws WorkflowException thrown if there was an error parsing the action configuration.
044         */
045        @SuppressWarnings("unchecked")
046        protected static void liteExecute(NodeHandler.Context context) throws WorkflowException {
047            XLog log = XLog.getLog(LiteWorkflowStoreService.class);
048            String jobId = context.getProcessInstance().getId();
049            String nodeName = context.getNodeDef().getName();
050            String skipVar = context.getProcessInstance().getVar(context.getNodeDef().getName()
051                    + WorkflowInstance.NODE_VAR_SEPARATOR + ReRunCommand.TO_SKIP);
052            boolean skipAction = false;
053            if (skipVar != null) {
054                skipAction = skipVar.equals("true");
055            }
056            WorkflowActionBean action = new WorkflowActionBean();
057            String actionId = Services.get().get(UUIDService.class).generateChildId(jobId, nodeName);
058            if (!skipAction) {
059                String nodeConf = context.getNodeDef().getConf();
060                String executionPath = context.getExecutionPath();
061    
062                String actionType;
063                try {
064                    Element element = XmlUtils.parseXml(nodeConf);
065                    actionType = element.getName();
066                    nodeConf = XmlUtils.prettyPrint(element).toString();
067                }
068                catch (JDOMException ex) {
069                    throw new WorkflowException(ErrorCode.E0700, ex.getMessage(), ex);
070                }
071    
072                log.debug(" Creating action for node [{0}]", nodeName);
073                action.setType(actionType);
074                action.setExecutionPath(executionPath);
075                action.setConf(nodeConf);
076                action.setLogToken(((WorkflowJobBean) context.getTransientVar(WORKFLOW_BEAN)).getLogToken());
077                action.setStatus(WorkflowAction.Status.PREP);
078                action.setJobId(jobId);
079            }
080            action.setName(nodeName);
081            action.setId(actionId);
082            context.setVar(nodeName + WorkflowInstance.NODE_VAR_SEPARATOR + ACTION_ID, actionId);
083            List list = (List) context.getTransientVar(ACTIONS_TO_START);
084            if (list == null) {
085                list = new ArrayList();
086                context.setTransientVar(ACTIONS_TO_START, list);
087            }
088            list.add(action);
089        }
090    
091        /**
092         * Delegation method used when failing actions. <p/>
093         *
094         * @param context NodeHandler context.
095         */
096        @SuppressWarnings("unchecked")
097        protected static void liteFail(NodeHandler.Context context) {
098            liteTerminate(context, ACTIONS_TO_FAIL);
099        }
100    
101        /**
102         * Delegation method used when killing actions. <p/>
103         *
104         * @param context NodeHandler context.
105         */
106        @SuppressWarnings("unchecked")
107        protected static void liteKill(NodeHandler.Context context) {
108            liteTerminate(context, ACTIONS_TO_KILL);
109        }
110    
111        /**
112         * Used to terminate jobs - FAIL or KILL. <p/>
113         *
114         * @param context NodeHandler context.
115         * @param transientVar The transient variable name.
116         */
117        @SuppressWarnings("unchecked")
118        private static void liteTerminate(NodeHandler.Context context, String transientVar) {
119            List<String> list = (List<String>) context.getTransientVar(transientVar);
120            if (list == null) {
121                list = new ArrayList<String>();
122                context.setTransientVar(transientVar, list);
123            }
124            list.add(context.getVar(context.getNodeDef().getName() + WorkflowInstance.NODE_VAR_SEPARATOR + ACTION_ID));
125        }
126    
127        // wires workflow lib action execution with Oozie Dag
128        public static class LiteActionHandler extends ActionNodeHandler {
129    
130            @Override
131            public void start(Context context) throws WorkflowException {
132                liteExecute(context);
133            }
134    
135            public void end(Context context) {
136            }
137    
138            public void kill(Context context) {
139                liteKill(context);
140            }
141    
142            public void fail(Context context) {
143                liteFail(context);
144            }
145        }
146    
147        // wires workflow lib decision execution with Oozie Dag
148        public static class LiteDecisionHandler extends DecisionNodeHandler {
149    
150            @Override
151            public void start(Context context) throws WorkflowException {
152                liteExecute(context);
153            }
154    
155            public void end(Context context) {
156            }
157    
158            public void kill(Context context) {
159                liteKill(context);
160            }
161    
162            public void fail(Context context) {
163                liteFail(context);
164            }
165        }
166    }