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.hadoop;
020
021import org.apache.hadoop.conf.Configuration;
022import org.apache.hadoop.fs.Path;
023import org.apache.hadoop.mapreduce.MRJobConfig;
024import org.apache.oozie.action.ActionExecutorException;
025import org.apache.oozie.service.ConfigurationService;
026import org.apache.oozie.util.XLog;
027import org.jdom.Element;
028
029import java.util.ArrayList;
030import java.util.List;
031
032public class DistcpActionExecutor extends JavaActionExecutor{
033    public static final String CONF_OOZIE_DISTCP_ACTION_MAIN_CLASS = "org.apache.oozie.action.hadoop.DistcpMain";
034    private static final String DISTCP_MAIN_CLASS_NAME = "org.apache.hadoop.tools.DistCp";
035    public static final String CLASS_NAMES = "oozie.actions.main.classnames";
036    private static final XLog LOG = XLog.getLog(DistcpActionExecutor.class);
037    public static final String DISTCP_TYPE = "distcp";
038
039    /**
040     * Comma separated list of NameNode hosts to obtain delegation token(s) for.
041     */
042    private static final String OOZIE_LAUNCHER_MAPREDUCE_JOB_HDFS_SERVERS = "oozie.launcher.mapreduce.job.hdfs-servers";
043
044    /**
045     * Comma separated list to instruct ResourceManagers on either cluster to skip delegation token renewal for NameNode hosts.
046     */
047    private static final String OOZIE_LAUNCHER_MAPREDUCE_JOB_HDFS_SERVERS_TOKEN_RENEWAL_EXCLUDE =
048            "oozie.launcher.mapreduce.job.hdfs-servers.token-renewal.exclude";
049    private static final String JOB_NAMENODES_TOKEN_RENEWAL_EXCLUDE = "mapreduce.job.hdfs-servers.token-renewal.exclude";
050
051
052    public DistcpActionExecutor() {
053        super("distcp");
054    }
055
056    @Override
057    Configuration setupActionConf(Configuration actionConf, Context context, Element actionXml, Path appPath)
058            throws ActionExecutorException {
059        actionConf = super.setupActionConf(actionConf, context, actionXml, appPath);
060        actionConf.set(JavaMain.JAVA_MAIN_CLASS, DISTCP_MAIN_CLASS_NAME);
061        return actionConf;
062    }
063
064    @Override
065    public List<Class<?>> getLauncherClasses() {
066        List<Class<?>> classes = new ArrayList<Class<?>>();
067        try {
068            classes.add(Class.forName(CONF_OOZIE_DISTCP_ACTION_MAIN_CLASS));
069        }
070        catch (ClassNotFoundException e) {
071            throw new RuntimeException("Class not found", e);
072        }
073        return classes;
074    }
075
076    /**
077     * This function returns the Action classes names from the configuration
078     *
079     * @param type This is type of the action classes
080     * @return Name of the class from the configuration
081     */
082    public static String getClassNamebyType(String type){
083        String classname = null;
084        for (String function : ConfigurationService.getStrings(CLASS_NAMES)) {
085            function = DistcpActionExecutor.Trim(function);
086            LOG.debug("class for Distcp Action: " + function);
087            String[] str = function.split("=");
088            if (str.length > 0) {
089                if(type.equalsIgnoreCase(str[0])){
090                    classname = new String(str[1]);
091                }
092            }
093        }
094        return classname;
095    }
096
097    /**
098     * To trim string
099     *
100     * @param str
101     * @return trim string
102     */
103    public static String Trim(String str) {
104        if (str != null) {
105            str = str.replaceAll("\\n", "");
106            str = str.replaceAll("\\t", "");
107            str = str.trim();
108        }
109        return str;
110    }
111
112    /**
113     * Return the sharelib name for the action.
114     *
115     * @return returns <code>distcp</code>.
116     * @param actionXml
117     */
118    @Override
119    protected String getDefaultShareLibName(Element actionXml) {
120        return "distcp";
121    }
122
123    @Override
124    protected String getLauncherMain(Configuration launcherConf, Element actionXml) {
125        return launcherConf.get(LauncherAMUtils.CONF_OOZIE_ACTION_MAIN_CLASS, CONF_OOZIE_DISTCP_ACTION_MAIN_CLASS);
126    }
127
128    /**
129     * Extracts information required for DistCp action between secure clusters (in the same or distinct Kerberos realms)
130     *
131     * @param jobconf workflow action configuration
132     */
133    @Override
134    protected void setActionTokenProperties(final Configuration jobconf) {
135        final String hdfsServers = jobconf.get(OOZIE_LAUNCHER_MAPREDUCE_JOB_HDFS_SERVERS);
136        if (hdfsServers != null) {
137            jobconf.set(MRJobConfig.JOB_NAMENODES, hdfsServers);
138            final String tokenRenewalExclude = jobconf.get(OOZIE_LAUNCHER_MAPREDUCE_JOB_HDFS_SERVERS_TOKEN_RENEWAL_EXCLUDE);
139            if (tokenRenewalExclude != null) {
140                jobconf.set(JOB_NAMENODES_TOKEN_RENEWAL_EXCLUDE, tokenRenewalExclude);
141            }
142        }
143    }
144}