001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *      http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.oozie.action.decision;
020
021import org.apache.oozie.client.WorkflowAction;
022import org.apache.oozie.action.ActionExecutor;
023import org.apache.oozie.action.ActionExecutorException;
024import org.apache.oozie.util.XLog;
025import org.apache.oozie.util.XmlUtils;
026import org.jdom.Element;
027import org.jdom.JDOMException;
028import org.jdom.Namespace;
029
030import java.util.List;
031
032public class DecisionActionExecutor extends ActionExecutor {
033    public static final String ACTION_TYPE = "switch";
034
035    private static final String TRUE = "true";
036
037    public static final String XML_ERROR = "XML_ERROR";
038
039    private final XLog LOG = XLog.getLog(getClass());
040
041    public DecisionActionExecutor() {
042        super(ACTION_TYPE);
043    }
044
045    @SuppressWarnings("unchecked")
046    public void start(Context context, WorkflowAction action) throws ActionExecutorException {
047        LOG.info("Starting action");
048        try {
049            String confStr = action.getConf();
050            context.setStartData("-", "-", "-");
051            Element conf = XmlUtils.parseXml(confStr);
052            Namespace ns = conf.getNamespace();
053
054            String externalState = null;
055
056            for (Element eval : (List<Element>) conf.getChildren("case", ns)) {
057                if (TRUE.equals(eval.getTextTrim())) {
058                    externalState = eval.getAttributeValue("to");
059                    break;
060                }
061            }
062            if (externalState == null) {
063                Element def = conf.getChild("default", ns);
064                if (def != null) {
065                    externalState = def.getAttributeValue("to");
066                }
067            }
068
069            if (externalState == null) {
070                throw new IllegalStateException("Transition cannot be NULL");
071            }
072            // for decision we are piggybacking on external status to transfer the transition,
073            // the {@link ActionEndCommand} does the special handling of setting it as signal value.
074            context.setExecutionData(externalState, null);
075        }
076        catch (JDOMException ex) {
077            throw new ActionExecutorException(ActionExecutorException.ErrorType.FAILED, XML_ERROR, ex.getMessage(), ex);
078        }
079    }
080
081    public void end(Context context, WorkflowAction action) throws ActionExecutorException {
082        context.setEndData(WorkflowAction.Status.OK, action.getExternalStatus());
083        LOG.info("Action ended with external status [{0}]", action.getExternalStatus());
084    }
085
086    public void check(Context context, WorkflowAction action) throws ActionExecutorException {
087        throw new UnsupportedOperationException();
088    }
089
090    public void kill(Context context, WorkflowAction action) throws ActionExecutorException {
091        throw new UnsupportedOperationException();
092    }
093
094    public boolean isCompleted(String externalStatus) {
095        return true;
096    }
097
098}