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 package org.apache.oozie.coord; 019 020 import java.text.ParseException; 021 import java.util.ArrayList; 022 import java.util.Date; 023 import java.util.HashSet; 024 import java.util.List; 025 import java.util.Set; 026 027 import org.apache.hadoop.conf.Configuration; 028 import org.apache.oozie.CoordinatorActionBean; 029 import org.apache.oozie.ErrorCode; 030 import org.apache.oozie.XException; 031 import org.apache.oozie.client.OozieClient; 032 import org.apache.oozie.command.CommandException; 033 import org.apache.oozie.executor.jpa.CoordActionGetJPAExecutor; 034 import org.apache.oozie.executor.jpa.CoordJobGetActionForNominalTimeJPAExecutor; 035 import org.apache.oozie.executor.jpa.JPAExecutorException; 036 import org.apache.oozie.service.JPAService; 037 import org.apache.oozie.service.Services; 038 import org.apache.oozie.util.CoordActionsInDateRange; 039 import org.apache.oozie.util.DateUtils; 040 import org.apache.oozie.util.ParamChecker; 041 import org.jdom.Element; 042 043 public class CoordUtils { 044 public static final String HADOOP_USER = "user.name"; 045 046 public static String getDoneFlag(Element doneFlagElement) { 047 if (doneFlagElement != null) { 048 return doneFlagElement.getTextTrim(); 049 } 050 else { 051 return CoordELConstants.DEFAULT_DONE_FLAG; 052 } 053 } 054 055 public static Configuration getHadoopConf(Configuration jobConf) { 056 Configuration conf = new Configuration(); 057 ParamChecker.notNull(jobConf, "Configuration to be used for hadoop setup "); 058 String user = ParamChecker.notEmpty(jobConf.get(OozieClient.USER_NAME), OozieClient.USER_NAME); 059 conf.set(HADOOP_USER, user); 060 return conf; 061 } 062 063 /** 064 * Get the list of actions for given date ranges 065 * 066 * @param jobId coordinator job id 067 * @param scope a comma-separated list of date ranges. Each date range element is specified with two dates separated by '::' 068 * @return the list of Coordinator actions for the date range 069 * @throws CommandException thrown if failed to get coordinator actions by given date range 070 */ 071 public static List<CoordinatorActionBean> getCoordActionsFromDates(String jobId, String scope) throws CommandException { 072 JPAService jpaService = Services.get().get(JPAService.class); 073 ParamChecker.notEmpty(jobId, "jobId"); 074 ParamChecker.notEmpty(scope, "scope"); 075 076 Set<CoordinatorActionBean> actionSet = new HashSet<CoordinatorActionBean>(); 077 String[] list = scope.split(","); 078 for (String s : list) { 079 s = s.trim(); 080 // A date range is specified with two dates separated by '::' 081 if (s.contains("::")) { 082 List<CoordinatorActionBean> listOfActions; 083 try { 084 // Get list of actions within the range of date 085 listOfActions = CoordActionsInDateRange.getCoordActionsFromDateRange(jobId, s); 086 } 087 catch (XException e) { 088 throw new CommandException(e); 089 } 090 actionSet.addAll(listOfActions); 091 } 092 else { 093 try { 094 // Get action for the nominal time 095 Date date = DateUtils.parseDateOozieTZ(s.trim()); 096 CoordinatorActionBean coordAction = jpaService 097 .execute(new CoordJobGetActionForNominalTimeJPAExecutor(jobId, date)); 098 099 if (coordAction != null) { 100 actionSet.add(coordAction); 101 } 102 else { 103 throw new RuntimeException("This should never happen, Coordinator Action shouldn't be null"); 104 } 105 } 106 catch (ParseException e) { 107 throw new CommandException(ErrorCode.E0302, e); 108 } 109 catch (JPAExecutorException e) { 110 throw new CommandException(e); 111 } 112 113 } 114 } 115 116 List<CoordinatorActionBean> coordActions = new ArrayList<CoordinatorActionBean>(); 117 for (CoordinatorActionBean coordAction : actionSet) { 118 coordActions.add(coordAction); 119 } 120 return coordActions; 121 } 122 123 /** 124 * Get the list of actions for given id ranges 125 * 126 * @param jobId coordinator job id 127 * @param scope a comma-separated list of action ranges. The action range is specified with two action numbers separated by '-' 128 * @return the list of all Coordinator actions for action range 129 * @throws CommandException thrown if failed to get coordinator actions by given id range 130 */ 131 public static List<CoordinatorActionBean> getCoordActionsFromIds(String jobId, String scope) throws CommandException { 132 JPAService jpaService = Services.get().get(JPAService.class); 133 ParamChecker.notEmpty(jobId, "jobId"); 134 ParamChecker.notEmpty(scope, "scope"); 135 136 Set<String> actions = new HashSet<String>(); 137 String[] list = scope.split(","); 138 for (String s : list) { 139 s = s.trim(); 140 // An action range is specified with two actions separated by '-' 141 if (s.contains("-")) { 142 String[] range = s.split("-"); 143 // Check the format for action's range 144 if (range.length != 2) { 145 throw new CommandException(ErrorCode.E0302, "format is wrong for action's range '" + s + "', an example of correct format is 1-5"); 146 } 147 int start; 148 int end; 149 try { 150 //Get the starting and ending action numbers 151 start = Integer.parseInt(range[0].trim()); 152 end = Integer.parseInt(range[1].trim()); 153 if (start > end) { 154 throw new CommandException(ErrorCode.E0302, "format is wrong for action's range '" + s 155 + "', starting action number of the range should be less than ending action number, an example will be 1-4"); 156 } 157 } 158 catch (NumberFormatException ne) { 159 throw new CommandException(ErrorCode.E0302, ne); 160 } 161 // Add the actionIds 162 for (int i = start; i <= end; i++) { 163 actions.add(jobId + "@" + i); 164 } 165 } 166 else { 167 try { 168 Integer.parseInt(s); 169 } 170 catch (NumberFormatException ne) { 171 throw new CommandException(ErrorCode.E0302, "format is wrong for action id'" + s 172 + "'. Integer only."); 173 } 174 actions.add(jobId + "@" + s); 175 } 176 } 177 // Retrieve the actions using the corresponding actionIds 178 List<CoordinatorActionBean> coordActions = new ArrayList<CoordinatorActionBean>(); 179 for (String id : actions) { 180 CoordinatorActionBean coordAction; 181 try { 182 coordAction = jpaService.execute(new CoordActionGetJPAExecutor(id)); 183 } 184 catch (JPAExecutorException je) { 185 throw new CommandException(je); 186 } 187 coordActions.add(coordAction); 188 } 189 return coordActions; 190 } 191 192 }