| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| */ |
| |
| |
| package org.apache.oozie.action.hadoop; |
| |
| import java.io.File; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fs.Path; |
| import org.apache.hadoop.yarn.util.Apps; |
| import org.apache.oozie.action.ActionExecutorException; |
| import org.apache.oozie.service.ConfigurationService; |
| import org.jdom.Element; |
| import org.jdom.Namespace; |
| |
| public class ShellActionExecutor extends JavaActionExecutor { |
| |
| public ShellActionExecutor() { |
| super("shell"); |
| } |
| |
| @Override |
| public List<Class<?>> getLauncherClasses() { |
| return null; |
| } |
| |
| @Override |
| protected String getLauncherMain(Configuration launcherConf, Element actionXml) { |
| return launcherConf.get(LauncherMapper.CONF_OOZIE_ACTION_MAIN_CLASS, ShellMain.class.getName()); |
| } |
| |
| @Override |
| Configuration setupActionConf(Configuration actionConf, Context context, Element actionXml, Path appPath) |
| throws ActionExecutorException { |
| super.setupActionConf(actionConf, context, actionXml, appPath); |
| Namespace ns = actionXml.getNamespace(); |
| |
| String exec = actionXml.getChild("exec", ns).getTextTrim(); |
| String execName = new Path(exec).getName(); |
| actionConf.set(ShellMain.CONF_OOZIE_SHELL_EXEC, execName); |
| |
| // Setting Shell command's arguments |
| setListInConf("argument", actionXml, actionConf, ShellMain.CONF_OOZIE_SHELL_ARGS, false); |
| // Setting Shell command's environment variable key=value |
| setListInConf("env-var", actionXml, actionConf, ShellMain.CONF_OOZIE_SHELL_ENVS, true); |
| |
| // Setting capture output flag |
| actionConf.setBoolean(ShellMain.CONF_OOZIE_SHELL_CAPTURE_OUTPUT, actionXml.getChild("capture-output", ns) != null); |
| |
| // Setting if ShellMain should setup HADOOP_CONF_DIR |
| boolean setupHadoopConfDir = actionConf.getBoolean(ShellMain.CONF_OOZIE_SHELL_SETUP_HADOOP_CONF_DIR, |
| ConfigurationService.getBoolean(ShellMain.CONF_OOZIE_SHELL_SETUP_HADOOP_CONF_DIR)); |
| actionConf.setBoolean(ShellMain.CONF_OOZIE_SHELL_SETUP_HADOOP_CONF_DIR, setupHadoopConfDir); |
| // Setting to control if ShellMain should write log4j.properties |
| boolean writeL4J = actionConf.getBoolean(ShellMain.CONF_OOZIE_SHELL_SETUP_HADOOP_CONF_DIR_WRITE_LOG4J_PROPERTIES, |
| ConfigurationService.getBoolean(ShellMain.CONF_OOZIE_SHELL_SETUP_HADOOP_CONF_DIR_WRITE_LOG4J_PROPERTIES)); |
| actionConf.setBoolean(ShellMain.CONF_OOZIE_SHELL_SETUP_HADOOP_CONF_DIR_WRITE_LOG4J_PROPERTIES, writeL4J); |
| // Setting of content of log4j.properties, if to be written |
| if (writeL4J) { |
| String l4jContent = actionConf.get(ShellMain.CONF_OOZIE_SHELL_SETUP_HADOOP_CONF_DIR_LOG4J_CONTENT, |
| ConfigurationService.get(ShellMain.CONF_OOZIE_SHELL_SETUP_HADOOP_CONF_DIR_LOG4J_CONTENT)); |
| actionConf.set(ShellMain.CONF_OOZIE_SHELL_SETUP_HADOOP_CONF_DIR_LOG4J_CONTENT, l4jContent); |
| } |
| |
| return actionConf; |
| } |
| |
| /** |
| * This method read a list of tag from an XML element and set the |
| * Configuration accordingly |
| * |
| * @param tag |
| * @param actionXml |
| * @param actionConf |
| * @param key |
| * @param checkKeyValue |
| * @throws ActionExecutorException |
| */ |
| protected void setListInConf(String tag, Element actionXml, Configuration actionConf, String key, |
| boolean checkKeyValue) throws ActionExecutorException { |
| String[] strTagValue = null; |
| Namespace ns = actionXml.getNamespace(); |
| @SuppressWarnings("unchecked") |
| List<Element> eTags = actionXml.getChildren(tag, ns); |
| if (eTags != null && eTags.size() > 0) { |
| strTagValue = new String[eTags.size()]; |
| for (int i = 0; i < eTags.size(); i++) { |
| strTagValue[i] = eTags.get(i).getTextTrim(); |
| if (checkKeyValue) { |
| checkPair(strTagValue[i]); |
| } |
| } |
| } |
| ActionUtils.setStrings(actionConf, key, strTagValue); |
| } |
| |
| /** |
| * Check if the key=value pair is appropriately formatted |
| * @param pair |
| * @throws ActionExecutorException |
| */ |
| private void checkPair(String pair) throws ActionExecutorException { |
| String[] varValue = pair.split("="); |
| if (varValue == null || varValue.length <= 1) { |
| throw new ActionExecutorException(ActionExecutorException.ErrorType.FAILED, "JA010", |
| "Wrong ENV format [{0}] in <env-var> , key=value format expected ", pair); |
| } |
| } |
| |
| @Override |
| protected Configuration setupLauncherConf(Configuration conf, Element actionXml, Path appPath, Context context) |
| throws ActionExecutorException { |
| super.setupLauncherConf(conf, actionXml, appPath, context); |
| return conf; |
| } |
| |
| @Override |
| protected void addActionSpecificEnvVars(Map<String, String> env) { |
| Apps.setEnvFromInputString(env, "PATH=.:$PATH", File.pathSeparator); |
| } |
| |
| /** |
| * Utility method to append the new value to any property. |
| * |
| * @param conf |
| * @param propertyName |
| * @param appendValue |
| */ |
| private void updateProperty(Configuration conf, String propertyName, String appendValue) { |
| if (conf != null) { |
| String val = conf.get(propertyName, ""); |
| if (val.length() > 0) { |
| val += ","; |
| } |
| val += appendValue; |
| conf.set(propertyName, val); |
| LOG.debug("action conf is updated with default value for property " + propertyName + ", old value :" |
| + conf.get(propertyName, "") + ", new value :" + val); |
| } |
| } |
| |
| } |