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