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.ReRunXCommand;
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.ActionNodeDef;
026    import org.apache.oozie.workflow.lite.ActionNodeHandler;
027    import org.apache.oozie.workflow.lite.DecisionNodeHandler;
028    import org.apache.oozie.workflow.lite.NodeHandler;
029    import org.apache.oozie.util.XLog;
030    import org.apache.oozie.util.XmlUtils;
031    import org.jdom.Element;
032    import org.jdom.JDOMException;
033    
034    import java.util.ArrayList;
035    import java.util.List;
036    
037    public abstract class LiteWorkflowStoreService extends WorkflowStoreService {
038    
039        /**
040         * Delegation method used by the Action and Decision {@link NodeHandler} on start. <p/> This method provides the
041         * necessary information to create ActionExecutors.
042         *
043         * @param context NodeHandler context.
044         * @throws WorkflowException thrown if there was an error parsing the action configuration.
045         */
046        @SuppressWarnings("unchecked")
047        protected static void liteExecute(NodeHandler.Context context) throws WorkflowException {
048            XLog log = XLog.getLog(LiteWorkflowStoreService.class);
049            String jobId = context.getProcessInstance().getId();
050            String nodeName = context.getNodeDef().getName();
051            String skipVar = context.getProcessInstance().getVar(context.getNodeDef().getName()
052                    + WorkflowInstance.NODE_VAR_SEPARATOR + ReRunXCommand.TO_SKIP);
053            boolean skipAction = false;
054            if (skipVar != null) {
055                skipAction = skipVar.equals("true");
056            }
057            WorkflowActionBean action = new WorkflowActionBean();
058            String actionId = Services.get().get(UUIDService.class).generateChildId(jobId, nodeName);
059            
060            if (!skipAction) {
061                String nodeConf = context.getNodeDef().getConf();
062                String executionPath = context.getExecutionPath();
063    
064                String actionType;
065                try {
066                    Element element = XmlUtils.parseXml(nodeConf);
067                    actionType = element.getName();
068                    nodeConf = XmlUtils.prettyPrint(element).toString();
069                }
070                catch (JDOMException ex) {
071                    throw new WorkflowException(ErrorCode.E0700, ex.getMessage(), ex);
072                }
073    
074                log.debug(" Creating action for node [{0}]", nodeName);
075                action.setType(actionType);
076                action.setExecutionPath(executionPath);
077                action.setConf(nodeConf);
078                action.setLogToken(((WorkflowJobBean) context.getTransientVar(WORKFLOW_BEAN)).getLogToken());
079                action.setStatus(WorkflowAction.Status.PREP);
080                action.setJobId(jobId);
081            }
082            action.setCred(context.getNodeDef().getCred());
083            log.debug("liteExecute: Setting the Auth type for action "+context.getNodeDef().getCred() + " Name: "+context.getNodeDef().getName());
084            action.setName(nodeName);
085            action.setId(actionId);
086            context.setVar(nodeName + WorkflowInstance.NODE_VAR_SEPARATOR + ACTION_ID, actionId);
087            List list = (List) context.getTransientVar(ACTIONS_TO_START);
088            if (list == null) {
089                list = new ArrayList();
090                context.setTransientVar(ACTIONS_TO_START, list);
091            }
092            list.add(action);
093        }
094    
095        /**
096         * Delegation method used when failing actions. <p/>
097         *
098         * @param context NodeHandler context.
099         */
100        @SuppressWarnings("unchecked")
101        protected static void liteFail(NodeHandler.Context context) {
102            liteTerminate(context, ACTIONS_TO_FAIL);
103        }
104    
105        /**
106         * Delegation method used when killing actions. <p/>
107         *
108         * @param context NodeHandler context.
109         */
110        @SuppressWarnings("unchecked")
111        protected static void liteKill(NodeHandler.Context context) {
112            liteTerminate(context, ACTIONS_TO_KILL);
113        }
114    
115        /**
116         * Used to terminate jobs - FAIL or KILL. <p/>
117         *
118         * @param context NodeHandler context.
119         * @param transientVar The transient variable name.
120         */
121        @SuppressWarnings("unchecked")
122        private static void liteTerminate(NodeHandler.Context context, String transientVar) {
123            List<String> list = (List<String>) context.getTransientVar(transientVar);
124            if (list == null) {
125                list = new ArrayList<String>();
126                context.setTransientVar(transientVar, list);
127            }
128            list.add(context.getVar(context.getNodeDef().getName() + WorkflowInstance.NODE_VAR_SEPARATOR + ACTION_ID));
129        }
130    
131        // wires workflow lib action execution with Oozie Dag
132        public static class LiteActionHandler extends ActionNodeHandler {
133    
134            @Override
135            public void start(Context context) throws WorkflowException {
136                liteExecute(context);
137            }
138    
139            @Override
140            public void end(Context context) {
141            }
142    
143            @Override
144            public void kill(Context context) {
145                liteKill(context);
146            }
147    
148            @Override
149            public void fail(Context context) {
150                liteFail(context);
151            }
152        }
153    
154        // wires workflow lib decision execution with Oozie Dag
155        public static class LiteDecisionHandler extends DecisionNodeHandler {
156    
157            @Override
158            public void start(Context context) throws WorkflowException {
159                liteExecute(context);
160            }
161    
162            @Override
163            public void end(Context context) {
164            }
165    
166            @Override
167            public void kill(Context context) {
168                liteKill(context);
169            }
170    
171            @Override
172            public void fail(Context context) {
173                liteFail(context);
174            }
175        }
176    }