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 import java.util.concurrent.Callable; 035 import java.util.regex.Matcher; 036 import java.util.regex.Pattern; 037 038 import javax.xml.XMLConstants; 039 import javax.xml.parsers.DocumentBuilder; 040 import javax.xml.parsers.DocumentBuilderFactory; 041 import javax.xml.parsers.ParserConfigurationException; 042 import javax.xml.transform.stream.StreamSource; 043 import javax.xml.validation.Schema; 044 import javax.xml.validation.SchemaFactory; 045 import javax.xml.validation.Validator; 046 047 import org.apache.commons.cli.CommandLine; 048 import org.apache.commons.cli.Option; 049 import org.apache.commons.cli.OptionBuilder; 050 import org.apache.commons.cli.OptionGroup; 051 import org.apache.commons.cli.Options; 052 import org.apache.commons.cli.ParseException; 053 import org.apache.oozie.BuildInfo; 054 import org.apache.oozie.client.AuthOozieClient; 055 import org.apache.oozie.client.BulkResponse; 056 import org.apache.oozie.client.BundleJob; 057 import org.apache.oozie.client.CoordinatorAction; 058 import org.apache.oozie.client.CoordinatorJob; 059 import org.apache.oozie.client.OozieClient; 060 import org.apache.oozie.client.OozieClientException; 061 import org.apache.oozie.client.WorkflowAction; 062 import org.apache.oozie.client.WorkflowJob; 063 import org.apache.oozie.client.XOozieClient; 064 import org.apache.oozie.client.OozieClient.SYSTEM_MODE; 065 import org.apache.oozie.client.rest.RestConstants; 066 import org.w3c.dom.DOMException; 067 import org.w3c.dom.Document; 068 import org.w3c.dom.Element; 069 import org.w3c.dom.Node; 070 import org.w3c.dom.NodeList; 071 import org.w3c.dom.Text; 072 import org.xml.sax.SAXException; 073 074 /** 075 * Oozie command line utility. 076 */ 077 public class OozieCLI { 078 public static final String ENV_OOZIE_URL = "OOZIE_URL"; 079 public static final String ENV_OOZIE_DEBUG = "OOZIE_DEBUG"; 080 public static final String ENV_OOZIE_TIME_ZONE = "OOZIE_TIMEZONE"; 081 public static final String WS_HEADER_PREFIX = "header:"; 082 083 public static final String HELP_CMD = "help"; 084 public static final String VERSION_CMD = "version"; 085 public static final String JOB_CMD = "job"; 086 public static final String JOBS_CMD = "jobs"; 087 public static final String ADMIN_CMD = "admin"; 088 public static final String VALIDATE_CMD = "validate"; 089 public static final String SLA_CMD = "sla"; 090 public static final String PIG_CMD = "pig"; 091 public static final String MR_CMD = "mapreduce"; 092 public static final String INFO_CMD = "info"; 093 094 public static final String OOZIE_OPTION = "oozie"; 095 public static final String CONFIG_OPTION = "config"; 096 public static final String SUBMIT_OPTION = "submit"; 097 public static final String OFFSET_OPTION = "offset"; 098 public static final String START_OPTION = "start"; 099 public static final String RUN_OPTION = "run"; 100 public static final String DRYRUN_OPTION = "dryrun"; 101 public static final String SUSPEND_OPTION = "suspend"; 102 public static final String RESUME_OPTION = "resume"; 103 public static final String KILL_OPTION = "kill"; 104 public static final String CHANGE_OPTION = "change"; 105 public static final String CHANGE_VALUE_OPTION = "value"; 106 public static final String RERUN_OPTION = "rerun"; 107 public static final String INFO_OPTION = "info"; 108 public static final String LOG_OPTION = "log"; 109 public static final String ACTION_OPTION = "action"; 110 public static final String DEFINITION_OPTION = "definition"; 111 public static final String CONFIG_CONTENT_OPTION = "configcontent"; 112 113 public static final String DO_AS_OPTION = "doas"; 114 115 public static final String LEN_OPTION = "len"; 116 public static final String FILTER_OPTION = "filter"; 117 public static final String JOBTYPE_OPTION = "jobtype"; 118 public static final String SYSTEM_MODE_OPTION = "systemmode"; 119 public static final String VERSION_OPTION = "version"; 120 public static final String STATUS_OPTION = "status"; 121 public static final String LOCAL_TIME_OPTION = "localtime"; 122 public static final String TIME_ZONE_OPTION = "timezone"; 123 public static final String QUEUE_DUMP_OPTION = "queuedump"; 124 public static final String RERUN_COORD_OPTION = "coordinator"; 125 public static final String DATE_OPTION = "date"; 126 public static final String RERUN_REFRESH_OPTION = "refresh"; 127 public static final String RERUN_NOCLEANUP_OPTION = "nocleanup"; 128 129 public static final String AUTH_OPTION = "auth"; 130 131 public static final String VERBOSE_OPTION = "verbose"; 132 public static final String VERBOSE_DELIMITER = "\t"; 133 public static final String DEBUG_OPTION = "debug"; 134 135 public static final String PIGFILE_OPTION = "file"; 136 137 public static final String INFO_TIME_ZONES_OPTION = "timezones"; 138 139 public static final String BULK_OPTION = "bulk"; 140 141 private static final String[] OOZIE_HELP = { 142 "the env variable '" + ENV_OOZIE_URL + "' is used as default value for the '-" + OOZIE_OPTION + "' option", 143 "the env variable '" + ENV_OOZIE_TIME_ZONE + "' is used as default value for the '-" + TIME_ZONE_OPTION + "' option", 144 "custom headers for Oozie web services can be specified using '-D" + WS_HEADER_PREFIX + "NAME=VALUE'" }; 145 146 private static final String RULER; 147 private static final int LINE_WIDTH = 132; 148 149 private boolean used; 150 151 private static final String INSTANCE_SEPARATOR = "#"; 152 153 private static final String MAPRED_MAPPER = "mapred.mapper.class"; 154 private static final String MAPRED_REDUCER = "mapred.reducer.class"; 155 private static final String MAPRED_INPUT = "mapred.input.dir"; 156 private static final String MAPRED_OUTPUT = "mapred.output.dir"; 157 158 private static final Pattern GMT_OFFSET_SHORTEN_PATTERN = Pattern.compile("(.* )GMT((?:-|\\+)\\d{2}:\\d{2})"); 159 160 static { 161 StringBuilder sb = new StringBuilder(); 162 for (int i = 0; i < LINE_WIDTH; i++) { 163 sb.append("-"); 164 } 165 RULER = sb.toString(); 166 } 167 168 /** 169 * Entry point for the Oozie CLI when invoked from the command line. 170 * <p/> 171 * Upon completion this method exits the JVM with '0' (success) or '-1' (failure). 172 * 173 * @param args options and arguments for the Oozie CLI. 174 */ 175 public static void main(String[] args) { 176 if (!System.getProperties().contains(AuthOozieClient.USE_AUTH_TOKEN_CACHE_SYS_PROP)) { 177 System.setProperty(AuthOozieClient.USE_AUTH_TOKEN_CACHE_SYS_PROP, "true"); 178 } 179 System.exit(new OozieCLI().run(args)); 180 } 181 182 /** 183 * Create an Oozie CLI instance. 184 */ 185 public OozieCLI() { 186 used = false; 187 } 188 189 /** 190 * Return Oozie CLI top help lines. 191 * 192 * @return help lines. 193 */ 194 protected String[] getCLIHelp() { 195 return OOZIE_HELP; 196 } 197 198 /** 199 * Add authentication specific options to oozie cli 200 * 201 * @param options the collection of options to add auth options 202 */ 203 protected void addAuthOptions(Options options) { 204 Option auth = new Option(AUTH_OPTION, true, "select authentication type [SIMPLE|KERBEROS]"); 205 options.addOption(auth); 206 } 207 208 /** 209 * Create option for command line option 'admin' 210 * @return admin options 211 */ 212 protected Options createAdminOptions() { 213 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 214 Option system_mode = new Option(SYSTEM_MODE_OPTION, true, 215 "Supported in Oozie-2.0 or later versions ONLY. Change oozie system mode [NORMAL|NOWEBSERVICE|SAFEMODE]"); 216 Option status = new Option(STATUS_OPTION, false, "show the current system status"); 217 Option version = new Option(VERSION_OPTION, false, "show Oozie server build version"); 218 Option queuedump = new Option(QUEUE_DUMP_OPTION, false, "show Oozie server queue elements"); 219 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 220 Options adminOptions = new Options(); 221 adminOptions.addOption(oozie); 222 adminOptions.addOption(doAs); 223 OptionGroup group = new OptionGroup(); 224 group.addOption(system_mode); 225 group.addOption(status); 226 group.addOption(version); 227 group.addOption(queuedump); 228 adminOptions.addOptionGroup(group); 229 addAuthOptions(adminOptions); 230 return adminOptions; 231 } 232 233 /** 234 * Create option for command line option 'job' 235 * @return job options 236 */ 237 protected Options createJobOptions() { 238 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 239 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.xml' or '.properties'"); 240 Option submit = new Option(SUBMIT_OPTION, false, "submit a job"); 241 Option run = new Option(RUN_OPTION, false, "run a job"); 242 Option debug = new Option(DEBUG_OPTION, false, "Use debug mode to see debugging statements on stdout"); 243 Option rerun = new Option(RERUN_OPTION, true, 244 "rerun a job (coordinator requires -action or -date, bundle requires -coordinator or -date)"); 245 Option dryrun = new Option(DRYRUN_OPTION, false, "Dryrun a workflow (since 3.3.2) or coordinator (since 2.0) job without" 246 + " actually executing it"); 247 Option start = new Option(START_OPTION, true, "start a job"); 248 Option suspend = new Option(SUSPEND_OPTION, true, "suspend a job"); 249 Option resume = new Option(RESUME_OPTION, true, "resume a job"); 250 Option kill = new Option(KILL_OPTION, true, "kill a job"); 251 Option change = new Option(CHANGE_OPTION, true, "change a coordinator job"); 252 Option changeValue = new Option(CHANGE_VALUE_OPTION, true, 253 "new endtime/concurrency/pausetime value for changing a coordinator job"); 254 Option info = new Option(INFO_OPTION, true, "info of a job"); 255 Option offset = new Option(OFFSET_OPTION, true, "job info offset of actions (default '1', requires -info)"); 256 Option len = new Option(LEN_OPTION, true, "number of actions (default TOTAL ACTIONS, requires -info)"); 257 Option filter = new Option(FILTER_OPTION, true, 258 "status=<S1>[;status=<S2>]* (All Coordinator actions satisfying any one of the status filters will be retreived. Currently, only supported for Coordinator job)"); 259 Option localtime = new Option(LOCAL_TIME_OPTION, false, "use local time (same as passing your time zone to -" + 260 TIME_ZONE_OPTION + "). Overrides -" + TIME_ZONE_OPTION + " option"); 261 Option timezone = new Option(TIME_ZONE_OPTION, true, 262 "use time zone with the specified ID (default GMT).\nSee 'oozie info -timezones' for a list"); 263 Option log = new Option(LOG_OPTION, true, "job log"); 264 Option definition = new Option(DEFINITION_OPTION, true, "job definition"); 265 Option config_content = new Option(CONFIG_CONTENT_OPTION, true, "job configuration"); 266 Option verbose = new Option(VERBOSE_OPTION, false, "verbose mode"); 267 Option action = new Option(ACTION_OPTION, true, 268 "coordinator rerun on action ids (requires -rerun); coordinator log retrieval on action ids (requires -log)"); 269 Option date = new Option(DATE_OPTION, true, 270 "coordinator/bundle rerun on action dates (requires -rerun); coordinator log retrieval on action dates (requires -log)"); 271 Option rerun_coord = new Option(RERUN_COORD_OPTION, true, "bundle rerun on coordinator names (requires -rerun)"); 272 Option rerun_refresh = new Option(RERUN_REFRESH_OPTION, false, 273 "re-materialize the coordinator rerun actions (requires -rerun)"); 274 Option rerun_nocleanup = new Option(RERUN_NOCLEANUP_OPTION, false, 275 "do not clean up output-events of the coordiantor rerun actions (requires -rerun)"); 276 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 277 "set/override value for given property").create("D"); 278 279 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 280 281 OptionGroup actions = new OptionGroup(); 282 actions.addOption(submit); 283 actions.addOption(start); 284 actions.addOption(run); 285 actions.addOption(dryrun); 286 actions.addOption(suspend); 287 actions.addOption(resume); 288 actions.addOption(kill); 289 actions.addOption(change); 290 actions.addOption(info); 291 actions.addOption(rerun); 292 actions.addOption(log); 293 actions.addOption(definition); 294 actions.addOption(config_content); 295 actions.setRequired(true); 296 Options jobOptions = new Options(); 297 jobOptions.addOption(oozie); 298 jobOptions.addOption(doAs); 299 jobOptions.addOption(config); 300 jobOptions.addOption(property); 301 jobOptions.addOption(changeValue); 302 jobOptions.addOption(localtime); 303 jobOptions.addOption(timezone); 304 jobOptions.addOption(verbose); 305 jobOptions.addOption(debug); 306 jobOptions.addOption(offset); 307 jobOptions.addOption(len); 308 jobOptions.addOption(filter); 309 jobOptions.addOption(action); 310 jobOptions.addOption(date); 311 jobOptions.addOption(rerun_coord); 312 jobOptions.addOption(rerun_refresh); 313 jobOptions.addOption(rerun_nocleanup); 314 jobOptions.addOptionGroup(actions); 315 addAuthOptions(jobOptions); 316 return jobOptions; 317 } 318 319 /** 320 * Create option for command line option 'jobs' 321 * @return jobs options 322 */ 323 protected Options createJobsOptions() { 324 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 325 Option start = new Option(OFFSET_OPTION, true, "jobs offset (default '1')"); 326 Option jobtype = new Option(JOBTYPE_OPTION, true, 327 "job type ('Supported in Oozie-2.0 or later versions ONLY - 'coordinator' or 'bundle' or 'wf'(default))"); 328 Option len = new Option(LEN_OPTION, true, "number of jobs (default '100')"); 329 Option filter = new Option(FILTER_OPTION, true, "user=<U>\\;name=<N>\\;group=<G>\\;status=<S>\\;frequency=<F>\\;unit=<M> " + 330 "(Valid unit values are 'months', 'days', 'hours' or 'minutes'.)"); 331 Option localtime = new Option(LOCAL_TIME_OPTION, false, "use local time (same as passing your time zone to -" + 332 TIME_ZONE_OPTION + "). Overrides -" + TIME_ZONE_OPTION + " option"); 333 Option timezone = new Option(TIME_ZONE_OPTION, true, 334 "use time zone with the specified ID (default GMT).\nSee 'oozie info -timezones' for a list"); 335 Option verbose = new Option(VERBOSE_OPTION, false, "verbose mode"); 336 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 337 Option bulkMonitor = new Option(BULK_OPTION, true, "key-value pairs to filter bulk jobs response. e.g. bundle=<B>\\;" + 338 "coordinators=<C>\\;actionstatus=<S>\\;startcreatedtime=<SC>\\;endcreatedtime=<EC>\\;" + 339 "startscheduledtime=<SS>\\;endscheduledtime=<ES>\\; coordinators and actionstatus can be multiple comma separated values" + 340 "bundle and coordinators are 'names' of those jobs. Bundle name is mandatory, other params are optional"); 341 start.setType(Integer.class); 342 len.setType(Integer.class); 343 Options jobsOptions = new Options(); 344 jobsOptions.addOption(oozie); 345 jobsOptions.addOption(doAs); 346 jobsOptions.addOption(localtime); 347 jobsOptions.addOption(timezone); 348 jobsOptions.addOption(start); 349 jobsOptions.addOption(len); 350 jobsOptions.addOption(oozie); 351 jobsOptions.addOption(filter); 352 jobsOptions.addOption(jobtype); 353 jobsOptions.addOption(verbose); 354 jobsOptions.addOption(bulkMonitor); 355 addAuthOptions(jobsOptions); 356 return jobsOptions; 357 } 358 359 /** 360 * Create option for command line option 'sla' 361 * 362 * @return sla options 363 */ 364 protected Options createSlaOptions() { 365 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 366 Option start = new Option(OFFSET_OPTION, true, "start offset (default '0')"); 367 Option len = new Option(LEN_OPTION, true, "number of results (default '100', max '1000')"); 368 Option filter = new Option(FILTER_OPTION, true, "filter of SLA events"); 369 start.setType(Integer.class); 370 len.setType(Integer.class); 371 Options slaOptions = new Options(); 372 slaOptions.addOption(start); 373 slaOptions.addOption(len); 374 slaOptions.addOption(filter); 375 slaOptions.addOption(oozie); 376 addAuthOptions(slaOptions); 377 return slaOptions; 378 } 379 380 /** 381 * Create option for command line option 'pig' 382 * @return pig options 383 */ 384 @SuppressWarnings("static-access") 385 protected Options createPigOptions() { 386 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 387 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.properties'"); 388 Option pigFile = new Option(PIGFILE_OPTION, true, "Pig script"); 389 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 390 "set/override value for given property").create("D"); 391 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 392 Options pigOptions = new Options(); 393 pigOptions.addOption(oozie); 394 pigOptions.addOption(doAs); 395 pigOptions.addOption(config); 396 pigOptions.addOption(property); 397 pigOptions.addOption(pigFile); 398 addAuthOptions(pigOptions); 399 return pigOptions; 400 } 401 402 /** 403 * Create option for command line option 'info' 404 * @return info options 405 */ 406 protected Options createInfoOptions() { 407 Option timezones = new Option(INFO_TIME_ZONES_OPTION, false, "display a list of available time zones"); 408 Options infoOptions = new Options(); 409 infoOptions.addOption(timezones); 410 return infoOptions; 411 } 412 413 /** 414 * Create option for command line option 'mapreduce' 415 * @return mapreduce options 416 */ 417 @SuppressWarnings("static-access") 418 protected Options createMROptions() { 419 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 420 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.properties'"); 421 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 422 "set/override value for given property").create("D"); 423 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 424 Options mrOptions = new Options(); 425 mrOptions.addOption(oozie); 426 mrOptions.addOption(doAs); 427 mrOptions.addOption(config); 428 mrOptions.addOption(property); 429 addAuthOptions(mrOptions); 430 return mrOptions; 431 } 432 433 /** 434 * Run a CLI programmatically. 435 * <p/> 436 * It does not exit the JVM. 437 * <p/> 438 * A CLI instance can be used only once. 439 * 440 * @param args options and arguments for the Oozie CLI. 441 * @return '0' (success), '-1' (failure). 442 */ 443 public synchronized int run(String[] args) { 444 if (used) { 445 throw new IllegalStateException("CLI instance already used"); 446 } 447 used = true; 448 449 final CLIParser parser = new CLIParser(OOZIE_OPTION, getCLIHelp()); 450 parser.addCommand(HELP_CMD, "", "display usage for all commands or specified command", new Options(), false); 451 parser.addCommand(VERSION_CMD, "", "show client version", new Options(), false); 452 parser.addCommand(JOB_CMD, "", "job operations", createJobOptions(), false); 453 parser.addCommand(JOBS_CMD, "", "jobs status", createJobsOptions(), false); 454 parser.addCommand(ADMIN_CMD, "", "admin operations", createAdminOptions(), false); 455 parser.addCommand(VALIDATE_CMD, "", "validate a workflow XML file", new Options(), true); 456 parser.addCommand(SLA_CMD, "", "sla operations (Supported in Oozie-2.0 or later)", createSlaOptions(), false); 457 parser.addCommand(PIG_CMD, "-X ", "submit a pig job, everything after '-X' are pass-through parameters to pig", 458 createPigOptions(), true); 459 parser.addCommand(INFO_CMD, "", "get more detailed info about specific topics", createInfoOptions(), false); 460 parser.addCommand(MR_CMD, "", "submit a mapreduce job", createMROptions(), false); 461 462 try { 463 final CLIParser.Command command = parser.parse(args); 464 465 String doAsUser = command.getCommandLine().getOptionValue(DO_AS_OPTION); 466 467 if (doAsUser != null) { 468 OozieClient.doAs(doAsUser, new Callable<Void>() { 469 @Override 470 public Void call() throws Exception { 471 processCommand(parser, command); 472 return null; 473 } 474 }); 475 } 476 else { 477 processCommand(parser, command); 478 } 479 480 return 0; 481 } 482 catch (OozieCLIException ex) { 483 System.err.println("Error: " + ex.getMessage()); 484 return -1; 485 } 486 catch (ParseException ex) { 487 System.err.println("Invalid sub-command: " + ex.getMessage()); 488 System.err.println(); 489 System.err.println(parser.shortHelp()); 490 return -1; 491 } 492 catch (Exception ex) { 493 ex.printStackTrace(); 494 System.err.println(ex.getMessage()); 495 return -1; 496 } 497 } 498 499 private void processCommand(CLIParser parser, CLIParser.Command command) throws Exception { 500 if (command.getName().equals(HELP_CMD)) { 501 parser.showHelp(command.getCommandLine()); 502 } 503 else if (command.getName().equals(JOB_CMD)) { 504 jobCommand(command.getCommandLine()); 505 } 506 else if (command.getName().equals(JOBS_CMD)) { 507 jobsCommand(command.getCommandLine()); 508 } 509 else if (command.getName().equals(ADMIN_CMD)) { 510 adminCommand(command.getCommandLine()); 511 } 512 else if (command.getName().equals(VERSION_CMD)) { 513 versionCommand(); 514 } 515 else if (command.getName().equals(VALIDATE_CMD)) { 516 validateCommand(command.getCommandLine()); 517 } 518 else if (command.getName().equals(SLA_CMD)) { 519 slaCommand(command.getCommandLine()); 520 } 521 else if (command.getName().equals(PIG_CMD)) { 522 pigCommand(command.getCommandLine()); 523 } 524 else if (command.getName().equals(INFO_CMD)) { 525 infoCommand(command.getCommandLine()); 526 } 527 else if (command.getName().equals(MR_CMD)){ 528 mrCommand(command.getCommandLine()); 529 } 530 } 531 protected String getOozieUrl(CommandLine commandLine) { 532 String url = commandLine.getOptionValue(OOZIE_OPTION); 533 if (url == null) { 534 url = System.getenv(ENV_OOZIE_URL); 535 if (url == null) { 536 throw new IllegalArgumentException( 537 "Oozie URL is not available neither in command option or in the environment"); 538 } 539 } 540 return url; 541 } 542 543 private String getTimeZoneId(CommandLine commandLine) 544 { 545 if (commandLine.hasOption(LOCAL_TIME_OPTION)) { 546 return null; 547 } 548 if (commandLine.hasOption(TIME_ZONE_OPTION)) { 549 return commandLine.getOptionValue(TIME_ZONE_OPTION); 550 } 551 String timeZoneId = System.getenv(ENV_OOZIE_TIME_ZONE); 552 if (timeZoneId != null) { 553 return timeZoneId; 554 } 555 return "GMT"; 556 } 557 558 // Canibalized from Hadoop <code>Configuration.loadResource()</code>. 559 private Properties parse(InputStream is, Properties conf) throws IOException { 560 try { 561 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 562 // ignore all comments inside the xml file 563 docBuilderFactory.setIgnoringComments(true); 564 DocumentBuilder builder = docBuilderFactory.newDocumentBuilder(); 565 Document doc = builder.parse(is); 566 return parseDocument(doc, conf); 567 } 568 catch (SAXException e) { 569 throw new IOException(e); 570 } 571 catch (ParserConfigurationException e) { 572 throw new IOException(e); 573 } 574 } 575 576 // Canibalized from Hadoop <code>Configuration.loadResource()</code>. 577 private Properties parseDocument(Document doc, Properties conf) throws IOException { 578 try { 579 Element root = doc.getDocumentElement(); 580 if (!"configuration".equals(root.getTagName())) { 581 throw new RuntimeException("bad conf file: top-level element not <configuration>"); 582 } 583 NodeList props = root.getChildNodes(); 584 for (int i = 0; i < props.getLength(); i++) { 585 Node propNode = props.item(i); 586 if (!(propNode instanceof Element)) { 587 continue; 588 } 589 Element prop = (Element) propNode; 590 if (!"property".equals(prop.getTagName())) { 591 throw new RuntimeException("bad conf file: element not <property>"); 592 } 593 NodeList fields = prop.getChildNodes(); 594 String attr = null; 595 String value = null; 596 for (int j = 0; j < fields.getLength(); j++) { 597 Node fieldNode = fields.item(j); 598 if (!(fieldNode instanceof Element)) { 599 continue; 600 } 601 Element field = (Element) fieldNode; 602 if ("name".equals(field.getTagName()) && field.hasChildNodes()) { 603 attr = ((Text) field.getFirstChild()).getData(); 604 } 605 if ("value".equals(field.getTagName()) && field.hasChildNodes()) { 606 value = ((Text) field.getFirstChild()).getData(); 607 } 608 } 609 610 if (attr != null && value != null) { 611 conf.setProperty(attr, value); 612 } 613 } 614 return conf; 615 } 616 catch (DOMException e) { 617 throw new IOException(e); 618 } 619 } 620 621 private Properties getConfiguration(OozieClient wc, CommandLine commandLine) throws IOException { 622 Properties conf = wc.createConfiguration(); 623 String configFile = commandLine.getOptionValue(CONFIG_OPTION); 624 if (configFile == null) { 625 throw new IOException("configuration file not specified"); 626 } 627 else { 628 File file = new File(configFile); 629 if (!file.exists()) { 630 throw new IOException("configuration file [" + configFile + "] not found"); 631 } 632 if (configFile.endsWith(".properties")) { 633 conf.load(new FileReader(file)); 634 } 635 else if (configFile.endsWith(".xml")) { 636 parse(new FileInputStream(configFile), conf); 637 } 638 else { 639 throw new IllegalArgumentException("configuration must be a '.properties' or a '.xml' file"); 640 } 641 } 642 if (commandLine.hasOption("D")) { 643 Properties commandLineProperties = commandLine.getOptionProperties("D"); 644 conf.putAll(commandLineProperties); 645 } 646 return conf; 647 } 648 649 /** 650 * @param commandLine command line string. 651 * @return change value specified by -value. 652 * @throws OozieCLIException 653 */ 654 private String getChangeValue(CommandLine commandLine) throws OozieCLIException { 655 String changeValue = commandLine.getOptionValue(CHANGE_VALUE_OPTION); 656 657 if (changeValue == null) { 658 throw new OozieCLIException("-value option needs to be specified for -change option"); 659 } 660 661 return changeValue; 662 } 663 664 protected void addHeader(OozieClient wc) { 665 for (Map.Entry entry : System.getProperties().entrySet()) { 666 String key = (String) entry.getKey(); 667 if (key.startsWith(WS_HEADER_PREFIX)) { 668 String header = key.substring(WS_HEADER_PREFIX.length()); 669 wc.setHeader(header, (String) entry.getValue()); 670 } 671 } 672 } 673 674 /** 675 * Get auth option from command line 676 * 677 * @param commandLine the command line object 678 * @return auth option 679 */ 680 protected String getAuthOption(CommandLine commandLine) { 681 String authOpt = commandLine.getOptionValue(AUTH_OPTION); 682 return authOpt; 683 } 684 685 /** 686 * Create a OozieClient. 687 * <p/> 688 * It injects any '-Dheader:' as header to the the {@link org.apache.oozie.client.OozieClient}. 689 * 690 * @param commandLine the parsed command line options. 691 * @return a pre configured eXtended workflow client. 692 * @throws OozieCLIException thrown if the OozieClient could not be configured. 693 */ 694 protected OozieClient createOozieClient(CommandLine commandLine) throws OozieCLIException { 695 return createXOozieClient(commandLine); 696 } 697 698 /** 699 * Create a XOozieClient. 700 * <p/> 701 * It injects any '-Dheader:' as header to the the {@link org.apache.oozie.client.OozieClient}. 702 * 703 * @param commandLine the parsed command line options. 704 * @return a pre configured eXtended workflow client. 705 * @throws OozieCLIException thrown if the XOozieClient could not be configured. 706 */ 707 protected XOozieClient createXOozieClient(CommandLine commandLine) throws OozieCLIException { 708 XOozieClient wc = new AuthOozieClient(getOozieUrl(commandLine), getAuthOption(commandLine)); 709 addHeader(wc); 710 setDebugMode(wc,commandLine.hasOption(DEBUG_OPTION)); 711 return wc; 712 } 713 714 protected void setDebugMode(OozieClient wc, boolean debugOpt) { 715 716 String debug = System.getenv(ENV_OOZIE_DEBUG); 717 if (debug != null && !debug.isEmpty()) { 718 int debugVal = 0; 719 try { 720 debugVal = Integer.parseInt(debug.trim()); 721 } 722 catch (Exception ex) { 723 System.out.println("Unable to parse the debug settings. May be not an integer [" + debug + "]"); 724 ex.printStackTrace(); 725 } 726 wc.setDebugMode(debugVal); 727 } 728 else if(debugOpt){ // CLI argument "-debug" used 729 wc.setDebugMode(1); 730 } 731 } 732 733 private static String JOB_ID_PREFIX = "job: "; 734 735 private void jobCommand(CommandLine commandLine) throws IOException, OozieCLIException { 736 XOozieClient wc = createXOozieClient(commandLine); 737 738 List<String> options = new ArrayList<String>(); 739 for (Option option : commandLine.getOptions()) { 740 options.add(option.getOpt()); 741 } 742 743 try { 744 if (options.contains(SUBMIT_OPTION)) { 745 System.out.println(JOB_ID_PREFIX + wc.submit(getConfiguration(wc, commandLine))); 746 } 747 else if (options.contains(START_OPTION)) { 748 wc.start(commandLine.getOptionValue(START_OPTION)); 749 } 750 else if (options.contains(DRYRUN_OPTION)) { 751 String dryrunStr = wc.dryrun(getConfiguration(wc, commandLine)); 752 if (dryrunStr.equals("OK")) { // workflow 753 System.out.println("OK"); 754 } else { // coordinator 755 String[] dryrunStrs = dryrunStr.split("action for new instance"); 756 int arraysize = dryrunStrs.length; 757 System.out.println("***coordJob after parsing: ***"); 758 System.out.println(dryrunStrs[0]); 759 int aLen = dryrunStrs.length - 1; 760 if (aLen < 0) { 761 aLen = 0; 762 } 763 System.out.println("***total coord actions is " + aLen + " ***"); 764 for (int i = 1; i <= arraysize - 1; i++) { 765 System.out.println(RULER); 766 System.out.println("coordAction instance: " + i + ":"); 767 System.out.println(dryrunStrs[i]); 768 } 769 } 770 } 771 else if (options.contains(SUSPEND_OPTION)) { 772 wc.suspend(commandLine.getOptionValue(SUSPEND_OPTION)); 773 } 774 else if (options.contains(RESUME_OPTION)) { 775 wc.resume(commandLine.getOptionValue(RESUME_OPTION)); 776 } 777 else if (options.contains(KILL_OPTION)) { 778 wc.kill(commandLine.getOptionValue(KILL_OPTION)); 779 } 780 else if (options.contains(CHANGE_OPTION)) { 781 wc.change(commandLine.getOptionValue(CHANGE_OPTION), getChangeValue(commandLine)); 782 } 783 else if (options.contains(RUN_OPTION)) { 784 System.out.println(JOB_ID_PREFIX + wc.run(getConfiguration(wc, commandLine))); 785 } 786 else if (options.contains(RERUN_OPTION)) { 787 if (commandLine.getOptionValue(RERUN_OPTION).contains("-W")) { 788 wc.reRun(commandLine.getOptionValue(RERUN_OPTION), getConfiguration(wc, commandLine)); 789 } 790 else if (commandLine.getOptionValue(RERUN_OPTION).contains("-B")) { 791 String bundleJobId = commandLine.getOptionValue(RERUN_OPTION); 792 String coordScope = null; 793 String dateScope = null; 794 boolean refresh = false; 795 boolean noCleanup = false; 796 if (options.contains(ACTION_OPTION)) { 797 throw new OozieCLIException("Invalid options provided for bundle rerun. " + ACTION_OPTION 798 + " is not valid for bundle rerun"); 799 } 800 if (options.contains(DATE_OPTION)) { 801 dateScope = commandLine.getOptionValue(DATE_OPTION); 802 } 803 804 if (options.contains(RERUN_COORD_OPTION)) { 805 coordScope = commandLine.getOptionValue(RERUN_COORD_OPTION); 806 } 807 808 if (options.contains(RERUN_REFRESH_OPTION)) { 809 refresh = true; 810 } 811 if (options.contains(RERUN_NOCLEANUP_OPTION)) { 812 noCleanup = true; 813 } 814 wc.reRunBundle(bundleJobId, coordScope, dateScope, refresh, noCleanup); 815 if (coordScope != null && !coordScope.isEmpty()) { 816 System.out.println("Coordinators [" + coordScope + "] of bundle " + bundleJobId 817 + " are scheduled to rerun on date ranges [" + dateScope + "]."); 818 } 819 else { 820 System.out.println("All coordinators of bundle " + bundleJobId 821 + " are scheduled to rerun on the date ranges [" + dateScope + "]."); 822 } 823 } 824 else { 825 String coordJobId = commandLine.getOptionValue(RERUN_OPTION); 826 String scope = null; 827 String rerunType = null; 828 boolean refresh = false; 829 boolean noCleanup = false; 830 if (options.contains(DATE_OPTION) && options.contains(ACTION_OPTION)) { 831 throw new OozieCLIException("Invalid options provided for rerun: either" + DATE_OPTION + " or " 832 + ACTION_OPTION + " expected. Don't use both at the same time."); 833 } 834 if (options.contains(DATE_OPTION)) { 835 rerunType = RestConstants.JOB_COORD_RERUN_DATE; 836 scope = commandLine.getOptionValue(DATE_OPTION); 837 } 838 else if (options.contains(ACTION_OPTION)) { 839 rerunType = RestConstants.JOB_COORD_RERUN_ACTION; 840 scope = commandLine.getOptionValue(ACTION_OPTION); 841 } 842 else { 843 throw new OozieCLIException("Invalid options provided for rerun: " + DATE_OPTION + " or " 844 + ACTION_OPTION + " expected."); 845 } 846 if (options.contains(RERUN_REFRESH_OPTION)) { 847 refresh = true; 848 } 849 if (options.contains(RERUN_NOCLEANUP_OPTION)) { 850 noCleanup = true; 851 } 852 printRerunCoordActions(wc.reRunCoord(coordJobId, rerunType, scope, refresh, noCleanup)); 853 } 854 } 855 else if (options.contains(INFO_OPTION)) { 856 String timeZoneId = getTimeZoneId(commandLine); 857 if (commandLine.getOptionValue(INFO_OPTION).endsWith("-B")) { 858 String filter = commandLine.getOptionValue(FILTER_OPTION); 859 if (filter != null) { 860 throw new OozieCLIException("Filter option is currently not supported for a Bundle job"); 861 } 862 printBundleJob(wc.getBundleJobInfo(commandLine.getOptionValue(INFO_OPTION)), timeZoneId, 863 options.contains(VERBOSE_OPTION)); 864 } 865 else if (commandLine.getOptionValue(INFO_OPTION).endsWith("-C")) { 866 String s = commandLine.getOptionValue(OFFSET_OPTION); 867 int start = Integer.parseInt((s != null) ? s : "0"); 868 s = commandLine.getOptionValue(LEN_OPTION); 869 int len = Integer.parseInt((s != null) ? s : "0"); 870 String filter = commandLine.getOptionValue(FILTER_OPTION); 871 printCoordJob(wc.getCoordJobInfo(commandLine.getOptionValue(INFO_OPTION), filter, start, len), timeZoneId, 872 options.contains(VERBOSE_OPTION)); 873 } 874 else if (commandLine.getOptionValue(INFO_OPTION).contains("-C@")) { 875 String filter = commandLine.getOptionValue(FILTER_OPTION); 876 if (filter != null) { 877 throw new OozieCLIException("Filter option is not supported for a Coordinator action"); 878 } 879 printCoordAction(wc.getCoordActionInfo(commandLine.getOptionValue(INFO_OPTION)), timeZoneId); 880 } 881 else if (commandLine.getOptionValue(INFO_OPTION).contains("-W@")) { 882 String filter = commandLine.getOptionValue(FILTER_OPTION); 883 if (filter != null) { 884 throw new OozieCLIException("Filter option is not supported for a Workflow action"); 885 } 886 printWorkflowAction(wc.getWorkflowActionInfo(commandLine.getOptionValue(INFO_OPTION)), timeZoneId, 887 options.contains(VERBOSE_OPTION)); 888 } 889 else { 890 String filter = commandLine.getOptionValue(FILTER_OPTION); 891 if (filter != null) { 892 throw new OozieCLIException("Filter option is currently not supported for a Workflow job"); 893 } 894 String s = commandLine.getOptionValue(OFFSET_OPTION); 895 int start = Integer.parseInt((s != null) ? s : "0"); 896 s = commandLine.getOptionValue(LEN_OPTION); 897 String jobtype = commandLine.getOptionValue(JOBTYPE_OPTION); 898 jobtype = (jobtype != null) ? jobtype : "wf"; 899 int len = Integer.parseInt((s != null) ? s : "0"); 900 printJob(wc.getJobInfo(commandLine.getOptionValue(INFO_OPTION), start, len), timeZoneId, 901 options.contains(VERBOSE_OPTION)); 902 } 903 } 904 else if (options.contains(LOG_OPTION)) { 905 PrintStream ps = System.out; 906 if (commandLine.getOptionValue(LOG_OPTION).contains("-C")) { 907 String logRetrievalScope = null; 908 String logRetrievalType = null; 909 if (options.contains(ACTION_OPTION)) { 910 logRetrievalType = RestConstants.JOB_LOG_ACTION; 911 logRetrievalScope = commandLine.getOptionValue(ACTION_OPTION); 912 } 913 if (options.contains(DATE_OPTION)) { 914 logRetrievalType = RestConstants.JOB_LOG_DATE; 915 logRetrievalScope = commandLine.getOptionValue(DATE_OPTION); 916 } 917 try { 918 wc.getJobLog(commandLine.getOptionValue(LOG_OPTION), logRetrievalType, logRetrievalScope, ps); 919 } 920 finally { 921 ps.close(); 922 } 923 } 924 else { 925 if (!options.contains(ACTION_OPTION) && !options.contains(DATE_OPTION)) { 926 wc.getJobLog(commandLine.getOptionValue(LOG_OPTION), null, null, ps); 927 } 928 else { 929 throw new OozieCLIException("Invalid options provided for log retrieval. " + ACTION_OPTION 930 + " and " + DATE_OPTION + " are valid only for coordinator job log retrieval"); 931 } 932 } 933 } 934 else if (options.contains(DEFINITION_OPTION)) { 935 System.out.println(wc.getJobDefinition(commandLine.getOptionValue(DEFINITION_OPTION))); 936 } 937 else if (options.contains(CONFIG_CONTENT_OPTION)) { 938 if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-C")) { 939 System.out.println(wc.getCoordJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 940 } 941 else if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-W")) { 942 System.out.println(wc.getJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 943 } 944 else if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-B")) { 945 System.out 946 .println(wc.getBundleJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 947 } 948 else { 949 System.out.println("ERROR: job id [" + commandLine.getOptionValue(CONFIG_CONTENT_OPTION) 950 + "] doesn't end with either C or W or B"); 951 } 952 } 953 } 954 catch (OozieClientException ex) { 955 throw new OozieCLIException(ex.toString(), ex); 956 } 957 } 958 959 private void printCoordJob(CoordinatorJob coordJob, String timeZoneId, boolean verbose) { 960 System.out.println("Job ID : " + coordJob.getId()); 961 962 System.out.println(RULER); 963 964 List<CoordinatorAction> actions = coordJob.getActions(); 965 System.out.println("Job Name : " + maskIfNull(coordJob.getAppName())); 966 System.out.println("App Path : " + maskIfNull(coordJob.getAppPath())); 967 System.out.println("Status : " + coordJob.getStatus()); 968 System.out.println("Start Time : " + maskDate(coordJob.getStartTime(), timeZoneId, false)); 969 System.out.println("End Time : " + maskDate(coordJob.getEndTime(), timeZoneId, false)); 970 System.out.println("Pause Time : " + maskDate(coordJob.getPauseTime(), timeZoneId, false)); 971 System.out.println("Concurrency : " + coordJob.getConcurrency()); 972 System.out.println(RULER); 973 974 if (verbose) { 975 System.out.println("ID" + VERBOSE_DELIMITER + "Action Number" + VERBOSE_DELIMITER + "Console URL" 976 + VERBOSE_DELIMITER + "Error Code" + VERBOSE_DELIMITER + "Error Message" + VERBOSE_DELIMITER 977 + "External ID" + VERBOSE_DELIMITER + "External Status" + VERBOSE_DELIMITER + "Job ID" 978 + VERBOSE_DELIMITER + "Tracker URI" + VERBOSE_DELIMITER + "Created" + VERBOSE_DELIMITER 979 + "Nominal Time" + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Last Modified" 980 + VERBOSE_DELIMITER + "Missing Dependencies"); 981 System.out.println(RULER); 982 983 for (CoordinatorAction action : actions) { 984 String missingDep = action.getMissingDependencies(); 985 if(missingDep != null && !missingDep.isEmpty()) { 986 missingDep = missingDep.split(INSTANCE_SEPARATOR)[0]; 987 } 988 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER + action.getActionNumber() 989 + VERBOSE_DELIMITER + maskIfNull(action.getConsoleUrl()) + VERBOSE_DELIMITER 990 + maskIfNull(action.getErrorCode()) + VERBOSE_DELIMITER + maskIfNull(action.getErrorMessage()) 991 + VERBOSE_DELIMITER + maskIfNull(action.getExternalId()) + VERBOSE_DELIMITER 992 + maskIfNull(action.getExternalStatus()) + VERBOSE_DELIMITER + maskIfNull(action.getJobId()) 993 + VERBOSE_DELIMITER + maskIfNull(action.getTrackerUri()) + VERBOSE_DELIMITER 994 + maskDate(action.getCreatedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 995 + maskDate(action.getNominalTime(), timeZoneId, verbose) + action.getStatus() + VERBOSE_DELIMITER 996 + maskDate(action.getLastModifiedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 997 + maskIfNull(missingDep)); 998 999 System.out.println(RULER); 1000 } 1001 } 1002 else { 1003 System.out.println(String.format(COORD_ACTION_FORMATTER, "ID", "Status", "Ext ID", "Err Code", "Created", 1004 "Nominal Time", "Last Mod")); 1005 1006 for (CoordinatorAction action : actions) { 1007 System.out.println(String.format(COORD_ACTION_FORMATTER, maskIfNull(action.getId()), 1008 action.getStatus(), maskIfNull(action.getExternalId()), maskIfNull(action.getErrorCode()), 1009 maskDate(action.getCreatedTime(), timeZoneId, verbose), maskDate(action.getNominalTime(), timeZoneId, verbose), 1010 maskDate(action.getLastModifiedTime(), timeZoneId, verbose))); 1011 1012 System.out.println(RULER); 1013 } 1014 } 1015 } 1016 1017 private void printBundleJob(BundleJob bundleJob, String timeZoneId, boolean verbose) { 1018 System.out.println("Job ID : " + bundleJob.getId()); 1019 1020 System.out.println(RULER); 1021 1022 List<CoordinatorJob> coordinators = bundleJob.getCoordinators(); 1023 System.out.println("Job Name : " + maskIfNull(bundleJob.getAppName())); 1024 System.out.println("App Path : " + maskIfNull(bundleJob.getAppPath())); 1025 System.out.println("Status : " + bundleJob.getStatus()); 1026 System.out.println("Kickoff time : " + bundleJob.getKickoffTime()); 1027 System.out.println(RULER); 1028 1029 System.out.println(String.format(BUNDLE_COORD_JOBS_FORMATTER, "Job ID", "Status", "Freq", "Unit", "Started", 1030 "Next Materialized")); 1031 System.out.println(RULER); 1032 1033 for (CoordinatorJob job : coordinators) { 1034 System.out.println(String.format(BUNDLE_COORD_JOBS_FORMATTER, maskIfNull(job.getId()), job.getStatus(), 1035 job.getFrequency(), job.getTimeUnit(), maskDate(job.getStartTime(), timeZoneId, verbose), 1036 maskDate(job.getNextMaterializedTime(), timeZoneId, verbose))); 1037 1038 System.out.println(RULER); 1039 } 1040 } 1041 1042 private void printCoordAction(CoordinatorAction coordAction, String timeZoneId) { 1043 System.out.println("ID : " + maskIfNull(coordAction.getId())); 1044 1045 System.out.println(RULER); 1046 1047 System.out.println("Action Number : " + coordAction.getActionNumber()); 1048 System.out.println("Console URL : " + maskIfNull(coordAction.getConsoleUrl())); 1049 System.out.println("Error Code : " + maskIfNull(coordAction.getErrorCode())); 1050 System.out.println("Error Message : " + maskIfNull(coordAction.getErrorMessage())); 1051 System.out.println("External ID : " + maskIfNull(coordAction.getExternalId())); 1052 System.out.println("External Status : " + maskIfNull(coordAction.getExternalStatus())); 1053 System.out.println("Job ID : " + maskIfNull(coordAction.getJobId())); 1054 System.out.println("Tracker URI : " + maskIfNull(coordAction.getTrackerUri())); 1055 System.out.println("Created : " + maskDate(coordAction.getCreatedTime(), timeZoneId, false)); 1056 System.out.println("Nominal Time : " + maskDate(coordAction.getNominalTime(), timeZoneId, false)); 1057 System.out.println("Status : " + coordAction.getStatus()); 1058 System.out.println("Last Modified : " + maskDate(coordAction.getLastModifiedTime(), timeZoneId, false)); 1059 String missingDep = coordAction.getMissingDependencies(); 1060 if(missingDep != null && !missingDep.isEmpty()) { 1061 missingDep = missingDep.split(INSTANCE_SEPARATOR)[0]; 1062 } 1063 System.out.println("First Missing Dependency : " + maskIfNull(missingDep)); 1064 1065 System.out.println(RULER); 1066 } 1067 1068 private void printRerunCoordActions(List<CoordinatorAction> actions) { 1069 if (actions != null && actions.size() > 0) { 1070 System.out.println("Action ID" + VERBOSE_DELIMITER + "Nominal Time"); 1071 System.out.println(RULER); 1072 for (CoordinatorAction action : actions) { 1073 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER 1074 + maskDate(action.getNominalTime(), null,false)); 1075 } 1076 } 1077 else { 1078 System.out.println("No Actions match your rerun criteria!"); 1079 } 1080 } 1081 1082 private void printWorkflowAction(WorkflowAction action, String timeZoneId, boolean verbose) { 1083 System.out.println("ID : " + maskIfNull(action.getId())); 1084 1085 System.out.println(RULER); 1086 1087 System.out.println("Console URL : " + maskIfNull(action.getConsoleUrl())); 1088 System.out.println("Error Code : " + maskIfNull(action.getErrorCode())); 1089 System.out.println("Error Message : " + maskIfNull(action.getErrorMessage())); 1090 System.out.println("External ID : " + maskIfNull(action.getExternalId())); 1091 System.out.println("External Status : " + maskIfNull(action.getExternalStatus())); 1092 System.out.println("Name : " + maskIfNull(action.getName())); 1093 System.out.println("Retries : " + action.getRetries()); 1094 System.out.println("Tracker URI : " + maskIfNull(action.getTrackerUri())); 1095 System.out.println("Type : " + maskIfNull(action.getType())); 1096 System.out.println("Started : " + maskDate(action.getStartTime(), timeZoneId, verbose)); 1097 System.out.println("Status : " + action.getStatus()); 1098 System.out.println("Ended : " + maskDate(action.getEndTime(), timeZoneId, verbose)); 1099 1100 if (verbose) { 1101 System.out.println("External Stats : " + action.getStats()); 1102 System.out.println("External ChildIDs : " + action.getExternalChildIDs()); 1103 } 1104 1105 System.out.println(RULER); 1106 } 1107 1108 private static final String WORKFLOW_JOBS_FORMATTER = "%-41s%-13s%-10s%-10s%-10s%-24s%-24s"; 1109 private static final String COORD_JOBS_FORMATTER = "%-41s%-15s%-10s%-5s%-13s%-24s%-24s"; 1110 private static final String BUNDLE_JOBS_FORMATTER = "%-41s%-15s%-10s%-20s%-20s%-13s%-13s"; 1111 private static final String BUNDLE_COORD_JOBS_FORMATTER = "%-41s%-10s%-5s%-13s%-24s%-24s"; 1112 1113 private static final String WORKFLOW_ACTION_FORMATTER = "%-78s%-10s%-23s%-11s%-10s"; 1114 private static final String COORD_ACTION_FORMATTER = "%-43s%-10s%-37s%-10s%-21s%-21s"; 1115 private static final String BULK_RESPONSE_FORMATTER = "%-41s%-41s%-37s%-37s%-13s%-21s%-24s"; 1116 1117 private void printJob(WorkflowJob job, String timeZoneId, boolean verbose) throws IOException { 1118 System.out.println("Job ID : " + maskIfNull(job.getId())); 1119 1120 System.out.println(RULER); 1121 1122 System.out.println("Workflow Name : " + maskIfNull(job.getAppName())); 1123 System.out.println("App Path : " + maskIfNull(job.getAppPath())); 1124 System.out.println("Status : " + job.getStatus()); 1125 System.out.println("Run : " + job.getRun()); 1126 System.out.println("User : " + maskIfNull(job.getUser())); 1127 System.out.println("Group : " + maskIfNull(job.getGroup())); 1128 System.out.println("Created : " + maskDate(job.getCreatedTime(), timeZoneId, verbose)); 1129 System.out.println("Started : " + maskDate(job.getStartTime(), timeZoneId, verbose)); 1130 System.out.println("Last Modified : " + maskDate(job.getLastModifiedTime(), timeZoneId, verbose)); 1131 System.out.println("Ended : " + maskDate(job.getEndTime(), timeZoneId, verbose)); 1132 System.out.println("CoordAction ID: " + maskIfNull(job.getParentId())); 1133 1134 List<WorkflowAction> actions = job.getActions(); 1135 1136 if (actions != null && actions.size() > 0) { 1137 System.out.println(); 1138 System.out.println("Actions"); 1139 System.out.println(RULER); 1140 1141 if (verbose) { 1142 System.out.println("ID" + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "Error Code" 1143 + VERBOSE_DELIMITER + "Error Message" + VERBOSE_DELIMITER + "External ID" + VERBOSE_DELIMITER 1144 + "External Status" + VERBOSE_DELIMITER + "Name" + VERBOSE_DELIMITER + "Retries" 1145 + VERBOSE_DELIMITER + "Tracker URI" + VERBOSE_DELIMITER + "Type" + VERBOSE_DELIMITER 1146 + "Started" + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Ended"); 1147 System.out.println(RULER); 1148 1149 for (WorkflowAction action : job.getActions()) { 1150 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER 1151 + maskIfNull(action.getConsoleUrl()) + VERBOSE_DELIMITER 1152 + maskIfNull(action.getErrorCode()) + VERBOSE_DELIMITER 1153 + maskIfNull(action.getErrorMessage()) + VERBOSE_DELIMITER 1154 + maskIfNull(action.getExternalId()) + VERBOSE_DELIMITER 1155 + maskIfNull(action.getExternalStatus()) + VERBOSE_DELIMITER + maskIfNull(action.getName()) 1156 + VERBOSE_DELIMITER + action.getRetries() + VERBOSE_DELIMITER 1157 + maskIfNull(action.getTrackerUri()) + VERBOSE_DELIMITER + maskIfNull(action.getType()) 1158 + VERBOSE_DELIMITER + maskDate(action.getStartTime(), timeZoneId, verbose) 1159 + VERBOSE_DELIMITER + action.getStatus() + VERBOSE_DELIMITER 1160 + maskDate(action.getEndTime(), timeZoneId, verbose)); 1161 1162 System.out.println(RULER); 1163 } 1164 } 1165 else { 1166 System.out.println(String.format(WORKFLOW_ACTION_FORMATTER, "ID", "Status", "Ext ID", "Ext Status", 1167 "Err Code")); 1168 1169 System.out.println(RULER); 1170 1171 for (WorkflowAction action : job.getActions()) { 1172 System.out.println(String.format(WORKFLOW_ACTION_FORMATTER, maskIfNull(action.getId()), action 1173 .getStatus(), maskIfNull(action.getExternalId()), maskIfNull(action.getExternalStatus()), 1174 maskIfNull(action.getErrorCode()))); 1175 1176 System.out.println(RULER); 1177 } 1178 } 1179 } 1180 else { 1181 System.out.println(RULER); 1182 } 1183 1184 System.out.println(); 1185 } 1186 1187 private void jobsCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1188 XOozieClient wc = createXOozieClient(commandLine); 1189 1190 String filter = commandLine.getOptionValue(FILTER_OPTION); 1191 String s = commandLine.getOptionValue(OFFSET_OPTION); 1192 int start = Integer.parseInt((s != null) ? s : "0"); 1193 s = commandLine.getOptionValue(LEN_OPTION); 1194 String jobtype = commandLine.getOptionValue(JOBTYPE_OPTION); 1195 String timeZoneId = getTimeZoneId(commandLine); 1196 jobtype = (jobtype != null) ? jobtype : "wf"; 1197 int len = Integer.parseInt((s != null) ? s : "0"); 1198 String bulkFilterString = commandLine.getOptionValue(BULK_OPTION); 1199 1200 try { 1201 if (bulkFilterString != null) { 1202 printBulkJobs(wc.getBulkInfo(bulkFilterString, start, len), timeZoneId); 1203 } 1204 else if (jobtype.toLowerCase().contains("wf")) { 1205 printJobs(wc.getJobsInfo(filter, start, len), timeZoneId, commandLine.hasOption(VERBOSE_OPTION)); 1206 } 1207 else if (jobtype.toLowerCase().startsWith("coord")) { 1208 printCoordJobs(wc.getCoordJobsInfo(filter, start, len), timeZoneId, commandLine.hasOption(VERBOSE_OPTION)); 1209 } 1210 else if (jobtype.toLowerCase().startsWith("bundle")) { 1211 printBundleJobs(wc.getBundleJobsInfo(filter, start, len), timeZoneId, commandLine.hasOption(VERBOSE_OPTION)); 1212 } 1213 1214 } 1215 catch (OozieClientException ex) { 1216 throw new OozieCLIException(ex.toString(), ex); 1217 } 1218 } 1219 1220 private void printCoordJobs(List<CoordinatorJob> jobs, String timeZoneId, boolean verbose) throws IOException { 1221 if (jobs != null && jobs.size() > 0) { 1222 if (verbose) { 1223 System.out.println("Job ID" + VERBOSE_DELIMITER + "App Name" + VERBOSE_DELIMITER + "App Path" 1224 + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" 1225 + VERBOSE_DELIMITER + "Concurrency" + VERBOSE_DELIMITER + "Frequency" + VERBOSE_DELIMITER 1226 + "Time Unit" + VERBOSE_DELIMITER + "Time Zone" + VERBOSE_DELIMITER + "Time Out" 1227 + VERBOSE_DELIMITER + "Started" + VERBOSE_DELIMITER + "Next Materialize" + VERBOSE_DELIMITER 1228 + "Status" + VERBOSE_DELIMITER + "Last Action" + VERBOSE_DELIMITER + "Ended"); 1229 System.out.println(RULER); 1230 1231 for (CoordinatorJob job : jobs) { 1232 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1233 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1234 + maskIfNull(job.getConsoleUrl()) + VERBOSE_DELIMITER + maskIfNull(job.getUser()) 1235 + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) + VERBOSE_DELIMITER + job.getConcurrency() 1236 + VERBOSE_DELIMITER + job.getFrequency() + VERBOSE_DELIMITER + job.getTimeUnit() 1237 + VERBOSE_DELIMITER + maskIfNull(job.getTimeZone()) + VERBOSE_DELIMITER + job.getTimeout() 1238 + VERBOSE_DELIMITER + maskDate(job.getStartTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1239 + maskDate(job.getNextMaterializedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1240 + job.getStatus() + VERBOSE_DELIMITER 1241 + maskDate(job.getLastActionTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1242 + maskDate(job.getEndTime(), timeZoneId, verbose)); 1243 1244 System.out.println(RULER); 1245 } 1246 } 1247 else { 1248 System.out.println(String.format(COORD_JOBS_FORMATTER, "Job ID", "App Name", "Status", "Freq", "Unit", 1249 "Started", "Next Materialized")); 1250 System.out.println(RULER); 1251 1252 for (CoordinatorJob job : jobs) { 1253 System.out.println(String.format(COORD_JOBS_FORMATTER, maskIfNull(job.getId()), maskIfNull(job 1254 .getAppName()), job.getStatus(), job.getFrequency(), job.getTimeUnit(), maskDate(job 1255 .getStartTime(), timeZoneId, verbose), maskDate(job.getNextMaterializedTime(), timeZoneId, verbose))); 1256 1257 System.out.println(RULER); 1258 } 1259 } 1260 } 1261 else { 1262 System.out.println("No Jobs match your criteria!"); 1263 } 1264 } 1265 1266 private void printBulkJobs(List<BulkResponse> jobs, String timeZoneId) throws IOException { 1267 if (jobs != null && jobs.size() > 0) { 1268 System.out.println(String.format(BULK_RESPONSE_FORMATTER, "Bundle Name", "Coordinator Name", 1269 "Coord Action ID", "External ID", "Status", "Created Time", "Error Message")); 1270 1271 for (BulkResponse response : jobs) { 1272 System.out.println(String.format(BULK_RESPONSE_FORMATTER, maskIfNull((response.getBundle()).getAppName()), 1273 maskIfNull((response.getCoordinator()).getAppName()), maskIfNull((response.getAction()).getId()), 1274 maskIfNull((response.getAction()).getExternalId()), (response.getAction()).getStatus(), 1275 maskDate((response.getAction()).getCreatedTime(), timeZoneId, false), (response.getAction()).getErrorMessage())); 1276 System.out.println(RULER); 1277 } 1278 } 1279 else { 1280 System.out.println("Bulk request criteria did not match any coordinator actions"); 1281 } 1282 } 1283 1284 private void printBundleJobs(List<BundleJob> jobs, String timeZoneId, boolean verbose) throws IOException { 1285 if (jobs != null && jobs.size() > 0) { 1286 if (verbose) { 1287 System.out.println("Job ID" + VERBOSE_DELIMITER + "Bundle Name" + VERBOSE_DELIMITER + "Bundle Path" 1288 + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" + VERBOSE_DELIMITER + "Status" 1289 + VERBOSE_DELIMITER + "Kickoff" + VERBOSE_DELIMITER + "Pause" + VERBOSE_DELIMITER + "Created" 1290 + VERBOSE_DELIMITER + "Console URL"); 1291 System.out.println(RULER); 1292 1293 for (BundleJob job : jobs) { 1294 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1295 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1296 + maskIfNull(job.getUser()) + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) 1297 + VERBOSE_DELIMITER + job.getStatus() + VERBOSE_DELIMITER 1298 + maskDate(job.getKickoffTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1299 + maskDate(job.getPauseTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1300 + maskDate(job.getCreatedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1301 + maskIfNull(job.getConsoleUrl())); 1302 1303 System.out.println(RULER); 1304 } 1305 } 1306 else { 1307 System.out.println(String.format(BUNDLE_JOBS_FORMATTER, "Job ID", "Bundle Name", "Status", "Kickoff", 1308 "Created", "User", "Group")); 1309 System.out.println(RULER); 1310 1311 for (BundleJob job : jobs) { 1312 System.out.println(String.format(BUNDLE_JOBS_FORMATTER, maskIfNull(job.getId()), 1313 maskIfNull(job.getAppName()), job.getStatus(), 1314 maskDate(job.getKickoffTime(), timeZoneId, verbose), 1315 maskDate(job.getCreatedTime(), timeZoneId, verbose), maskIfNull(job.getUser()), 1316 maskIfNull(job.getGroup()))); 1317 System.out.println(RULER); 1318 } 1319 } 1320 } 1321 else { 1322 System.out.println("No Jobs match your criteria!"); 1323 } 1324 } 1325 1326 private void slaCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1327 XOozieClient wc = createXOozieClient(commandLine); 1328 List<String> options = new ArrayList<String>(); 1329 for (Option option : commandLine.getOptions()) { 1330 options.add(option.getOpt()); 1331 } 1332 1333 String s = commandLine.getOptionValue(OFFSET_OPTION); 1334 int start = Integer.parseInt((s != null) ? s : "0"); 1335 s = commandLine.getOptionValue(LEN_OPTION); 1336 int len = Integer.parseInt((s != null) ? s : "100"); 1337 String filter = commandLine.getOptionValue(FILTER_OPTION); 1338 1339 try { 1340 wc.getSlaInfo(start, len, filter); 1341 } 1342 catch (OozieClientException ex) { 1343 throw new OozieCLIException(ex.toString(), ex); 1344 } 1345 } 1346 1347 private void adminCommand(CommandLine commandLine) throws OozieCLIException { 1348 XOozieClient wc = createXOozieClient(commandLine); 1349 1350 List<String> options = new ArrayList<String>(); 1351 for (Option option : commandLine.getOptions()) { 1352 options.add(option.getOpt()); 1353 } 1354 1355 try { 1356 SYSTEM_MODE status = SYSTEM_MODE.NORMAL; 1357 if (options.contains(VERSION_OPTION)) { 1358 System.out.println("Oozie server build version: " + wc.getServerBuildVersion()); 1359 } 1360 else if (options.contains(SYSTEM_MODE_OPTION)) { 1361 String systemModeOption = commandLine.getOptionValue(SYSTEM_MODE_OPTION).toUpperCase(); 1362 try { 1363 status = SYSTEM_MODE.valueOf(systemModeOption); 1364 } 1365 catch (Exception e) { 1366 throw new OozieCLIException("Invalid input provided for option: " + SYSTEM_MODE_OPTION 1367 + " value given :" + systemModeOption 1368 + " Expected values are: NORMAL/NOWEBSERVICE/SAFEMODE "); 1369 } 1370 wc.setSystemMode(status); 1371 System.out.println("System mode: " + status); 1372 } 1373 else if (options.contains(STATUS_OPTION)) { 1374 status = wc.getSystemMode(); 1375 System.out.println("System mode: " + status); 1376 } 1377 else if (options.contains(QUEUE_DUMP_OPTION)) { 1378 1379 List<String> list = wc.getQueueDump(); 1380 if (list != null && list.size() != 0) { 1381 for (String str : list) { 1382 System.out.println(str); 1383 } 1384 } 1385 else { 1386 System.out.println("QueueDump is null!"); 1387 } 1388 } 1389 } 1390 catch (OozieClientException ex) { 1391 throw new OozieCLIException(ex.toString(), ex); 1392 } 1393 } 1394 1395 private void versionCommand() throws OozieCLIException { 1396 System.out.println("Oozie client build version: " 1397 + BuildInfo.getBuildInfo().getProperty(BuildInfo.BUILD_VERSION)); 1398 } 1399 1400 private void printJobs(List<WorkflowJob> jobs, String timeZoneId, boolean verbose) throws IOException { 1401 if (jobs != null && jobs.size() > 0) { 1402 if (verbose) { 1403 System.out.println("Job ID" + VERBOSE_DELIMITER + "App Name" + VERBOSE_DELIMITER + "App Path" 1404 + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" 1405 + VERBOSE_DELIMITER + "Run" + VERBOSE_DELIMITER + "Created" + VERBOSE_DELIMITER + "Started" 1406 + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Last Modified" + VERBOSE_DELIMITER 1407 + "Ended"); 1408 System.out.println(RULER); 1409 1410 for (WorkflowJob job : jobs) { 1411 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1412 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1413 + maskIfNull(job.getConsoleUrl()) + VERBOSE_DELIMITER + maskIfNull(job.getUser()) 1414 + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) + VERBOSE_DELIMITER + job.getRun() 1415 + VERBOSE_DELIMITER + maskDate(job.getCreatedTime(), timeZoneId, verbose) 1416 + VERBOSE_DELIMITER + maskDate(job.getStartTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1417 + job.getStatus() + VERBOSE_DELIMITER 1418 + maskDate(job.getLastModifiedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1419 + maskDate(job.getEndTime(), timeZoneId, verbose)); 1420 1421 System.out.println(RULER); 1422 } 1423 } 1424 else { 1425 System.out.println(String.format(WORKFLOW_JOBS_FORMATTER, "Job ID", "App Name", "Status", "User", 1426 "Group", "Started", "Ended")); 1427 System.out.println(RULER); 1428 1429 for (WorkflowJob job : jobs) { 1430 System.out.println(String.format(WORKFLOW_JOBS_FORMATTER, maskIfNull(job.getId()), 1431 maskIfNull(job.getAppName()), job.getStatus(), maskIfNull(job.getUser()), 1432 maskIfNull(job.getGroup()), maskDate(job.getStartTime(), timeZoneId, verbose), 1433 maskDate(job.getEndTime(), timeZoneId, verbose))); 1434 1435 System.out.println(RULER); 1436 } 1437 } 1438 } 1439 else { 1440 System.out.println("No Jobs match your criteria!"); 1441 } 1442 } 1443 1444 private String maskIfNull(String value) { 1445 if (value != null && value.length() > 0) { 1446 return value; 1447 } 1448 return "-"; 1449 } 1450 1451 private String maskDate(Date date, String timeZoneId, boolean verbose) { 1452 if (date == null) { 1453 return "-"; 1454 } 1455 1456 SimpleDateFormat dateFormater = null; 1457 if (verbose) { 1458 dateFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz", Locale.US); 1459 } 1460 else { 1461 dateFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm zzz", Locale.US); 1462 } 1463 1464 if (timeZoneId != null) { 1465 dateFormater.setTimeZone(TimeZone.getTimeZone(timeZoneId)); 1466 } 1467 String dateString = dateFormater.format(date); 1468 // Most TimeZones are 3 or 4 characters; GMT offsets (e.g. GMT-07:00) are 9, so lets remove the "GMT" part to make it 6 1469 // to fit better 1470 Matcher m = GMT_OFFSET_SHORTEN_PATTERN.matcher(dateString); 1471 if (m.matches() && m.groupCount() == 2) { 1472 dateString = m.group(1) + m.group(2); 1473 } 1474 return dateString; 1475 } 1476 1477 private void validateCommand(CommandLine commandLine) throws OozieCLIException { 1478 String[] args = commandLine.getArgs(); 1479 if (args.length != 1) { 1480 throw new OozieCLIException("One file must be specified"); 1481 } 1482 File file = new File(args[0]); 1483 if (file.exists()) { 1484 try { 1485 List<StreamSource> sources = new ArrayList<StreamSource>(); 1486 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1487 "oozie-workflow-0.1.xsd"))); 1488 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1489 "shell-action-0.1.xsd"))); 1490 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1491 "shell-action-0.2.xsd"))); 1492 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1493 "shell-action-0.3.xsd"))); 1494 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1495 "email-action-0.1.xsd"))); 1496 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1497 "distcp-action-0.1.xsd"))); 1498 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1499 "distcp-action-0.2.xsd"))); 1500 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1501 "oozie-workflow-0.2.xsd"))); 1502 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1503 "oozie-workflow-0.2.5.xsd"))); 1504 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1505 "oozie-workflow-0.3.xsd"))); 1506 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1507 "oozie-workflow-0.4.xsd"))); 1508 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1509 "oozie-coordinator-0.1.xsd"))); 1510 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1511 "oozie-coordinator-0.2.xsd"))); 1512 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1513 "oozie-coordinator-0.3.xsd"))); 1514 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1515 "oozie-coordinator-0.4.xsd"))); 1516 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1517 "oozie-bundle-0.1.xsd"))); 1518 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1519 "oozie-bundle-0.2.xsd"))); 1520 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1521 "oozie-sla-0.1.xsd"))); 1522 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1523 "hive-action-0.2.xsd"))); 1524 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1525 "hive-action-0.3.xsd"))); 1526 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1527 "hive-action-0.4.xsd"))); 1528 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1529 "sqoop-action-0.2.xsd"))); 1530 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1531 "sqoop-action-0.3.xsd"))); 1532 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1533 "sqoop-action-0.4.xsd"))); 1534 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1535 "ssh-action-0.1.xsd"))); 1536 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 1537 Schema schema = factory.newSchema(sources.toArray(new StreamSource[sources.size()])); 1538 Validator validator = schema.newValidator(); 1539 validator.validate(new StreamSource(new FileReader(file))); 1540 System.out.println("Valid worflow-app"); 1541 } 1542 catch (Exception ex) { 1543 throw new OozieCLIException("Invalid workflow-app, " + ex.toString(), ex); 1544 } 1545 } 1546 else { 1547 throw new OozieCLIException("File does not exists"); 1548 } 1549 } 1550 1551 private void pigCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1552 List<String> pigArgs = commandLine.getArgList(); 1553 if (pigArgs.size() > 0) { 1554 // checking is a pigArgs starts with -X (because CLIParser cannot check this) 1555 if (!pigArgs.get(0).equals("-X")) { 1556 throw new OozieCLIException("Unrecognized option: " + pigArgs.get(0) + " Expecting -X"); 1557 } 1558 pigArgs.remove(0); 1559 } 1560 1561 List<String> options = new ArrayList<String>(); 1562 for (Option option : commandLine.getOptions()) { 1563 options.add(option.getOpt()); 1564 } 1565 1566 if (!options.contains(PIGFILE_OPTION)) { 1567 throw new OozieCLIException("Need to specify -file <scriptfile>"); 1568 } 1569 1570 if (!options.contains(CONFIG_OPTION)) { 1571 throw new OozieCLIException("Need to specify -config <configfile>"); 1572 } 1573 1574 1575 try { 1576 XOozieClient wc = createXOozieClient(commandLine); 1577 Properties conf = getConfiguration(wc, commandLine); 1578 String script = commandLine.getOptionValue(PIGFILE_OPTION); 1579 System.out.println(JOB_ID_PREFIX + wc.submitPig(conf, script, pigArgs.toArray(new String[pigArgs.size()]))); 1580 } 1581 catch (OozieClientException ex) { 1582 throw new OozieCLIException(ex.toString(), ex); 1583 } 1584 } 1585 1586 private void infoCommand(CommandLine commandLine) throws OozieCLIException { 1587 for (Option option : commandLine.getOptions()) { 1588 String opt = option.getOpt(); 1589 if (opt.equals(INFO_TIME_ZONES_OPTION)) { 1590 printAvailableTimeZones(); 1591 } 1592 } 1593 } 1594 1595 private void printAvailableTimeZones() { 1596 System.out.println("The format is \"SHORT_NAME (ID)\"\nGive the ID to the -timezone argument"); 1597 System.out.println("GMT offsets can also be used (e.g. GMT-07:00, GMT-0700, GMT+05:30, GMT+0530)"); 1598 System.out.println("Available Time Zones:"); 1599 for (String tzId : TimeZone.getAvailableIDs()) { 1600 // skip id's that are like "Etc/GMT+01:00" because their display names are like "GMT-01:00", which is confusing 1601 if (!tzId.startsWith("Etc/GMT")) { 1602 TimeZone tZone = TimeZone.getTimeZone(tzId); 1603 System.out.println(" " + tZone.getDisplayName(false, TimeZone.SHORT) + " (" + tzId + ")"); 1604 } 1605 } 1606 } 1607 1608 1609 private void mrCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1610 try { 1611 XOozieClient wc = createXOozieClient(commandLine); 1612 Properties conf = getConfiguration(wc, commandLine); 1613 1614 String mapper = conf.getProperty(MAPRED_MAPPER); 1615 if (mapper == null) { 1616 throw new OozieCLIException("mapper is not specified in conf"); 1617 } 1618 1619 String reducer = conf.getProperty(MAPRED_REDUCER); 1620 if (reducer == null) { 1621 throw new OozieCLIException("reducer is not specified in conf"); 1622 } 1623 1624 String inputDir = conf.getProperty(MAPRED_INPUT); 1625 if (inputDir == null) { 1626 throw new OozieCLIException("mapred.input.dir is not specified in conf"); 1627 } 1628 1629 String outputDir = conf.getProperty(MAPRED_OUTPUT); 1630 if (outputDir == null) { 1631 throw new OozieCLIException("mapred.output.dir is not specified in conf"); 1632 } 1633 1634 System.out.println(JOB_ID_PREFIX + wc.submitMapReduce(conf)); 1635 } 1636 catch (OozieClientException ex) { 1637 throw new OozieCLIException(ex.toString(), ex); 1638 } 1639 } 1640 }