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