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, null); 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 * @param conf configuration information for the rerun 270 * @throws OozieClientException 271 */ 272 @Override 273 public List<CoordinatorAction> reRunCoord(String jobId, String rerunType, String scope, boolean refresh, 274 boolean noCleanup, boolean failed, Properties conf ) throws OozieClientException { 275 return getCoordinatorActions(jobId, rerunType, scope, refresh, noCleanup, failed, conf); 276 } 277 278 private List<CoordinatorAction> getCoordinatorActions(String jobId, String rerunType, String scope, boolean refresh, 279 boolean noCleanup, boolean failed, Properties prop) throws OozieClientException { 280 try { 281 XConfiguration conf = null; 282 if (prop != null) { 283 conf = new XConfiguration(prop); 284 } 285 if (!(rerunType.equals(RestConstants.JOB_COORD_SCOPE_DATE) || rerunType 286 .equals(RestConstants.JOB_COORD_SCOPE_ACTION))) { 287 throw new CommandException(ErrorCode.E1018, "date or action expected."); 288 } 289 CoordinatorActionInfo coordInfo = coordEngine.reRun(jobId, rerunType, scope, Boolean.valueOf(refresh), 290 Boolean.valueOf(noCleanup), Boolean.valueOf(failed), conf); 291 List<CoordinatorActionBean> actionBeans; 292 if (coordInfo != null) { 293 actionBeans = coordInfo.getCoordActions(); 294 } 295 else { 296 actionBeans = CoordUtils.getCoordActions(rerunType, jobId, scope, false); 297 } 298 List<CoordinatorAction> actions = new ArrayList<CoordinatorAction>(); 299 for (CoordinatorActionBean actionBean : actionBeans) { 300 actions.add(actionBean); 301 } 302 return actions; 303 } 304 catch(CommandException ce){ 305 throw new OozieClientException(ce.getErrorCode().toString(), ce); 306 } 307 catch (BaseEngineException ex) { 308 throw new OozieClientException(ex.getErrorCode().toString(), ex); 309 } 310 } 311 312 /** 313 * Suspend a coordinator job. 314 * 315 * @param jobId job Id. 316 * @throws org.apache.oozie.client.OozieClientException thrown if the job 317 * could not be suspended. 318 */ 319 @Override 320 public void suspend(String jobId) throws OozieClientException { 321 try { 322 coordEngine.suspend(jobId); 323 } 324 catch (CoordinatorEngineException ex) { 325 throw new OozieClientException(ex.getErrorCode().toString(), ex); 326 } 327 } 328 329 /** 330 * Resume a coordinator job. 331 * 332 * @param jobId job Id. 333 * @throws org.apache.oozie.client.OozieClientException thrown if the job 334 * could not be resume. 335 */ 336 @Override 337 public void resume(String jobId) throws OozieClientException { 338 try { 339 coordEngine.resume(jobId); 340 } 341 catch (CoordinatorEngineException ex) { 342 throw new OozieClientException(ex.getErrorCode().toString(), ex); 343 } 344 } 345 346 /** 347 * Kill a coordinator job. 348 * 349 * @param jobId job Id. 350 * @throws org.apache.oozie.client.OozieClientException thrown if the job 351 * could not be killed. 352 */ 353 @Override 354 public void kill(String jobId) throws OozieClientException { 355 try { 356 coordEngine.kill(jobId); 357 } 358 catch (CoordinatorEngineException ex) { 359 throw new OozieClientException(ex.getErrorCode().toString(), ex); 360 } 361 } 362 363 /** 364 * Get the info of a workflow job. 365 * 366 * @param jobId job Id. 367 * @return the job info. 368 * @throws org.apache.oozie.client.OozieClientException thrown if the job 369 * info could not be retrieved. 370 */ 371 @Override 372 @Deprecated 373 public WorkflowJob getJobInfo(String jobId) throws OozieClientException { 374 throw new OozieClientException(ErrorCode.E0301.toString(), "no-op"); 375 } 376 377 /** 378 * Get the info of a coordinator job. 379 * 380 * @param jobId job Id. 381 * @return the job info. 382 * @throws org.apache.oozie.client.OozieClientException thrown if the job 383 * info could not be retrieved. 384 */ 385 @Override 386 public CoordinatorJob getCoordJobInfo(String jobId) throws OozieClientException { 387 try { 388 return coordEngine.getCoordJob(jobId); 389 } 390 catch (CoordinatorEngineException ex) { 391 throw new OozieClientException(ex.getErrorCode().toString(), ex); 392 } 393 catch (BaseEngineException bex) { 394 throw new OozieClientException(bex.getErrorCode().toString(), bex); 395 } 396 } 397 398 /** 399 * Get the info of a coordinator action. 400 * 401 * @param actionId Id. 402 * @return the coordinator action info. 403 * @throws OozieClientException thrown if the job info could not be 404 * retrieved. 405 */ 406 @Override 407 public CoordinatorAction getCoordActionInfo(String actionId) throws OozieClientException { 408 try { 409 return coordEngine.getCoordAction(actionId); 410 } 411 catch (CoordinatorEngineException ex) { 412 throw new OozieClientException(ex.getErrorCode().toString(), ex); 413 } 414 catch (BaseEngineException bex) { 415 throw new OozieClientException(bex.getErrorCode().toString(), bex); 416 } 417 } 418 419 /** 420 * Return the info of the workflow jobs that match the filter. 421 * 422 * @param filter job filter. Refer to the {@link OozieClient} for the filter 423 * syntax. 424 * @param start jobs offset, base 1. 425 * @param len number of jobs to return. 426 * @return a list with the workflow jobs info, without node details. 427 * @throws OozieClientException thrown if the jobs info could not be 428 * retrieved. 429 */ 430 @Override 431 @Deprecated 432 public List<WorkflowJob> getJobsInfo(String filter, int start, int len) throws OozieClientException { 433 throw new OozieClientException(ErrorCode.E0301.toString(), "no-op"); 434 } 435 436 /** 437 * Return the info of the coordinator jobs that match the filter. 438 * 439 * @param filter job filter. Refer to the {@link OozieClient} for the filter 440 * syntax. 441 * @param start jobs offset, base 1. 442 * @param len number of jobs to return. 443 * @return a list with the coordinator jobs info 444 * @throws OozieClientException thrown if the jobs info could not be 445 * retrieved. 446 */ 447 @Override 448 public List<CoordinatorJob> getCoordJobsInfo(String filter, int start, int len) throws OozieClientException { 449 try { 450 CoordinatorJobInfo info = coordEngine.getCoordJobs(filter, start, len); 451 List<CoordinatorJob> jobs = new ArrayList<CoordinatorJob>(); 452 List<CoordinatorJobBean> jobBeans = info.getCoordJobs(); 453 for (CoordinatorJobBean jobBean : jobBeans) { 454 jobs.add(jobBean); 455 } 456 return jobs; 457 458 } 459 catch (CoordinatorEngineException ex) { 460 throw new OozieClientException(ex.getErrorCode().toString(), ex); 461 } 462 } 463 464 /** 465 * Return the info of the workflow jobs that match the filter. 466 * <p/> 467 * It returns the first 100 jobs that match the filter. 468 * 469 * @param filter job filter. Refer to the {@link LocalOozieClient} for the 470 * filter syntax. 471 * @return a list with the workflow jobs info, without node details. 472 * @throws org.apache.oozie.client.OozieClientException thrown if the jobs 473 * info could not be retrieved. 474 */ 475 @Override 476 @Deprecated 477 public List<WorkflowJob> getJobsInfo(String filter) throws OozieClientException { 478 throw new OozieClientException(ErrorCode.E0301.toString(), "no-op"); 479 } 480 481}