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.util; 016 017 import java.io.IOException; 018 import java.util.HashMap; 019 import java.util.Map; 020 021 import org.apache.hadoop.conf.Configuration; 022 import org.apache.hadoop.fs.FileSystem; 023 import org.apache.hadoop.fs.Path; 024 import org.apache.oozie.ErrorCode; 025 import org.apache.oozie.client.OozieClient; 026 import org.apache.oozie.client.XOozieClient; 027 import org.apache.oozie.command.CommandException; 028 import org.apache.oozie.service.HadoopAccessorException; 029 import org.apache.oozie.service.HadoopAccessorService; 030 import org.apache.oozie.service.Services; 031 032 /** 033 * Job utilities. 034 */ 035 public class JobUtils { 036 /** 037 * Normalize appPath in job conf with the provided user/group - If it's not jobs via proxy submission, after 038 * normalization appPath always points to job's Xml definition file. 039 * <p/> 040 * 041 * @param user user 042 * @param group group 043 * @param conf job configuration. 044 * @throws IOException thrown if normalization can not be done properly. 045 */ 046 public static void normalizeAppPath(String user, String group, Configuration conf) throws IOException { 047 if (user == null) { 048 throw new IllegalArgumentException("user cannot be null"); 049 } 050 051 if (group == null) { 052 throw new IllegalArgumentException("group cannot be null"); 053 } 054 055 if (conf.get(XOozieClient.IS_PROXY_SUBMISSION) != null) { // do nothing for proxy submission job; 056 return; 057 } 058 059 String wfPathStr = conf.get(OozieClient.APP_PATH); 060 String coordPathStr = conf.get(OozieClient.COORDINATOR_APP_PATH); 061 String bundlePathStr = conf.get(OozieClient.BUNDLE_APP_PATH); 062 String appPathStr = wfPathStr != null ? wfPathStr : (coordPathStr != null ? coordPathStr : bundlePathStr); 063 064 FileSystem fs = null; 065 try { 066 fs = Services.get().get(HadoopAccessorService.class).createFileSystem(user, group, new Path(appPathStr).toUri(), conf); 067 } 068 catch (HadoopAccessorException ex) { 069 throw new IOException(ex.getMessage()); 070 } 071 072 Path appPath = new Path(appPathStr); 073 String normalizedAppPathStr = appPathStr; 074 if (!fs.exists(appPath)) { 075 throw new IOException("Error: " + appPathStr + " does not exist"); 076 } 077 078 if (wfPathStr != null) { 079 conf.set(OozieClient.APP_PATH, normalizedAppPathStr); 080 } 081 else if (coordPathStr != null) { 082 conf.set(OozieClient.COORDINATOR_APP_PATH, normalizedAppPathStr); 083 } 084 else if (bundlePathStr != null) { 085 conf.set(OozieClient.BUNDLE_APP_PATH, normalizedAppPathStr); 086 } 087 } 088 089 /** 090 * This Function will parse the value of the changed values in key value manner. the change value would be 091 * key1=value1;key2=value2 092 * 093 * @param changeValue change value. 094 * @return This returns the hash with hash<[key1,value1],[key2,value2]> 095 * @throws CommandException thrown if changeValue cannot be parsed properly. 096 */ 097 public static Map<String, String> parseChangeValue(String changeValue) throws CommandException { 098 if (changeValue == null || changeValue.trim().equalsIgnoreCase("")) { 099 throw new CommandException(ErrorCode.E1015, "change value can not be empty string or null"); 100 } 101 102 Map<String, String> map = new HashMap<String, String>(); 103 104 String[] tokens = changeValue.split(";"); 105 for (String token : tokens) { 106 if (!token.contains("=")) { 107 throw new CommandException(ErrorCode.E1015, changeValue, 108 "change value must be name=value pair or name=(empty string)"); 109 } 110 111 String[] pair = token.split("="); 112 String key = pair[0]; 113 114 if (map.containsKey(key)) { 115 throw new CommandException(ErrorCode.E1015, changeValue, "can not specify repeated change values on " 116 + key); 117 } 118 119 if (pair.length == 2) { 120 map.put(key, pair[1]); 121 } 122 else if (pair.length == 1) { 123 map.put(key, ""); 124 } 125 else { 126 throw new CommandException(ErrorCode.E1015, changeValue, "elements on " + key 127 + " must be name=value pair or name=(empty string)"); 128 } 129 } 130 131 return map; 132 } 133 }