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; 020 021import java.util.ArrayList; 022import java.util.Collections; 023import java.util.Iterator; 024import java.util.List; 025import java.util.Properties; 026 027import org.apache.oozie.client.CoordinatorAction; 028import org.apache.oozie.client.CoordinatorJob; 029import org.apache.oozie.client.OozieClient; 030import org.apache.oozie.client.OozieClientException; 031import org.apache.oozie.client.WorkflowJob; 032import org.apache.oozie.client.rest.RestConstants; 033import org.apache.oozie.command.CommandException; 034import org.apache.oozie.coord.CoordUtils; 035import org.apache.oozie.util.XConfiguration; 036 037/** 038 * Client API to submit and manage Oozie coordinator jobs against an Oozie 039 * intance. 040 * <p/> 041 * This class is thread safe. 042 * <p/> 043 * Syntax for filter for the {@link #getJobsInfo(String)} 044 * {@link #getJobsInfo(String, int, int)} methods: 045 * <code>[NAME=VALUE][;NAME=VALUE]*</code>. 046 * <p/> 047 * Valid filter names are: 048 * <p/> 049 * <ul/> 050 * <li>name: the coordinator application name from the coordinator definition.</li> 051 * <li>user: the user that submitted the job.</li> 052 * <li>group: the group for the job.</li> 053 * <li>status: the status of the job.</li> 054 * </ul> 055 * <p/> 056 * The query will do an AND among all the filter names. The query will do an OR 057 * among all the filter values for the same name. Multiple values must be 058 * specified as different name value pairs. 059 */ 060public class LocalOozieClientCoord extends OozieClient { 061 062 private final CoordinatorEngine coordEngine; 063 064 /** 065 * Create a coordinator client for Oozie local use. 066 * <p/> 067 * 068 * @param coordEngine the engine instance to use. 069 */ 070 public LocalOozieClientCoord(CoordinatorEngine coordEngine) { 071 this.coordEngine = coordEngine; 072 } 073 074 /** 075 * Return the Oozie URL of the coordinator client instance. 076 * <p/> 077 * This URL is the base URL fo the Oozie system, with not protocol 078 * versioning. 079 * 080 * @return the Oozie URL of the coordinator client instance. 081 */ 082 @Override 083 public String getOozieUrl() { 084 return "localoozie"; 085 } 086 087 /** 088 * Return the Oozie URL used by the client and server for WS communications. 089 * <p/> 090 * This URL is the original URL plus the versioning element path. 091 * 092 * @return the Oozie URL used by the client and server for communication. 093 * @throws org.apache.oozie.client.OozieClientException thrown in the client 094 * and the server are not protocol compatible. 095 */ 096 @Override 097 public String getProtocolUrl() throws OozieClientException { 098 return "localoozie"; 099 } 100 101 /** 102 * Validate that the Oozie client and server instances are protocol 103 * compatible. 104 * 105 * @throws org.apache.oozie.client.OozieClientException thrown in the client 106 * and the server are not protocol compatible. 107 */ 108 @Override 109 public synchronized void validateWSVersion() throws OozieClientException { 110 } 111 112 /** 113 * Create an empty configuration with just the {@link #USER_NAME} set to the 114 * JVM user name and the {@link #GROUP_NAME} set to 'other'. 115 * 116 * @return an empty configuration. 117 */ 118 @Override 119 public Properties createConfiguration() { 120 Properties conf = new Properties(); 121 if (coordEngine != null) { 122 conf.setProperty(USER_NAME, coordEngine.getUser()); 123 } 124 conf.setProperty(GROUP_NAME, "users"); 125 return conf; 126 } 127 128 /** 129 * Set a HTTP header to be used in the WS requests by the coordinator 130 * instance. 131 * 132 * @param name header name. 133 * @param value header value. 134 */ 135 @Override 136 public void setHeader(String name, String value) { 137 } 138 139 /** 140 * Get the value of a set HTTP header from the coordinator instance. 141 * 142 * @param name header name. 143 * @return header value, <code>null</code> if not set. 144 */ 145 @Override 146 public String getHeader(String name) { 147 return null; 148 } 149 150 /** 151 * Remove a HTTP header from the coordinator client instance. 152 * 153 * @param name header name. 154 */ 155 @Override 156 public void removeHeader(String name) { 157 } 158 159 /** 160 * Return an iterator with all the header names set in the coordinator 161 * instance. 162 * 163 * @return header names. 164 */ 165 @Override 166 @SuppressWarnings("unchecked") 167 public Iterator<String> getHeaderNames() { 168 return Collections.EMPTY_SET.iterator(); 169 } 170 171 /** 172 * Submit a coordinator job. 173 * 174 * @param conf job configuration. 175 * @return the job Id. 176 * @throws org.apache.oozie.client.OozieClientException thrown if the job 177 * could not be submitted. 178 */ 179 @Override 180 public String submit(Properties conf) throws OozieClientException { 181 try { 182 return coordEngine.submitJob(new XConfiguration(conf), false); 183 } 184 catch (CoordinatorEngineException ex) { 185 throw new OozieClientException(ex.getErrorCode().toString(), ex); 186 } 187 } 188 189 /** 190 * Start a coordinator job. 191 * 192 * @param jobId job Id. 193 * @throws org.apache.oozie.client.OozieClientException thrown if the job 194 * could not be started. 195 */ 196 @Override 197 @Deprecated 198 public void start(String jobId) throws OozieClientException { 199 try { 200 coordEngine.start(jobId); 201 } 202 catch (CoordinatorEngineException ex) { 203 throw new OozieClientException(ex.getErrorCode().toString(), ex); 204 } 205 catch (BaseEngineException bex) { 206 throw new OozieClientException(bex.getErrorCode().toString(), bex); 207 } 208 } 209 210 /** 211 * Submit and start a coordinator job. 212 * 213 * @param conf job configuration. 214 * @return the job Id. 215 * @throws org.apache.oozie.client.OozieClientException thrown if the job 216 * could not be submitted. 217 */ 218 @Override 219 public String run(Properties conf) throws OozieClientException { 220 try { 221 return coordEngine.submitJob(new XConfiguration(conf), true); 222 } 223 catch (CoordinatorEngineException ex) { 224 throw new OozieClientException(ex.getErrorCode().toString(), ex); 225 } 226 } 227 228 /** 229 * Rerun a workflow job. 230 * 231 * @param jobId job Id to rerun. 232 * @param conf configuration information for the rerun. 233 * @throws org.apache.oozie.client.OozieClientException thrown if the job 234 * could not be started. 235 */ 236 @Override 237 @Deprecated 238 public void reRun(String jobId, Properties conf) throws OozieClientException { 239 throw new OozieClientException(ErrorCode.E0301.toString(), "no-op"); 240 } 241 242 /** 243 * Rerun coordinator actions. 244 * 245 * @param jobId coordinator jobId 246 * @param rerunType rerun type 'date' if -date is used, 'action-id' if 247 * -action is used 248 * @param scope rerun scope for date or actionIds 249 * @param refresh true if -refresh is given in command option 250 * @param noCleanup true if -nocleanup is given in command option 251 * @throws OozieClientException 252 */ 253 @Override 254 public List<CoordinatorAction> reRunCoord(String jobId, String rerunType, String scope, boolean refresh, 255 boolean noCleanup) throws OozieClientException { 256 return getCoordinatorActions(jobId, rerunType, scope, refresh, noCleanup, false); 257 } 258 259 /** 260 * Rerun coordinator actions with failed option. 261 * 262 * @param jobId coordinator jobId 263 * @param rerunType rerun type 'date' if -date is used, 'action-id' if 264 * -action is used 265 * @param scope rerun scope for date or actionIds 266 * @param refresh true if -refresh is given in command option 267 * @param noCleanup true if -nocleanup is given in command option 268 * @param failed true if -failed is given in command option 269 * @throws OozieClientException 270 */ 271 @Override 272 public List<CoordinatorAction> reRunCoord(String jobId, String rerunType, String scope, boolean refresh, 273 boolean noCleanup, boolean failed) throws OozieClientException { 274 return getCoordinatorActions(jobId, rerunType, scope, refresh, noCleanup, failed); 275 } 276 277 private List<CoordinatorAction> getCoordinatorActions(String jobId, String rerunType, String scope, boolean refresh, 278 boolean noCleanup, boolean failed) throws OozieClientException { 279 try { 280 if (!(rerunType.equals(RestConstants.JOB_COORD_SCOPE_DATE) || rerunType 281 .equals(RestConstants.JOB_COORD_SCOPE_ACTION))) { 282 throw new CommandException(ErrorCode.E1018, "date or action expected."); 283 } 284 CoordinatorActionInfo coordInfo = coordEngine.reRun(jobId, rerunType, scope, Boolean.valueOf(refresh), 285 Boolean.valueOf(noCleanup), Boolean.valueOf(failed)); 286 List<CoordinatorActionBean> actionBeans; 287 if (coordInfo != null) { 288 actionBeans = coordInfo.getCoordActions(); 289 } 290 else { 291 actionBeans = CoordUtils.getCoordActions(rerunType, jobId, scope, false); 292 } 293 List<CoordinatorAction> actions = new ArrayList<CoordinatorAction>(); 294 for (CoordinatorActionBean actionBean : actionBeans) { 295 actions.add(actionBean); 296 } 297 return actions; 298 } 299 catch(CommandException ce){ 300 throw new OozieClientException(ce.getErrorCode().toString(), ce); 301 } 302 catch (BaseEngineException ex) { 303 throw new OozieClientException(ex.getErrorCode().toString(), ex); 304 } 305 } 306 307 /** 308 * Suspend a coordinator job. 309 * 310 * @param jobId job Id. 311 * @throws org.apache.oozie.client.OozieClientException thrown if the job 312 * could not be suspended. 313 */ 314 @Override 315 public void suspend(String jobId) throws OozieClientException { 316 try { 317 coordEngine.suspend(jobId); 318 } 319 catch (CoordinatorEngineException ex) { 320 throw new OozieClientException(ex.getErrorCode().toString(), ex); 321 } 322 } 323 324 /** 325 * Resume a coordinator job. 326 * 327 * @param jobId job Id. 328 * @throws org.apache.oozie.client.OozieClientException thrown if the job 329 * could not be resume. 330 */ 331 @Override 332 public void resume(String jobId) throws OozieClientException { 333 try { 334 coordEngine.resume(jobId); 335 } 336 catch (CoordinatorEngineException ex) { 337 throw new OozieClientException(ex.getErrorCode().toString(), ex); 338 } 339 } 340 341 /** 342 * Kill a coordinator job. 343 * 344 * @param jobId job Id. 345 * @throws org.apache.oozie.client.OozieClientException thrown if the job 346 * could not be killed. 347 */ 348 @Override 349 public void kill(String jobId) throws OozieClientException { 350 try { 351 coordEngine.kill(jobId); 352 } 353 catch (CoordinatorEngineException ex) { 354 throw new OozieClientException(ex.getErrorCode().toString(), ex); 355 } 356 } 357 358 /** 359 * Get the info of a workflow job. 360 * 361 * @param jobId job Id. 362 * @return the job info. 363 * @throws org.apache.oozie.client.OozieClientException thrown if the job 364 * info could not be retrieved. 365 */ 366 @Override 367 @Deprecated 368 public WorkflowJob getJobInfo(String jobId) throws OozieClientException { 369 throw new OozieClientException(ErrorCode.E0301.toString(), "no-op"); 370 } 371 372 /** 373 * Get the info of a coordinator job. 374 * 375 * @param jobId job Id. 376 * @return the job info. 377 * @throws org.apache.oozie.client.OozieClientException thrown if the job 378 * info could not be retrieved. 379 */ 380 @Override 381 public CoordinatorJob getCoordJobInfo(String jobId) throws OozieClientException { 382 try { 383 return coordEngine.getCoordJob(jobId); 384 } 385 catch (CoordinatorEngineException ex) { 386 throw new OozieClientException(ex.getErrorCode().toString(), ex); 387 } 388 catch (BaseEngineException bex) { 389 throw new OozieClientException(bex.getErrorCode().toString(), bex); 390 } 391 } 392 393 /** 394 * Get the info of a coordinator action. 395 * 396 * @param actionId Id. 397 * @return the coordinator action info. 398 * @throws OozieClientException thrown if the job info could not be 399 * retrieved. 400 */ 401 @Override 402 public CoordinatorAction getCoordActionInfo(String actionId) throws OozieClientException { 403 try { 404 return coordEngine.getCoordAction(actionId); 405 } 406 catch (CoordinatorEngineException ex) { 407 throw new OozieClientException(ex.getErrorCode().toString(), ex); 408 } 409 catch (BaseEngineException bex) { 410 throw new OozieClientException(bex.getErrorCode().toString(), bex); 411 } 412 } 413 414 /** 415 * Return the info of the workflow jobs that match the filter. 416 * 417 * @param filter job filter. Refer to the {@link OozieClient} for the filter 418 * syntax. 419 * @param start jobs offset, base 1. 420 * @param len number of jobs to return. 421 * @return a list with the workflow jobs info, without node details. 422 * @throws OozieClientException thrown if the jobs info could not be 423 * retrieved. 424 */ 425 @Override 426 @Deprecated 427 public List<WorkflowJob> getJobsInfo(String filter, int start, int len) throws OozieClientException { 428 throw new OozieClientException(ErrorCode.E0301.toString(), "no-op"); 429 } 430 431 /** 432 * Return the info of the coordinator jobs that match the filter. 433 * 434 * @param filter job filter. Refer to the {@link OozieClient} for the filter 435 * syntax. 436 * @param start jobs offset, base 1. 437 * @param len number of jobs to return. 438 * @return a list with the coordinator jobs info 439 * @throws OozieClientException thrown if the jobs info could not be 440 * retrieved. 441 */ 442 @Override 443 public List<CoordinatorJob> getCoordJobsInfo(String filter, int start, int len) throws OozieClientException { 444 try { 445 CoordinatorJobInfo info = coordEngine.getCoordJobs(filter, start, len); 446 List<CoordinatorJob> jobs = new ArrayList<CoordinatorJob>(); 447 List<CoordinatorJobBean> jobBeans = info.getCoordJobs(); 448 for (CoordinatorJobBean jobBean : jobBeans) { 449 jobs.add(jobBean); 450 } 451 return jobs; 452 453 } 454 catch (CoordinatorEngineException ex) { 455 throw new OozieClientException(ex.getErrorCode().toString(), ex); 456 } 457 } 458 459 /** 460 * Return the info of the workflow jobs that match the filter. 461 * <p/> 462 * It returns the first 100 jobs that match the filter. 463 * 464 * @param filter job filter. Refer to the {@link LocalOozieClient} for the 465 * filter syntax. 466 * @return a list with the workflow jobs info, without node details. 467 * @throws org.apache.oozie.client.OozieClientException thrown if the jobs 468 * info could not be retrieved. 469 */ 470 @Override 471 @Deprecated 472 public List<WorkflowJob> getJobsInfo(String filter) throws OozieClientException { 473 throw new OozieClientException(ErrorCode.E0301.toString(), "no-op"); 474 } 475 476}