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.cli; 016 017 import java.io.File; 018 import java.io.FileInputStream; 019 import java.io.FileReader; 020 import java.io.IOException; 021 import java.io.InputStream; 022 import java.text.SimpleDateFormat; 023 import java.util.ArrayList; 024 import java.util.Date; 025 import java.util.List; 026 import java.util.Locale; 027 import java.util.Map; 028 import java.util.Properties; 029 import java.util.TimeZone; 030 031 import javax.xml.XMLConstants; 032 import javax.xml.parsers.DocumentBuilder; 033 import javax.xml.parsers.DocumentBuilderFactory; 034 import javax.xml.parsers.ParserConfigurationException; 035 import javax.xml.transform.stream.StreamSource; 036 import javax.xml.validation.Schema; 037 import javax.xml.validation.SchemaFactory; 038 import javax.xml.validation.Validator; 039 040 import org.apache.commons.cli.CommandLine; 041 import org.apache.commons.cli.Option; 042 import org.apache.commons.cli.OptionBuilder; 043 import org.apache.commons.cli.OptionGroup; 044 import org.apache.commons.cli.Options; 045 import org.apache.commons.cli.ParseException; 046 import org.apache.oozie.BuildInfo; 047 import org.apache.oozie.client.BundleJob; 048 import org.apache.oozie.client.CoordinatorAction; 049 import org.apache.oozie.client.CoordinatorJob; 050 import org.apache.oozie.client.OozieClient; 051 import org.apache.oozie.client.OozieClientException; 052 import org.apache.oozie.client.WorkflowAction; 053 import org.apache.oozie.client.WorkflowJob; 054 import org.apache.oozie.client.XOozieClient; 055 import org.apache.oozie.client.OozieClient.SYSTEM_MODE; 056 import org.apache.oozie.client.rest.RestConstants; 057 import org.w3c.dom.DOMException; 058 import org.w3c.dom.Document; 059 import org.w3c.dom.Element; 060 import org.w3c.dom.Node; 061 import org.w3c.dom.NodeList; 062 import org.w3c.dom.Text; 063 import org.xml.sax.SAXException; 064 065 /** 066 * Oozie command line utility. 067 */ 068 public class OozieCLI { 069 public static final String ENV_OOZIE_URL = "OOZIE_URL"; 070 public static final String ENV_OOZIE_DEBUG = "OOZIE_DEBUG"; 071 public static final String WS_HEADER_PREFIX = "header:"; 072 073 public static final String HELP_CMD = "help"; 074 public static final String VERSION_CMD = "version"; 075 public static final String JOB_CMD = "job"; 076 public static final String JOBS_CMD = "jobs"; 077 public static final String ADMIN_CMD = "admin"; 078 public static final String VALIDATE_CMD = "validate"; 079 public static final String SLA_CMD = "sla"; 080 public static final String PIG_CMD = "pig"; 081 082 public static final String OOZIE_OPTION = "oozie"; 083 public static final String CONFIG_OPTION = "config"; 084 public static final String SUBMIT_OPTION = "submit"; 085 public static final String OFFSET_OPTION = "offset"; 086 public static final String START_OPTION = "start"; 087 public static final String RUN_OPTION = "run"; 088 public static final String DRYRUN_OPTION = "dryrun"; 089 public static final String SUSPEND_OPTION = "suspend"; 090 public static final String RESUME_OPTION = "resume"; 091 public static final String KILL_OPTION = "kill"; 092 public static final String CHANGE_OPTION = "change"; 093 public static final String CHANGE_VALUE_OPTION = "value"; 094 public static final String RERUN_OPTION = "rerun"; 095 public static final String INFO_OPTION = "info"; 096 public static final String LOG_OPTION = "log"; 097 public static final String DEFINITION_OPTION = "definition"; 098 public static final String CONFIG_CONTENT_OPTION = "configcontent"; 099 100 public static final String LEN_OPTION = "len"; 101 public static final String FILTER_OPTION = "filter"; 102 public static final String JOBTYPE_OPTION = "jobtype"; 103 public static final String SYSTEM_MODE_OPTION = "systemmode"; 104 public static final String VERSION_OPTION = "version"; 105 public static final String STATUS_OPTION = "status"; 106 public static final String LOCAL_TIME_OPTION = "localtime"; 107 public static final String QUEUE_DUMP_OPTION = "queuedump"; 108 public static final String RERUN_ACTION_OPTION = "action"; 109 public static final String RERUN_COORD_OPTION = "coordinator"; 110 public static final String RERUN_DATE_OPTION = "date"; 111 public static final String RERUN_REFRESH_OPTION = "refresh"; 112 public static final String RERUN_NOCLEANUP_OPTION = "nocleanup"; 113 114 public static final String VERBOSE_OPTION = "verbose"; 115 public static final String VERBOSE_DELIMITER = "\t"; 116 117 public static final String PIGFILE_OPTION = "file"; 118 119 private static final String[] OOZIE_HELP = { 120 "the env variable '" + ENV_OOZIE_URL + "' is used as default value for the '-" + OOZIE_OPTION + "' option", 121 "custom headers for Oozie web services can be specified using '-D" + WS_HEADER_PREFIX + "NAME=VALUE'" }; 122 123 private static final String RULER; 124 private static final int LINE_WIDTH = 132; 125 126 private boolean used; 127 128 static { 129 StringBuilder sb = new StringBuilder(); 130 for (int i = 0; i < LINE_WIDTH; i++) { 131 sb.append("-"); 132 } 133 RULER = sb.toString(); 134 } 135 136 /** 137 * Entry point for the Oozie CLI when invoked from the command line. 138 * <p/> 139 * Upon completion this method exits the JVM with '0' (success) or '-1' (failure). 140 * 141 * @param args options and arguments for the Oozie CLI. 142 */ 143 public static void main(String[] args) { 144 System.exit(new OozieCLI().run(args)); 145 } 146 147 /** 148 * Create an Oozie CLI instance. 149 */ 150 public OozieCLI() { 151 used = false; 152 } 153 154 /** 155 * Return Oozie CLI top help lines. 156 * 157 * @return help lines. 158 */ 159 protected String[] getCLIHelp() { 160 return OOZIE_HELP; 161 } 162 163 protected Options createAdminOptions() { 164 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 165 Option system_mode = new Option(SYSTEM_MODE_OPTION, true, 166 "Supported in Oozie-2.0 or later versions ONLY. Change oozie system mode [NORMAL|NOWEBSERVICE|SAFEMODE]"); 167 Option status = new Option(STATUS_OPTION, false, "show the current system status"); 168 Option version = new Option(VERSION_OPTION, false, "show Oozie server build version"); 169 Option queuedump = new Option(QUEUE_DUMP_OPTION, false, "show Oozie server queue elements"); 170 Options adminOptions = new Options(); 171 adminOptions.addOption(oozie); 172 OptionGroup group = new OptionGroup(); 173 group.addOption(system_mode); 174 group.addOption(status); 175 group.addOption(version); 176 group.addOption(queuedump); 177 adminOptions.addOptionGroup(group); 178 return adminOptions; 179 } 180 181 protected Options createJobOptions() { 182 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 183 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.xml' or '.properties'"); 184 Option submit = new Option(SUBMIT_OPTION, false, "submit a job"); 185 Option run = new Option(RUN_OPTION, false, "run a job"); 186 Option rerun = new Option(RERUN_OPTION, true, 187 "rerun a job (coordinator requires -action or -date, bundle requires -coordinator or -date)"); 188 Option dryrun = new Option(DRYRUN_OPTION, false, 189 "Supported in Oozie-2.0 or later versions ONLY - dryrun or test run a coordinator job, job is not queued"); 190 Option start = new Option(START_OPTION, true, "start a job"); 191 Option suspend = new Option(SUSPEND_OPTION, true, "suspend a job"); 192 Option resume = new Option(RESUME_OPTION, true, "resume a job"); 193 Option kill = new Option(KILL_OPTION, true, "kill a job"); 194 Option change = new Option(CHANGE_OPTION, true, "change a coordinator job"); 195 Option changeValue = new Option(CHANGE_VALUE_OPTION, true, 196 "new endtime/concurrency/pausetime value for changing a coordinator job"); 197 Option info = new Option(INFO_OPTION, true, "info of a job"); 198 Option offset = new Option(OFFSET_OPTION, true, "job info offset of actions (default '1', requires -info)"); 199 Option len = new Option(LEN_OPTION, true, "number of actions (default TOTAL ACTIONS, requires -info)"); 200 Option localtime = new Option(LOCAL_TIME_OPTION, false, "use local time (default GMT)"); 201 Option log = new Option(LOG_OPTION, true, "job log"); 202 Option definition = new Option(DEFINITION_OPTION, true, "job definition"); 203 Option config_content = new Option(CONFIG_CONTENT_OPTION, true, "job configuration"); 204 Option verbose = new Option(VERBOSE_OPTION, false, "verbose mode"); 205 Option rerun_action = new Option(RERUN_ACTION_OPTION, true, "coordinator rerun on action ids (requires -rerun)"); 206 Option rerun_date = new Option(RERUN_DATE_OPTION, true, 207 "coordinator/bundle rerun on action dates (requires -rerun)"); 208 Option rerun_coord = new Option(RERUN_COORD_OPTION, true, "bundle rerun on coordinator names (requires -rerun)"); 209 Option rerun_refresh = new Option(RERUN_REFRESH_OPTION, false, 210 "re-materialize the coordinator rerun actions (requires -rerun)"); 211 Option rerun_nocleanup = new Option(RERUN_NOCLEANUP_OPTION, false, 212 "do not clean up output-events of the coordiantor rerun actions (requires -rerun)"); 213 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 214 "set/override value for given property").create("D"); 215 216 OptionGroup actions = new OptionGroup(); 217 actions.addOption(submit); 218 actions.addOption(start); 219 actions.addOption(run); 220 actions.addOption(dryrun); 221 actions.addOption(suspend); 222 actions.addOption(resume); 223 actions.addOption(kill); 224 actions.addOption(change); 225 actions.addOption(info); 226 actions.addOption(rerun); 227 actions.addOption(log); 228 actions.addOption(definition); 229 actions.addOption(config_content); 230 actions.setRequired(true); 231 Options jobOptions = new Options(); 232 jobOptions.addOption(oozie); 233 jobOptions.addOption(config); 234 jobOptions.addOption(property); 235 jobOptions.addOption(changeValue); 236 jobOptions.addOption(localtime); 237 jobOptions.addOption(verbose); 238 jobOptions.addOption(offset); 239 jobOptions.addOption(len); 240 jobOptions.addOption(rerun_action); 241 jobOptions.addOption(rerun_date); 242 jobOptions.addOption(rerun_coord); 243 jobOptions.addOption(rerun_refresh); 244 jobOptions.addOption(rerun_nocleanup); 245 jobOptions.addOptionGroup(actions); 246 return jobOptions; 247 } 248 249 protected Options createJobsOptions() { 250 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 251 Option start = new Option(OFFSET_OPTION, true, "jobs offset (default '1')"); 252 Option jobtype = new Option(JOBTYPE_OPTION, true, 253 "job type ('Supported in Oozie-2.0 or later versions ONLY - 'coordinator' or 'bundle' or 'wf'(default))"); 254 Option len = new Option(LEN_OPTION, true, "number of jobs (default '100')"); 255 Option filter = new Option(FILTER_OPTION, true, "user=<U>;name=<N>;group=<G>;status=<S>;..."); 256 Option localtime = new Option(LOCAL_TIME_OPTION, false, "use local time (default GMT)"); 257 Option verbose = new Option(VERBOSE_OPTION, false, "verbose mode"); 258 start.setType(Integer.class); 259 len.setType(Integer.class); 260 Options jobsOptions = new Options(); 261 jobsOptions.addOption(oozie); 262 jobsOptions.addOption(localtime); 263 jobsOptions.addOption(start); 264 jobsOptions.addOption(len); 265 jobsOptions.addOption(oozie); 266 jobsOptions.addOption(filter); 267 jobsOptions.addOption(jobtype); 268 jobsOptions.addOption(verbose); 269 return jobsOptions; 270 } 271 272 protected Options createSlaOptions() { 273 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 274 Option start = new Option(OFFSET_OPTION, true, "start offset (default '0')"); 275 Option len = new Option(LEN_OPTION, true, "number of results (default '100')"); 276 start.setType(Integer.class); 277 len.setType(Integer.class); 278 Options slaOptions = new Options(); 279 slaOptions.addOption(start); 280 slaOptions.addOption(len); 281 slaOptions.addOption(oozie); 282 return slaOptions; 283 } 284 285 protected Options createPigOptions() { 286 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 287 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.properties'"); 288 Option pigFile = new Option(PIGFILE_OPTION, true, "Pig script"); 289 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 290 "set/override value for given property").create("D"); 291 Options pigOptions = new Options(); 292 pigOptions.addOption(oozie); 293 pigOptions.addOption(config); 294 pigOptions.addOption(property); 295 pigOptions.addOption(pigFile); 296 return pigOptions; 297 } 298 299 /** 300 * Run a CLI programmatically. 301 * <p/> 302 * It does not exit the JVM. 303 * <p/> 304 * A CLI instance can be used only once. 305 * 306 * @param args options and arguments for the Oozie CLI. 307 * @return '0' (success), '-1' (failure). 308 */ 309 public synchronized int run(String[] args) { 310 if (used) { 311 throw new IllegalStateException("CLI instance already used"); 312 } 313 used = true; 314 315 CLIParser parser = new CLIParser(OOZIE_OPTION, getCLIHelp()); 316 parser.addCommand(HELP_CMD, "", "display usage", new Options(), false); 317 parser.addCommand(VERSION_CMD, "", "show client version", new Options(), false); 318 parser.addCommand(JOB_CMD, "", "job operations", createJobOptions(), false); 319 parser.addCommand(JOBS_CMD, "", "jobs status", createJobsOptions(), false); 320 parser.addCommand(ADMIN_CMD, "", "admin operations", createAdminOptions(), false); 321 parser.addCommand(VALIDATE_CMD, "", "validate a workflow XML file", new Options(), true); 322 parser.addCommand(SLA_CMD, "", "sla operations (Supported in Oozie-2.0 or later)", createSlaOptions(), false); 323 parser.addCommand(PIG_CMD, "-X ", "submit a pig job, everything after '-X' are pass-through parameters to pig", 324 createPigOptions(), true); 325 326 try { 327 CLIParser.Command command = parser.parse(args); 328 if (command.getName().equals(HELP_CMD)) { 329 parser.showHelp(); 330 } 331 else if (command.getName().equals(JOB_CMD)) { 332 jobCommand(command.getCommandLine()); 333 } 334 else if (command.getName().equals(JOBS_CMD)) { 335 jobsCommand(command.getCommandLine()); 336 } 337 else if (command.getName().equals(ADMIN_CMD)) { 338 adminCommand(command.getCommandLine()); 339 } 340 else if (command.getName().equals(VERSION_CMD)) { 341 versionCommand(); 342 } 343 else if (command.getName().equals(VALIDATE_CMD)) { 344 validateCommand(command.getCommandLine()); 345 } 346 else if (command.getName().equals(SLA_CMD)) { 347 slaCommand(command.getCommandLine()); 348 } 349 else if (command.getName().equals(PIG_CMD)) { 350 pigCommand(command.getCommandLine()); 351 } 352 353 return 0; 354 } 355 catch (OozieCLIException ex) { 356 System.err.println("Error: " + ex.getMessage()); 357 return -1; 358 } 359 catch (ParseException ex) { 360 System.err.println("Invalid sub-command: " + ex.getMessage()); 361 System.err.println(); 362 System.err.println(parser.shortHelp()); 363 return -1; 364 } 365 catch (Exception ex) { 366 ex.printStackTrace(); 367 System.err.println(ex.getMessage()); 368 return -1; 369 } 370 } 371 372 protected String getOozieUrl(CommandLine commandLine) { 373 String url = commandLine.getOptionValue(OOZIE_OPTION); 374 if (url == null) { 375 url = System.getenv(ENV_OOZIE_URL); 376 if (url == null) { 377 throw new IllegalArgumentException( 378 "Oozie URL is not available neither in command option or in the environment"); 379 } 380 } 381 return url; 382 } 383 384 // Canibalized from Hadoop <code>Configuration.loadResource()</code>. 385 private Properties parse(InputStream is, Properties conf) throws IOException { 386 try { 387 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 388 // ignore all comments inside the xml file 389 docBuilderFactory.setIgnoringComments(true); 390 DocumentBuilder builder = docBuilderFactory.newDocumentBuilder(); 391 Document doc = builder.parse(is); 392 return parseDocument(doc, conf); 393 } 394 catch (SAXException e) { 395 throw new IOException(e); 396 } 397 catch (ParserConfigurationException e) { 398 throw new IOException(e); 399 } 400 } 401 402 // Canibalized from Hadoop <code>Configuration.loadResource()</code>. 403 private Properties parseDocument(Document doc, Properties conf) throws IOException { 404 try { 405 Element root = doc.getDocumentElement(); 406 if (!"configuration".equals(root.getTagName())) { 407 throw new RuntimeException("bad conf file: top-level element not <configuration>"); 408 } 409 NodeList props = root.getChildNodes(); 410 for (int i = 0; i < props.getLength(); i++) { 411 Node propNode = props.item(i); 412 if (!(propNode instanceof Element)) { 413 continue; 414 } 415 Element prop = (Element) propNode; 416 if (!"property".equals(prop.getTagName())) { 417 throw new RuntimeException("bad conf file: element not <property>"); 418 } 419 NodeList fields = prop.getChildNodes(); 420 String attr = null; 421 String value = null; 422 for (int j = 0; j < fields.getLength(); j++) { 423 Node fieldNode = fields.item(j); 424 if (!(fieldNode instanceof Element)) { 425 continue; 426 } 427 Element field = (Element) fieldNode; 428 if ("name".equals(field.getTagName()) && field.hasChildNodes()) { 429 attr = ((Text) field.getFirstChild()).getData(); 430 } 431 if ("value".equals(field.getTagName()) && field.hasChildNodes()) { 432 value = ((Text) field.getFirstChild()).getData(); 433 } 434 } 435 436 if (attr != null && value != null) { 437 conf.setProperty(attr, value); 438 } 439 } 440 return conf; 441 } 442 catch (DOMException e) { 443 throw new IOException(e); 444 } 445 } 446 447 private Properties getConfiguration(CommandLine commandLine) throws IOException { 448 Properties conf = new Properties(); 449 conf.setProperty("user.name", System.getProperty("user.name")); 450 String configFile = commandLine.getOptionValue(CONFIG_OPTION); 451 if (configFile == null) { 452 throw new IOException("configuration file not specified"); 453 } 454 else { 455 File file = new File(configFile); 456 if (!file.exists()) { 457 throw new IOException("configuration file [" + configFile + "] not found"); 458 } 459 if (configFile.endsWith(".properties")) { 460 conf.load(new FileReader(file)); 461 } 462 else if (configFile.endsWith(".xml")) { 463 parse(new FileInputStream(configFile), conf); 464 } 465 else { 466 throw new IllegalArgumentException("configuration must be a '.properties' or a '.xml' file"); 467 } 468 } 469 if (commandLine.hasOption("D")) { 470 Properties commandLineProperties = commandLine.getOptionProperties("D"); 471 conf.putAll(commandLineProperties); 472 } 473 return conf; 474 } 475 476 /** 477 * @param commandLine command line string. 478 * @return change value specified by -value. 479 * @throws OozieCLIException 480 */ 481 private String getChangeValue(CommandLine commandLine) throws OozieCLIException { 482 String changeValue = commandLine.getOptionValue(CHANGE_VALUE_OPTION); 483 484 if (changeValue == null) { 485 throw new OozieCLIException("-value option needs to be specified for -change option"); 486 } 487 488 return changeValue; 489 } 490 491 private void addHeader(OozieClient wc) { 492 for (Map.Entry entry : System.getProperties().entrySet()) { 493 String key = (String) entry.getKey(); 494 if (key.startsWith(WS_HEADER_PREFIX)) { 495 String header = key.substring(WS_HEADER_PREFIX.length()); 496 wc.setHeader(header, (String) entry.getValue()); 497 } 498 } 499 } 500 501 /** 502 * Create a OozieClient. 503 * <p/> 504 * It injects any '-Dheader:' as header to the the {@link org.apache.oozie.client.OozieClient}. 505 * 506 * @param commandLine the parsed command line options. 507 * @return a pre configured eXtended workflow client. 508 * @throws OozieCLIException thrown if the OozieClient could not be configured. 509 */ 510 protected OozieClient createOozieClient(CommandLine commandLine) throws OozieCLIException { 511 OozieClient wc = new OozieClient(getOozieUrl(commandLine)); 512 addHeader(wc); 513 setDebugMode(wc); 514 return wc; 515 } 516 517 /** 518 * Create a XOozieClient. 519 * <p/> 520 * It injects any '-Dheader:' as header to the the {@link org.apache.oozie.client.OozieClient}. 521 * 522 * @param commandLine the parsed command line options. 523 * @return a pre configured eXtended workflow client. 524 * @throws OozieCLIException thrown if the XOozieClient could not be configured. 525 */ 526 protected XOozieClient createXOozieClient(CommandLine commandLine) throws OozieCLIException { 527 XOozieClient wc = new XOozieClient(getOozieUrl(commandLine)); 528 addHeader(wc); 529 setDebugMode(wc); 530 return wc; 531 } 532 533 protected void setDebugMode(OozieClient wc) { 534 String debug = System.getenv(ENV_OOZIE_DEBUG); 535 if (debug != null && !debug.isEmpty()) { 536 int debugVal = 0; 537 try { 538 debugVal = Integer.parseInt(debug.trim()); 539 } 540 catch (Exception ex) { 541 System.out.println("Unable to parse the debug settings. May be not an integer [" + debug + "]"); 542 ex.printStackTrace(); 543 } 544 wc.setDebugMode(debugVal); 545 } 546 } 547 548 private static String JOB_ID_PREFIX = "job: "; 549 550 private void jobCommand(CommandLine commandLine) throws IOException, OozieCLIException { 551 XOozieClient wc = createXOozieClient(commandLine); 552 553 List<String> options = new ArrayList<String>(); 554 for (Option option : commandLine.getOptions()) { 555 options.add(option.getOpt()); 556 } 557 558 try { 559 if (options.contains(SUBMIT_OPTION)) { 560 System.out.println(JOB_ID_PREFIX + wc.submit(getConfiguration(commandLine))); 561 } 562 else if (options.contains(START_OPTION)) { 563 wc.start(commandLine.getOptionValue(START_OPTION)); 564 } 565 else if (options.contains(DRYRUN_OPTION)) { 566 String[] dryrunStr = wc.dryrun(getConfiguration(commandLine)).split("action for new instance"); 567 int arraysize = dryrunStr.length; 568 System.out.println("***coordJob after parsing: ***"); 569 System.out.println(dryrunStr[0]); 570 int aLen = dryrunStr.length - 1; 571 if (aLen < 0) { 572 aLen = 0; 573 } 574 System.out.println("***total coord actions is " + aLen + " ***"); 575 for (int i = 1; i <= arraysize - 1; i++) { 576 System.out.println(RULER); 577 System.out.println("coordAction instance: " + i + ":"); 578 System.out.println(dryrunStr[i]); 579 } 580 } 581 else if (options.contains(SUSPEND_OPTION)) { 582 wc.suspend(commandLine.getOptionValue(SUSPEND_OPTION)); 583 } 584 else if (options.contains(RESUME_OPTION)) { 585 wc.resume(commandLine.getOptionValue(RESUME_OPTION)); 586 } 587 else if (options.contains(KILL_OPTION)) { 588 wc.kill(commandLine.getOptionValue(KILL_OPTION)); 589 } 590 else if (options.contains(CHANGE_OPTION)) { 591 wc.change(commandLine.getOptionValue(CHANGE_OPTION), getChangeValue(commandLine)); 592 } 593 else if (options.contains(RUN_OPTION)) { 594 System.out.println(JOB_ID_PREFIX + wc.run(getConfiguration(commandLine))); 595 } 596 else if (options.contains(RERUN_OPTION)) { 597 if (commandLine.getOptionValue(RERUN_OPTION).contains("-W")) { 598 wc.reRun(commandLine.getOptionValue(RERUN_OPTION), getConfiguration(commandLine)); 599 } 600 else if (commandLine.getOptionValue(RERUN_OPTION).contains("-B")) { 601 String bundleJobId = commandLine.getOptionValue(RERUN_OPTION); 602 String coordScope = null; 603 String dateScope = null; 604 boolean refresh = false; 605 boolean noCleanup = false; 606 if (options.contains(RERUN_ACTION_OPTION)) { 607 throw new OozieCLIException("Invalid options provided for bundle rerun. " + RERUN_ACTION_OPTION 608 + " is not valid for bundle rerun"); 609 } 610 if (options.contains(RERUN_DATE_OPTION)) { 611 dateScope = commandLine.getOptionValue(RERUN_DATE_OPTION); 612 } 613 614 if (options.contains(RERUN_COORD_OPTION)) { 615 coordScope = commandLine.getOptionValue(RERUN_COORD_OPTION); 616 } 617 618 if (options.contains(RERUN_REFRESH_OPTION)) { 619 refresh = true; 620 } 621 if (options.contains(RERUN_NOCLEANUP_OPTION)) { 622 noCleanup = true; 623 } 624 wc.reRunBundle(bundleJobId, coordScope, dateScope, refresh, noCleanup); 625 if (coordScope != null && !coordScope.isEmpty()) { 626 System.out.println("Coordinators [" + coordScope + "] of bundle " + bundleJobId 627 + " are scheduled to rerun on date ranges [" + dateScope + "]."); 628 } 629 else { 630 System.out.println("All coordinators of bundle " + bundleJobId 631 + " are scheduled to rerun on the date ranges [" + dateScope + "]."); 632 } 633 } 634 else { 635 String coordJobId = commandLine.getOptionValue(RERUN_OPTION); 636 String scope = null; 637 String rerunType = null; 638 boolean refresh = false; 639 boolean noCleanup = false; 640 if (options.contains(RERUN_DATE_OPTION) && options.contains(RERUN_ACTION_OPTION)) { 641 throw new OozieCLIException("Invalid options provided for rerun: either" + RERUN_DATE_OPTION 642 + " or " + RERUN_ACTION_OPTION + " expected. Don't use both at the same time."); 643 } 644 if (options.contains(RERUN_DATE_OPTION)) { 645 rerunType = RestConstants.JOB_COORD_RERUN_DATE; 646 scope = commandLine.getOptionValue(RERUN_DATE_OPTION); 647 } 648 else if (options.contains(RERUN_ACTION_OPTION)) { 649 rerunType = RestConstants.JOB_COORD_RERUN_ACTION; 650 scope = commandLine.getOptionValue(RERUN_ACTION_OPTION); 651 } 652 else { 653 throw new OozieCLIException("Invalid options provided for rerun: " + RERUN_DATE_OPTION + " or " 654 + RERUN_ACTION_OPTION + " expected."); 655 } 656 if (options.contains(RERUN_REFRESH_OPTION)) { 657 refresh = true; 658 } 659 if (options.contains(RERUN_NOCLEANUP_OPTION)) { 660 noCleanup = true; 661 } 662 printRerunCoordActions(wc.reRunCoord(coordJobId, rerunType, scope, refresh, noCleanup)); 663 } 664 } 665 else if (options.contains(INFO_OPTION)) { 666 if (commandLine.getOptionValue(INFO_OPTION).endsWith("-B")) { 667 printBundleJob(wc.getBundleJobInfo(commandLine.getOptionValue(INFO_OPTION)), options 668 .contains(LOCAL_TIME_OPTION), options.contains(VERBOSE_OPTION)); 669 } 670 else if (commandLine.getOptionValue(INFO_OPTION).endsWith("-C")) { 671 String s = commandLine.getOptionValue(OFFSET_OPTION); 672 int start = Integer.parseInt((s != null) ? s : "0"); 673 s = commandLine.getOptionValue(LEN_OPTION); 674 int len = Integer.parseInt((s != null) ? s : "0"); 675 printCoordJob(wc.getCoordJobInfo(commandLine.getOptionValue(INFO_OPTION), start, len), options 676 .contains(LOCAL_TIME_OPTION), options.contains(VERBOSE_OPTION)); 677 } 678 else if (commandLine.getOptionValue(INFO_OPTION).contains("-C@")) { 679 printCoordAction(wc.getCoordActionInfo(commandLine.getOptionValue(INFO_OPTION)), options 680 .contains(LOCAL_TIME_OPTION)); 681 } 682 else if (commandLine.getOptionValue(INFO_OPTION).contains("-W@")) { 683 printWorkflowAction(wc.getWorkflowActionInfo(commandLine.getOptionValue(INFO_OPTION)), options 684 .contains(LOCAL_TIME_OPTION)); 685 } 686 else { 687 String s = commandLine.getOptionValue(OFFSET_OPTION); 688 int start = Integer.parseInt((s != null) ? s : "0"); 689 s = commandLine.getOptionValue(LEN_OPTION); 690 String jobtype = commandLine.getOptionValue(JOBTYPE_OPTION); 691 jobtype = (jobtype != null) ? jobtype : "wf"; 692 int len = Integer.parseInt((s != null) ? s : "0"); 693 printJob(wc.getJobInfo(commandLine.getOptionValue(INFO_OPTION), start, len), options 694 .contains(LOCAL_TIME_OPTION), options.contains(VERBOSE_OPTION)); 695 } 696 } 697 else if (options.contains(LOG_OPTION)) { 698 System.out.println(wc.getJobLog(commandLine.getOptionValue(LOG_OPTION))); 699 } 700 else if (options.contains(DEFINITION_OPTION)) { 701 System.out.println(wc.getJobDefinition(commandLine.getOptionValue(DEFINITION_OPTION))); 702 } 703 else if (options.contains(CONFIG_CONTENT_OPTION)) { 704 if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-C")) { 705 System.out.println(wc.getCoordJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 706 } 707 else if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-W")) { 708 System.out.println(wc.getJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 709 } 710 else if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-B")) { 711 System.out 712 .println(wc.getBundleJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 713 } 714 else { 715 System.out.println("ERROR: job id [" + commandLine.getOptionValue(CONFIG_CONTENT_OPTION) 716 + "] doesn't end with either C or W or B"); 717 } 718 } 719 } 720 catch (OozieClientException ex) { 721 throw new OozieCLIException(ex.toString(), ex); 722 } 723 } 724 725 private void printCoordJob(CoordinatorJob coordJob, boolean localtime, boolean verbose) { 726 System.out.println("Job ID : " + coordJob.getId()); 727 728 System.out.println(RULER); 729 730 List<CoordinatorAction> actions = coordJob.getActions(); 731 System.out.println("Job Name : " + maskIfNull(coordJob.getAppName())); 732 System.out.println("App Path : " + maskIfNull(coordJob.getAppPath())); 733 System.out.println("Status : " + coordJob.getStatus()); 734 System.out.println(RULER); 735 736 if (verbose) { 737 System.out.println("ID" + VERBOSE_DELIMITER + "Action Number" + VERBOSE_DELIMITER + "Console URL" 738 + VERBOSE_DELIMITER + "Error Code" + VERBOSE_DELIMITER + "Error Message" + VERBOSE_DELIMITER 739 + "External ID" + VERBOSE_DELIMITER + "External Status" + VERBOSE_DELIMITER + "Job ID" 740 + VERBOSE_DELIMITER + "Tracker URI" + VERBOSE_DELIMITER + "Created" + VERBOSE_DELIMITER 741 + "Nominal Time" + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Last Modified" 742 + VERBOSE_DELIMITER + "Missing Dependencies"); 743 System.out.println(RULER); 744 745 for (CoordinatorAction action : actions) { 746 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER + action.getActionNumber() 747 + VERBOSE_DELIMITER + maskIfNull(action.getConsoleUrl()) + VERBOSE_DELIMITER 748 + maskIfNull(action.getErrorCode()) + VERBOSE_DELIMITER + maskIfNull(action.getErrorMessage()) 749 + VERBOSE_DELIMITER + maskIfNull(action.getExternalId()) + VERBOSE_DELIMITER 750 + maskIfNull(action.getExternalStatus()) + VERBOSE_DELIMITER + maskIfNull(action.getJobId()) 751 + VERBOSE_DELIMITER + maskIfNull(action.getTrackerUri()) + VERBOSE_DELIMITER 752 + maskDate(action.getCreatedTime(), localtime) + VERBOSE_DELIMITER 753 + maskDate(action.getNominalTime(), localtime) + action.getStatus() + VERBOSE_DELIMITER 754 + maskDate(action.getLastModifiedTime(), localtime) + VERBOSE_DELIMITER 755 + maskIfNull(action.getMissingDependencies())); 756 757 System.out.println(RULER); 758 } 759 } 760 else { 761 System.out.println(String.format(COORD_ACTION_FORMATTER, "ID", "Status", "Ext ID", "Err Code", "Created", 762 "Nominal Time", "Last Mod")); 763 764 for (CoordinatorAction action : actions) { 765 System.out.println(String.format(COORD_ACTION_FORMATTER, maskIfNull(action.getId()), 766 action.getStatus(), maskIfNull(action.getExternalId()), maskIfNull(action.getErrorCode()), 767 maskDate(action.getCreatedTime(), localtime), maskDate(action.getNominalTime(), localtime), 768 maskDate(action.getLastModifiedTime(), localtime))); 769 770 System.out.println(RULER); 771 } 772 } 773 } 774 775 private void printBundleJob(BundleJob bundleJob, boolean localtime, boolean verbose) { 776 System.out.println("Job ID : " + bundleJob.getId()); 777 778 System.out.println(RULER); 779 780 List<CoordinatorJob> coordinators = bundleJob.getCoordinators(); 781 System.out.println("Job Name : " + maskIfNull(bundleJob.getAppName())); 782 System.out.println("App Path : " + maskIfNull(bundleJob.getAppPath())); 783 System.out.println("Status : " + bundleJob.getStatus()); 784 System.out.println("Kickoff time : " + bundleJob.getKickoffTime()); 785 System.out.println(RULER); 786 787 System.out.println(String.format(BUNDLE_COORD_JOBS_FORMATTER, "Job ID", "Status", "Freq", "Unit", "Started", 788 "Next Materialized")); 789 System.out.println(RULER); 790 791 for (CoordinatorJob job : coordinators) { 792 System.out.println(String.format(BUNDLE_COORD_JOBS_FORMATTER, maskIfNull(job.getId()), job.getStatus(), job 793 .getFrequency(), job.getTimeUnit(), maskDate(job.getStartTime(), localtime), maskDate(job 794 .getNextMaterializedTime(), localtime))); 795 796 System.out.println(RULER); 797 } 798 } 799 800 private void printCoordAction(CoordinatorAction coordAction, boolean contains) { 801 System.out.println("ID : " + maskIfNull(coordAction.getId())); 802 803 System.out.println(RULER); 804 805 System.out.println("Action Number : " + coordAction.getActionNumber()); 806 System.out.println("Console URL : " + maskIfNull(coordAction.getConsoleUrl())); 807 System.out.println("Error Code : " + maskIfNull(coordAction.getErrorCode())); 808 System.out.println("Error Message : " + maskIfNull(coordAction.getErrorMessage())); 809 System.out.println("External ID : " + maskIfNull(coordAction.getExternalId())); 810 System.out.println("External Status : " + maskIfNull(coordAction.getExternalStatus())); 811 System.out.println("Job ID : " + maskIfNull(coordAction.getJobId())); 812 System.out.println("Tracker URI : " + maskIfNull(coordAction.getTrackerUri())); 813 System.out.println("Created : " + maskDate(coordAction.getCreatedTime(), contains)); 814 System.out.println("Nominal Time : " + maskDate(coordAction.getNominalTime(), contains)); 815 System.out.println("Status : " + coordAction.getStatus()); 816 System.out.println("Last Modified : " + maskDate(coordAction.getLastModifiedTime(), contains)); 817 System.out.println("Missing Dependencies : " + maskIfNull(coordAction.getMissingDependencies())); 818 819 System.out.println(RULER); 820 } 821 822 private void printRerunCoordActions(List<CoordinatorAction> actions) { 823 if (actions != null && actions.size() > 0) { 824 System.out.println("Action ID" + VERBOSE_DELIMITER + "Nominal Time"); 825 System.out.println(RULER); 826 for (CoordinatorAction action : actions) { 827 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER 828 + maskDate(action.getNominalTime(), false)); 829 } 830 } 831 else { 832 System.out.println("No Actions match your rerun criteria!"); 833 } 834 } 835 836 private void printWorkflowAction(WorkflowAction action, boolean contains) { 837 System.out.println("ID : " + maskIfNull(action.getId())); 838 839 System.out.println(RULER); 840 841 System.out.println("Console URL : " + maskIfNull(action.getConsoleUrl())); 842 System.out.println("Error Code : " + maskIfNull(action.getErrorCode())); 843 System.out.println("Error Message : " + maskIfNull(action.getErrorMessage())); 844 System.out.println("External ID : " + maskIfNull(action.getExternalId())); 845 System.out.println("External Status : " + maskIfNull(action.getExternalStatus())); 846 System.out.println("Name : " + maskIfNull(action.getName())); 847 System.out.println("Retries : " + action.getRetries()); 848 System.out.println("Tracker URI : " + maskIfNull(action.getTrackerUri())); 849 System.out.println("Type : " + maskIfNull(action.getType())); 850 System.out.println("Started : " + maskDate(action.getStartTime(), contains)); 851 System.out.println("Status : " + action.getStatus()); 852 System.out.println("Ended : " + maskDate(action.getEndTime(), contains)); 853 854 System.out.println(RULER); 855 } 856 857 private static final String WORKFLOW_JOBS_FORMATTER = "%-41s%-13s%-10s%-10s%-10s%-24s%-24s"; 858 private static final String COORD_JOBS_FORMATTER = "%-41s%-15s%-10s%-5s%-13s%-24s%-24s"; 859 private static final String BUNDLE_JOBS_FORMATTER = "%-41s%-15s%-10s%-20s%-20s%-13s%-13s"; 860 private static final String BUNDLE_COORD_JOBS_FORMATTER = "%-41s%-10s%-5s%-13s%-24s%-24s"; 861 862 private static final String WORKFLOW_ACTION_FORMATTER = "%-78s%-10s%-23s%-11s%-10s"; 863 private static final String COORD_ACTION_FORMATTER = "%-41s%-10s%-37s%-10s%-17s%-17s"; 864 865 private void printJob(WorkflowJob job, boolean localtime, boolean verbose) throws IOException { 866 System.out.println("Job ID : " + maskIfNull(job.getId())); 867 868 System.out.println(RULER); 869 870 System.out.println("Workflow Name : " + maskIfNull(job.getAppName())); 871 System.out.println("App Path : " + maskIfNull(job.getAppPath())); 872 System.out.println("Status : " + job.getStatus()); 873 System.out.println("Run : " + job.getRun()); 874 System.out.println("User : " + maskIfNull(job.getUser())); 875 System.out.println("Group : " + maskIfNull(job.getGroup())); 876 System.out.println("Created : " + maskDate(job.getCreatedTime(), localtime)); 877 System.out.println("Started : " + maskDate(job.getStartTime(), localtime)); 878 System.out.println("Last Modified : " + maskDate(job.getLastModifiedTime(), localtime)); 879 System.out.println("Ended : " + maskDate(job.getEndTime(), localtime)); 880 System.out.println("CoordAction ID: " + maskIfNull(job.getParentId())); 881 882 List<WorkflowAction> actions = job.getActions(); 883 884 if (actions != null && actions.size() > 0) { 885 System.out.println(); 886 System.out.println("Actions"); 887 System.out.println(RULER); 888 889 if (verbose) { 890 System.out.println("ID" + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "Error Code" 891 + VERBOSE_DELIMITER + "Error Message" + VERBOSE_DELIMITER + "External ID" + VERBOSE_DELIMITER 892 + "External Status" + VERBOSE_DELIMITER + "Name" + VERBOSE_DELIMITER + "Retries" 893 + VERBOSE_DELIMITER + "Tracker URI" + VERBOSE_DELIMITER + "Type" + VERBOSE_DELIMITER 894 + "Started" + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Ended"); 895 System.out.println(RULER); 896 897 for (WorkflowAction action : job.getActions()) { 898 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER 899 + maskIfNull(action.getConsoleUrl()) + VERBOSE_DELIMITER 900 + maskIfNull(action.getErrorCode()) + VERBOSE_DELIMITER 901 + maskIfNull(action.getErrorMessage()) + VERBOSE_DELIMITER 902 + maskIfNull(action.getExternalId()) + VERBOSE_DELIMITER 903 + maskIfNull(action.getExternalStatus()) + VERBOSE_DELIMITER + maskIfNull(action.getName()) 904 + VERBOSE_DELIMITER + action.getRetries() + VERBOSE_DELIMITER 905 + maskIfNull(action.getTrackerUri()) + VERBOSE_DELIMITER + maskIfNull(action.getType()) 906 + VERBOSE_DELIMITER + maskDate(action.getStartTime(), localtime) + VERBOSE_DELIMITER 907 + action.getStatus() + VERBOSE_DELIMITER + maskDate(action.getEndTime(), localtime)); 908 909 System.out.println(RULER); 910 } 911 } 912 else { 913 System.out.println(String.format(WORKFLOW_ACTION_FORMATTER, "ID", "Status", "Ext ID", "Ext Status", 914 "Err Code")); 915 916 System.out.println(RULER); 917 918 for (WorkflowAction action : job.getActions()) { 919 System.out.println(String.format(WORKFLOW_ACTION_FORMATTER, maskIfNull(action.getId()), action 920 .getStatus(), maskIfNull(action.getExternalId()), maskIfNull(action.getExternalStatus()), 921 maskIfNull(action.getErrorCode()))); 922 923 System.out.println(RULER); 924 } 925 } 926 } 927 else { 928 System.out.println(RULER); 929 } 930 931 System.out.println(); 932 } 933 934 private void jobsCommand(CommandLine commandLine) throws IOException, OozieCLIException { 935 XOozieClient wc = createXOozieClient(commandLine); 936 937 String filter = commandLine.getOptionValue(FILTER_OPTION); 938 String s = commandLine.getOptionValue(OFFSET_OPTION); 939 int start = Integer.parseInt((s != null) ? s : "0"); 940 s = commandLine.getOptionValue(LEN_OPTION); 941 String jobtype = commandLine.getOptionValue(JOBTYPE_OPTION); 942 jobtype = (jobtype != null) ? jobtype : "wf"; 943 int len = Integer.parseInt((s != null) ? s : "0"); 944 try { 945 if (jobtype.toLowerCase().contains("wf")) { 946 printJobs(wc.getJobsInfo(filter, start, len), commandLine.hasOption(LOCAL_TIME_OPTION), commandLine 947 .hasOption(VERBOSE_OPTION)); 948 } 949 else if (jobtype.toLowerCase().startsWith("coord")) { 950 printCoordJobs(wc.getCoordJobsInfo(filter, start, len), commandLine.hasOption(LOCAL_TIME_OPTION), 951 commandLine.hasOption(VERBOSE_OPTION)); 952 } 953 else if (jobtype.toLowerCase().startsWith("bundle")) { 954 printBundleJobs(wc.getBundleJobsInfo(filter, start, len), commandLine.hasOption(LOCAL_TIME_OPTION), 955 commandLine.hasOption(VERBOSE_OPTION)); 956 } 957 958 } 959 catch (OozieClientException ex) { 960 throw new OozieCLIException(ex.toString(), ex); 961 } 962 } 963 964 private void printCoordJobs(List<CoordinatorJob> jobs, boolean localtime, boolean verbose) throws IOException { 965 if (jobs != null && jobs.size() > 0) { 966 if (verbose) { 967 System.out.println("Job ID" + VERBOSE_DELIMITER + "App Name" + VERBOSE_DELIMITER + "App Path" 968 + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" 969 + VERBOSE_DELIMITER + "Concurrency" + VERBOSE_DELIMITER + "Frequency" + VERBOSE_DELIMITER 970 + "Time Unit" + VERBOSE_DELIMITER + "Time Zone" + VERBOSE_DELIMITER + "Time Out" 971 + VERBOSE_DELIMITER + "Started" + VERBOSE_DELIMITER + "Next Materialize" + VERBOSE_DELIMITER 972 + "Status" + VERBOSE_DELIMITER + "Last Action" + VERBOSE_DELIMITER + "Ended"); 973 System.out.println(RULER); 974 975 for (CoordinatorJob job : jobs) { 976 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 977 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 978 + maskIfNull(job.getConsoleUrl()) + VERBOSE_DELIMITER + maskIfNull(job.getUser()) 979 + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) + VERBOSE_DELIMITER + job.getConcurrency() 980 + VERBOSE_DELIMITER + job.getFrequency() + VERBOSE_DELIMITER + job.getTimeUnit() 981 + VERBOSE_DELIMITER + maskIfNull(job.getTimeZone()) + VERBOSE_DELIMITER + job.getTimeout() 982 + VERBOSE_DELIMITER + maskDate(job.getStartTime(), localtime) + VERBOSE_DELIMITER 983 + maskDate(job.getNextMaterializedTime(), localtime) + VERBOSE_DELIMITER + job.getStatus() 984 + VERBOSE_DELIMITER + maskDate(job.getLastActionTime(), localtime) + VERBOSE_DELIMITER 985 + maskDate(job.getEndTime(), localtime)); 986 987 System.out.println(RULER); 988 } 989 } 990 else { 991 System.out.println(String.format(COORD_JOBS_FORMATTER, "Job ID", "App Name", "Status", "Freq", "Unit", 992 "Started", "Next Materialized")); 993 System.out.println(RULER); 994 995 for (CoordinatorJob job : jobs) { 996 System.out.println(String.format(COORD_JOBS_FORMATTER, maskIfNull(job.getId()), maskIfNull(job 997 .getAppName()), job.getStatus(), job.getFrequency(), job.getTimeUnit(), maskDate(job 998 .getStartTime(), localtime), maskDate(job.getNextMaterializedTime(), localtime))); 999 1000 System.out.println(RULER); 1001 } 1002 } 1003 } 1004 else { 1005 System.out.println("No Jobs match your criteria!"); 1006 } 1007 } 1008 1009 private void printBundleJobs(List<BundleJob> jobs, boolean localtime, boolean verbose) throws IOException { 1010 if (jobs != null && jobs.size() > 0) { 1011 if (verbose) { 1012 System.out.println("Job ID" + VERBOSE_DELIMITER + "Bundle Name" + VERBOSE_DELIMITER + "Bundle Path" 1013 + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" + VERBOSE_DELIMITER + "Status" 1014 + VERBOSE_DELIMITER + "Kickoff" + VERBOSE_DELIMITER + "Pause" + VERBOSE_DELIMITER + "Created" 1015 + VERBOSE_DELIMITER + "Console URL"); 1016 System.out.println(RULER); 1017 1018 for (BundleJob job : jobs) { 1019 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1020 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1021 + maskIfNull(job.getUser()) + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) 1022 + VERBOSE_DELIMITER + job.getStatus() + VERBOSE_DELIMITER 1023 + maskDate(job.getKickoffTime(), localtime) + VERBOSE_DELIMITER 1024 + maskDate(job.getPauseTime(), localtime) + VERBOSE_DELIMITER 1025 + maskDate(job.getCreatedTime(), localtime) + VERBOSE_DELIMITER 1026 + maskIfNull(job.getConsoleUrl())); 1027 1028 System.out.println(RULER); 1029 } 1030 } 1031 else { 1032 System.out.println(String.format(BUNDLE_JOBS_FORMATTER, "Job ID", "Bundle Name", "Status", "Kickoff", 1033 "Created", "User", "Group")); 1034 System.out.println(RULER); 1035 1036 for (BundleJob job : jobs) { 1037 System.out.println(String.format(BUNDLE_JOBS_FORMATTER, maskIfNull(job.getId()), maskIfNull(job 1038 .getAppName()), job.getStatus(), maskDate(job.getKickoffTime(), localtime), 1039 maskDate(job.getCreatedTime(), localtime), maskIfNull(job.getUser()), maskIfNull(job.getGroup()))); 1040 System.out.println(RULER); 1041 } 1042 } 1043 } 1044 else { 1045 System.out.println("No Jobs match your criteria!"); 1046 } 1047 } 1048 1049 private void slaCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1050 XOozieClient wc = createXOozieClient(commandLine); 1051 String s = commandLine.getOptionValue(OFFSET_OPTION); 1052 int start = Integer.parseInt((s != null) ? s : "0"); 1053 s = commandLine.getOptionValue(LEN_OPTION); 1054 int len = Integer.parseInt((s != null) ? s : "100"); 1055 try { 1056 wc.getSlaInfo(start, len); 1057 } 1058 catch (OozieClientException ex) { 1059 throw new OozieCLIException(ex.toString(), ex); 1060 } 1061 } 1062 1063 private void adminCommand(CommandLine commandLine) throws OozieCLIException { 1064 XOozieClient wc = createXOozieClient(commandLine); 1065 1066 List<String> options = new ArrayList<String>(); 1067 for (Option option : commandLine.getOptions()) { 1068 options.add(option.getOpt()); 1069 } 1070 1071 try { 1072 SYSTEM_MODE status = SYSTEM_MODE.NORMAL; 1073 if (options.contains(VERSION_OPTION)) { 1074 System.out.println("Oozie server build version: " + wc.getServerBuildVersion()); 1075 } 1076 else if (options.contains(SYSTEM_MODE_OPTION)) { 1077 String systemModeOption = commandLine.getOptionValue(SYSTEM_MODE_OPTION).toUpperCase(); 1078 try { 1079 status = SYSTEM_MODE.valueOf(systemModeOption); 1080 } 1081 catch (Exception e) { 1082 throw new OozieCLIException("Invalid input provided for option: " + SYSTEM_MODE_OPTION 1083 + " value given :" + systemModeOption 1084 + " Expected values are: NORMAL/NOWEBSERVICE/SAFEMODE "); 1085 } 1086 wc.setSystemMode(status); 1087 System.out.println("System mode: " + status); 1088 } 1089 else if (options.contains(STATUS_OPTION)) { 1090 status = wc.getSystemMode(); 1091 System.out.println("System mode: " + status); 1092 } 1093 else if (options.contains(QUEUE_DUMP_OPTION)) { 1094 1095 List<String> list = wc.getQueueDump(); 1096 if (list != null && list.size() != 0) { 1097 for (String str : list) { 1098 System.out.println(str); 1099 } 1100 } 1101 else { 1102 System.out.println("QueueDump is null!"); 1103 } 1104 } 1105 } 1106 catch (OozieClientException ex) { 1107 throw new OozieCLIException(ex.toString(), ex); 1108 } 1109 } 1110 1111 private void versionCommand() throws OozieCLIException { 1112 System.out.println("Oozie client build version: " 1113 + BuildInfo.getBuildInfo().getProperty(BuildInfo.BUILD_VERSION)); 1114 } 1115 1116 private void printJobs(List<WorkflowJob> jobs, boolean localtime, boolean verbose) throws IOException { 1117 if (jobs != null && jobs.size() > 0) { 1118 if (verbose) { 1119 System.out.println("Job ID" + VERBOSE_DELIMITER + "App Name" + VERBOSE_DELIMITER + "App Path" 1120 + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" 1121 + VERBOSE_DELIMITER + "Run" + VERBOSE_DELIMITER + "Created" + VERBOSE_DELIMITER + "Started" 1122 + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Last Modified" + VERBOSE_DELIMITER 1123 + "Ended"); 1124 System.out.println(RULER); 1125 1126 for (WorkflowJob job : jobs) { 1127 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1128 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1129 + maskIfNull(job.getConsoleUrl()) + VERBOSE_DELIMITER + maskIfNull(job.getUser()) 1130 + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) + VERBOSE_DELIMITER + job.getRun() 1131 + VERBOSE_DELIMITER + maskDate(job.getCreatedTime(), localtime) + VERBOSE_DELIMITER 1132 + maskDate(job.getStartTime(), localtime) + VERBOSE_DELIMITER + job.getStatus() 1133 + VERBOSE_DELIMITER + maskDate(job.getLastModifiedTime(), localtime) + VERBOSE_DELIMITER 1134 + maskDate(job.getEndTime(), localtime)); 1135 1136 System.out.println(RULER); 1137 } 1138 } 1139 else { 1140 System.out.println(String.format(WORKFLOW_JOBS_FORMATTER, "Job ID", "App Name", "Status", "User", 1141 "Group", "Started", "Ended")); 1142 System.out.println(RULER); 1143 1144 for (WorkflowJob job : jobs) { 1145 System.out.println(String.format(WORKFLOW_JOBS_FORMATTER, maskIfNull(job.getId()), maskIfNull(job 1146 .getAppName()), job.getStatus(), maskIfNull(job.getUser()), maskIfNull(job.getGroup()), 1147 maskDate(job.getStartTime(), localtime), maskDate(job.getEndTime(), localtime))); 1148 1149 System.out.println(RULER); 1150 } 1151 } 1152 } 1153 else { 1154 System.out.println("No Jobs match your criteria!"); 1155 } 1156 } 1157 1158 private String maskIfNull(String value) { 1159 if (value != null && value.length() > 0) { 1160 return value; 1161 } 1162 return "-"; 1163 } 1164 1165 private String maskDate(Date date, boolean isLocalTimeZone) { 1166 if (date == null) { 1167 return "-"; 1168 } 1169 1170 // SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd 1171 // HH:mm Z", Locale.US); 1172 SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); 1173 if (!isLocalTimeZone) { 1174 dateFormater.setTimeZone(TimeZone.getTimeZone("GMT")); 1175 } 1176 return dateFormater.format(date); 1177 } 1178 1179 private void validateCommand(CommandLine commandLine) throws OozieCLIException { 1180 String[] args = commandLine.getArgs(); 1181 if (args.length != 1) { 1182 throw new OozieCLIException("One file must be specified"); 1183 } 1184 File file = new File(args[0]); 1185 if (file.exists()) { 1186 try { 1187 List<StreamSource> sources = new ArrayList<StreamSource>(); 1188 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1189 "oozie-workflow-0.1.xsd"))); 1190 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 1191 Schema schema = factory.newSchema(sources.toArray(new StreamSource[sources.size()])); 1192 Validator validator = schema.newValidator(); 1193 validator.validate(new StreamSource(new FileReader(file))); 1194 System.out.println("Valid worflow-app"); 1195 } 1196 catch (Exception ex) { 1197 throw new OozieCLIException("Invalid workflow-app, " + ex.toString(), ex); 1198 } 1199 } 1200 else { 1201 throw new OozieCLIException("File does not exists"); 1202 } 1203 } 1204 1205 private void pigCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1206 List<String> pigArgs = commandLine.getArgList(); 1207 if (pigArgs.size() > 0) { 1208 // checking is a pigArgs starts with -X (because CLIParser cannot check this) 1209 if (!pigArgs.get(0).equals("-X")) { 1210 throw new OozieCLIException("Unrecognized option: " + pigArgs.get(0) + " Expecting -X"); 1211 } 1212 pigArgs.remove(0); 1213 } 1214 1215 List<String> options = new ArrayList<String>(); 1216 for (Option option : commandLine.getOptions()) { 1217 options.add(option.getOpt()); 1218 } 1219 1220 if (!options.contains(PIGFILE_OPTION)) { 1221 throw new OozieCLIException("Need to specify -file <scriptfile>"); 1222 } 1223 1224 if (!options.contains(CONFIG_OPTION)) { 1225 throw new OozieCLIException("Need to specify -config <configfile>"); 1226 } 1227 1228 Properties conf = getConfiguration(commandLine); 1229 String script = commandLine.getOptionValue(PIGFILE_OPTION); 1230 1231 try { 1232 XOozieClient wc = createXOozieClient(commandLine); 1233 System.out.println(JOB_ID_PREFIX + wc.submitPig(conf, script, pigArgs.toArray(new String[pigArgs.size()]))); 1234 } 1235 catch (OozieClientException ex) { 1236 throw new OozieCLIException(ex.toString(), ex); 1237 } 1238 } 1239 }