This project has retired. For details please refer to its
Attic page.
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
019 package org.apache.oozie.action.hadoop;
020
021 import java.util.List;
022
023 import org.apache.hadoop.conf.Configuration;
024 import org.apache.hadoop.fs.Path;
025 import org.apache.oozie.action.ActionExecutorException;
026 import org.jdom.Element;
027 import org.jdom.Namespace;
028
029 public class ShellActionExecutor extends JavaActionExecutor {
030
031 /**
032 * Config property name to set the child environment
033 */
034 public String OOZIE_LAUNCHER_CHILD_ENV = "mapred.child.env";
035
036 public ShellActionExecutor() {
037 super("shell");
038 }
039
040 @Override
041 protected List<Class> getLauncherClasses() {
042 List<Class> classes = super.getLauncherClasses();
043 // Base class of ShellMain dedicated for 'shell' action
044 classes.add(LauncherMain.class);
045 // Some utility methods used in ShelltMain
046 classes.add(MapReduceMain.class);
047 // Specific to Shell action
048 classes.add(ShellMain.class);
049 // ShellMain's inner class
050 classes.add(ShellMain.OutputWriteThread.class);
051 return classes;
052 }
053
054 @Override
055 protected String getLauncherMain(Configuration launcherConf, Element actionXml) {
056 return launcherConf.get(LauncherMapper.CONF_OOZIE_ACTION_MAIN_CLASS, ShellMain.class.getName());
057 }
058
059 @SuppressWarnings("unchecked")
060 @Override
061 Configuration setupActionConf(Configuration actionConf, Context context, Element actionXml, Path appPath)
062 throws ActionExecutorException {
063 super.setupActionConf(actionConf, context, actionXml, appPath);
064 Namespace ns = actionXml.getNamespace();
065
066 String exec = actionXml.getChild("exec", ns).getTextTrim();
067 String execName = new Path(exec).getName();
068 actionConf.set(ShellMain.CONF_OOZIE_SHELL_EXEC, execName);
069
070 // Setting Shell command's arguments
071 setListInConf("argument", actionXml, actionConf, ShellMain.CONF_OOZIE_SHELL_ARGS, false);
072 // Setting Shell command's environment variable key=value
073 setListInConf("env-var", actionXml, actionConf, ShellMain.CONF_OOZIE_SHELL_ENVS, true);
074
075 // Setting capture output flag
076 actionConf.setBoolean(ShellMain.CONF_OOZIE_SHELL_CAPTURE_OUTPUT,
077 actionXml.getChild("capture-output", ns) != null);
078
079 return actionConf;
080 }
081
082 /**
083 * This method read a list of tag from an XML element and set the
084 * Configuration accordingly
085 *
086 * @param tag
087 * @param actionXml
088 * @param actionConf
089 * @param key
090 * @param checkKeyValue
091 * @throws ActionExecutorException
092 */
093 protected void setListInConf(String tag, Element actionXml, Configuration actionConf, String key,
094 boolean checkKeyValue) throws ActionExecutorException {
095 String[] strTagValue = null;
096 Namespace ns = actionXml.getNamespace();
097 List<Element> eTags = actionXml.getChildren(tag, ns);
098 if (eTags != null && eTags.size() > 0) {
099 strTagValue = new String[eTags.size()];
100 for (int i = 0; i < eTags.size(); i++) {
101 strTagValue[i] = eTags.get(i).getTextTrim();
102 if (checkKeyValue) {
103 checkPair(strTagValue[i]);
104 }
105 }
106 }
107 MapReduceMain.setStrings(actionConf, key, strTagValue);
108 }
109
110 /**
111 * Check if the key=value pair is appropriately formatted
112 * @param pair
113 * @throws ActionExecutorException
114 */
115 private void checkPair(String pair) throws ActionExecutorException {
116 String[] varValue = pair.split("=");
117 if (varValue == null || varValue.length <= 1) {
118 throw new ActionExecutorException(ActionExecutorException.ErrorType.FAILED, "JA010",
119 "Wrong ENV format [{0}] in <env-var> , key=value format expected ", pair);
120 }
121 }
122
123 @Override
124 protected Configuration setupLauncherConf(Configuration conf, Element actionXml, Path appPath, Context context)
125 throws ActionExecutorException {
126 super.setupLauncherConf(conf, actionXml, appPath, context);
127 conf.setBoolean("mapreduce.job.complete.cancel.delegation.tokens", true);
128 addDefaultChildEnv(conf);
129 return conf;
130 }
131
132 /**
133 * This method sets the PATH to current working directory for the launched
134 * map task from where shell command will run.
135 *
136 * @param conf
137 */
138 protected void addDefaultChildEnv(Configuration conf) {
139 String envValues = "PATH=.:$PATH";
140 updateProperty(conf, OOZIE_LAUNCHER_CHILD_ENV, envValues);
141 }
142
143 /**
144 * Utility method to append the new value to any property.
145 *
146 * @param conf
147 * @param propertyName
148 * @param appendValue
149 */
150 private void updateProperty(Configuration conf, String propertyName, String appendValue) {
151 if (conf != null) {
152 String val = conf.get(propertyName, "");
153 if (val.length() > 0) {
154 val += ",";
155 }
156 val += appendValue;
157 conf.set(propertyName, val);
158 log.debug("action conf is updated with default value for property " + propertyName + ", old value :"
159 + conf.get(propertyName, "") + ", new value :" + val);
160 }
161 }
162
163 }