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, 246 "Supported in Oozie-2.0 or later versions ONLY - dryrun or test run a coordinator job, job is not queued"); 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 * @return sla options 362 */ 363 protected Options createSlaOptions() { 364 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 365 Option start = new Option(OFFSET_OPTION, true, "start offset (default '0')"); 366 Option len = new Option(LEN_OPTION, true, "number of results (default '100')"); 367 start.setType(Integer.class); 368 len.setType(Integer.class); 369 Options slaOptions = new Options(); 370 slaOptions.addOption(start); 371 slaOptions.addOption(len); 372 slaOptions.addOption(oozie); 373 addAuthOptions(slaOptions); 374 return slaOptions; 375 } 376 377 /** 378 * Create option for command line option 'pig' 379 * @return pig options 380 */ 381 @SuppressWarnings("static-access") 382 protected Options createPigOptions() { 383 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 384 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.properties'"); 385 Option pigFile = new Option(PIGFILE_OPTION, true, "Pig script"); 386 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 387 "set/override value for given property").create("D"); 388 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 389 Options pigOptions = new Options(); 390 pigOptions.addOption(oozie); 391 pigOptions.addOption(doAs); 392 pigOptions.addOption(config); 393 pigOptions.addOption(property); 394 pigOptions.addOption(pigFile); 395 addAuthOptions(pigOptions); 396 return pigOptions; 397 } 398 399 /** 400 * Create option for command line option 'info' 401 * @return info options 402 */ 403 protected Options createInfoOptions() { 404 Option timezones = new Option(INFO_TIME_ZONES_OPTION, false, "display a list of available time zones"); 405 Options infoOptions = new Options(); 406 infoOptions.addOption(timezones); 407 return infoOptions; 408 } 409 410 /** 411 * Create option for command line option 'mapreduce' 412 * @return mapreduce options 413 */ 414 @SuppressWarnings("static-access") 415 protected Options createMROptions() { 416 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 417 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.properties'"); 418 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 419 "set/override value for given property").create("D"); 420 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 421 Options mrOptions = new Options(); 422 mrOptions.addOption(oozie); 423 mrOptions.addOption(doAs); 424 mrOptions.addOption(config); 425 mrOptions.addOption(property); 426 addAuthOptions(mrOptions); 427 return mrOptions; 428 } 429 430 /** 431 * Run a CLI programmatically. 432 * <p/> 433 * It does not exit the JVM. 434 * <p/> 435 * A CLI instance can be used only once. 436 * 437 * @param args options and arguments for the Oozie CLI. 438 * @return '0' (success), '-1' (failure). 439 */ 440 public synchronized int run(String[] args) { 441 if (used) { 442 throw new IllegalStateException("CLI instance already used"); 443 } 444 used = true; 445 446 final CLIParser parser = new CLIParser(OOZIE_OPTION, getCLIHelp()); 447 parser.addCommand(HELP_CMD, "", "display usage for all commands or specified command", new Options(), false); 448 parser.addCommand(VERSION_CMD, "", "show client version", new Options(), false); 449 parser.addCommand(JOB_CMD, "", "job operations", createJobOptions(), false); 450 parser.addCommand(JOBS_CMD, "", "jobs status", createJobsOptions(), false); 451 parser.addCommand(ADMIN_CMD, "", "admin operations", createAdminOptions(), false); 452 parser.addCommand(VALIDATE_CMD, "", "validate a workflow XML file", new Options(), true); 453 parser.addCommand(SLA_CMD, "", "sla operations (Supported in Oozie-2.0 or later)", createSlaOptions(), false); 454 parser.addCommand(PIG_CMD, "-X ", "submit a pig job, everything after '-X' are pass-through parameters to pig", 455 createPigOptions(), true); 456 parser.addCommand(INFO_CMD, "", "get more detailed info about specific topics", createInfoOptions(), false); 457 parser.addCommand(MR_CMD, "", "submit a mapreduce job", createMROptions(), false); 458 459 try { 460 final CLIParser.Command command = parser.parse(args); 461 462 String doAsUser = command.getCommandLine().getOptionValue(DO_AS_OPTION); 463 464 if (doAsUser != null) { 465 OozieClient.doAs(doAsUser, new Callable<Void>() { 466 @Override 467 public Void call() throws Exception { 468 processCommand(parser, command); 469 return null; 470 } 471 }); 472 } 473 else { 474 processCommand(parser, command); 475 } 476 477 return 0; 478 } 479 catch (OozieCLIException ex) { 480 System.err.println("Error: " + ex.getMessage()); 481 return -1; 482 } 483 catch (ParseException ex) { 484 System.err.println("Invalid sub-command: " + ex.getMessage()); 485 System.err.println(); 486 System.err.println(parser.shortHelp()); 487 return -1; 488 } 489 catch (Exception ex) { 490 ex.printStackTrace(); 491 System.err.println(ex.getMessage()); 492 return -1; 493 } 494 } 495 496 private void processCommand(CLIParser parser, CLIParser.Command command) throws Exception { 497 if (command.getName().equals(HELP_CMD)) { 498 parser.showHelp(command.getCommandLine()); 499 } 500 else if (command.getName().equals(JOB_CMD)) { 501 jobCommand(command.getCommandLine()); 502 } 503 else if (command.getName().equals(JOBS_CMD)) { 504 jobsCommand(command.getCommandLine()); 505 } 506 else if (command.getName().equals(ADMIN_CMD)) { 507 adminCommand(command.getCommandLine()); 508 } 509 else if (command.getName().equals(VERSION_CMD)) { 510 versionCommand(); 511 } 512 else if (command.getName().equals(VALIDATE_CMD)) { 513 validateCommand(command.getCommandLine()); 514 } 515 else if (command.getName().equals(SLA_CMD)) { 516 slaCommand(command.getCommandLine()); 517 } 518 else if (command.getName().equals(PIG_CMD)) { 519 pigCommand(command.getCommandLine()); 520 } 521 else if (command.getName().equals(INFO_CMD)) { 522 infoCommand(command.getCommandLine()); 523 } 524 else if (command.getName().equals(MR_CMD)){ 525 mrCommand(command.getCommandLine()); 526 } 527 } 528 protected String getOozieUrl(CommandLine commandLine) { 529 String url = commandLine.getOptionValue(OOZIE_OPTION); 530 if (url == null) { 531 url = System.getenv(ENV_OOZIE_URL); 532 if (url == null) { 533 throw new IllegalArgumentException( 534 "Oozie URL is not available neither in command option or in the environment"); 535 } 536 } 537 return url; 538 } 539 540 private String getTimeZoneId(CommandLine commandLine) 541 { 542 if (commandLine.hasOption(LOCAL_TIME_OPTION)) { 543 return null; 544 } 545 if (commandLine.hasOption(TIME_ZONE_OPTION)) { 546 return commandLine.getOptionValue(TIME_ZONE_OPTION); 547 } 548 String timeZoneId = System.getenv(ENV_OOZIE_TIME_ZONE); 549 if (timeZoneId != null) { 550 return timeZoneId; 551 } 552 return "GMT"; 553 } 554 555 // Canibalized from Hadoop <code>Configuration.loadResource()</code>. 556 private Properties parse(InputStream is, Properties conf) throws IOException { 557 try { 558 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 559 // ignore all comments inside the xml file 560 docBuilderFactory.setIgnoringComments(true); 561 DocumentBuilder builder = docBuilderFactory.newDocumentBuilder(); 562 Document doc = builder.parse(is); 563 return parseDocument(doc, conf); 564 } 565 catch (SAXException e) { 566 throw new IOException(e); 567 } 568 catch (ParserConfigurationException e) { 569 throw new IOException(e); 570 } 571 } 572 573 // Canibalized from Hadoop <code>Configuration.loadResource()</code>. 574 private Properties parseDocument(Document doc, Properties conf) throws IOException { 575 try { 576 Element root = doc.getDocumentElement(); 577 if (!"configuration".equals(root.getTagName())) { 578 throw new RuntimeException("bad conf file: top-level element not <configuration>"); 579 } 580 NodeList props = root.getChildNodes(); 581 for (int i = 0; i < props.getLength(); i++) { 582 Node propNode = props.item(i); 583 if (!(propNode instanceof Element)) { 584 continue; 585 } 586 Element prop = (Element) propNode; 587 if (!"property".equals(prop.getTagName())) { 588 throw new RuntimeException("bad conf file: element not <property>"); 589 } 590 NodeList fields = prop.getChildNodes(); 591 String attr = null; 592 String value = null; 593 for (int j = 0; j < fields.getLength(); j++) { 594 Node fieldNode = fields.item(j); 595 if (!(fieldNode instanceof Element)) { 596 continue; 597 } 598 Element field = (Element) fieldNode; 599 if ("name".equals(field.getTagName()) && field.hasChildNodes()) { 600 attr = ((Text) field.getFirstChild()).getData(); 601 } 602 if ("value".equals(field.getTagName()) && field.hasChildNodes()) { 603 value = ((Text) field.getFirstChild()).getData(); 604 } 605 } 606 607 if (attr != null && value != null) { 608 conf.setProperty(attr, value); 609 } 610 } 611 return conf; 612 } 613 catch (DOMException e) { 614 throw new IOException(e); 615 } 616 } 617 618 private Properties getConfiguration(OozieClient wc, CommandLine commandLine) throws IOException { 619 Properties conf = wc.createConfiguration(); 620 String configFile = commandLine.getOptionValue(CONFIG_OPTION); 621 if (configFile == null) { 622 throw new IOException("configuration file not specified"); 623 } 624 else { 625 File file = new File(configFile); 626 if (!file.exists()) { 627 throw new IOException("configuration file [" + configFile + "] not found"); 628 } 629 if (configFile.endsWith(".properties")) { 630 conf.load(new FileReader(file)); 631 } 632 else if (configFile.endsWith(".xml")) { 633 parse(new FileInputStream(configFile), conf); 634 } 635 else { 636 throw new IllegalArgumentException("configuration must be a '.properties' or a '.xml' file"); 637 } 638 } 639 if (commandLine.hasOption("D")) { 640 Properties commandLineProperties = commandLine.getOptionProperties("D"); 641 conf.putAll(commandLineProperties); 642 } 643 return conf; 644 } 645 646 /** 647 * @param commandLine command line string. 648 * @return change value specified by -value. 649 * @throws OozieCLIException 650 */ 651 private String getChangeValue(CommandLine commandLine) throws OozieCLIException { 652 String changeValue = commandLine.getOptionValue(CHANGE_VALUE_OPTION); 653 654 if (changeValue == null) { 655 throw new OozieCLIException("-value option needs to be specified for -change option"); 656 } 657 658 return changeValue; 659 } 660 661 protected void addHeader(OozieClient wc) { 662 for (Map.Entry entry : System.getProperties().entrySet()) { 663 String key = (String) entry.getKey(); 664 if (key.startsWith(WS_HEADER_PREFIX)) { 665 String header = key.substring(WS_HEADER_PREFIX.length()); 666 wc.setHeader(header, (String) entry.getValue()); 667 } 668 } 669 } 670 671 /** 672 * Get auth option from command line 673 * 674 * @param commandLine the command line object 675 * @return auth option 676 */ 677 protected String getAuthOption(CommandLine commandLine) { 678 String authOpt = commandLine.getOptionValue(AUTH_OPTION); 679 return authOpt; 680 } 681 682 /** 683 * Create a OozieClient. 684 * <p/> 685 * It injects any '-Dheader:' as header to the the {@link org.apache.oozie.client.OozieClient}. 686 * 687 * @param commandLine the parsed command line options. 688 * @return a pre configured eXtended workflow client. 689 * @throws OozieCLIException thrown if the OozieClient could not be configured. 690 */ 691 protected OozieClient createOozieClient(CommandLine commandLine) throws OozieCLIException { 692 return createXOozieClient(commandLine); 693 } 694 695 /** 696 * Create a XOozieClient. 697 * <p/> 698 * It injects any '-Dheader:' as header to the the {@link org.apache.oozie.client.OozieClient}. 699 * 700 * @param commandLine the parsed command line options. 701 * @return a pre configured eXtended workflow client. 702 * @throws OozieCLIException thrown if the XOozieClient could not be configured. 703 */ 704 protected XOozieClient createXOozieClient(CommandLine commandLine) throws OozieCLIException { 705 XOozieClient wc = new AuthOozieClient(getOozieUrl(commandLine), getAuthOption(commandLine)); 706 addHeader(wc); 707 setDebugMode(wc,commandLine.hasOption(DEBUG_OPTION)); 708 return wc; 709 } 710 711 protected void setDebugMode(OozieClient wc, boolean debugOpt) { 712 713 String debug = System.getenv(ENV_OOZIE_DEBUG); 714 if (debug != null && !debug.isEmpty()) { 715 int debugVal = 0; 716 try { 717 debugVal = Integer.parseInt(debug.trim()); 718 } 719 catch (Exception ex) { 720 System.out.println("Unable to parse the debug settings. May be not an integer [" + debug + "]"); 721 ex.printStackTrace(); 722 } 723 wc.setDebugMode(debugVal); 724 } 725 else if(debugOpt){ // CLI argument "-debug" used 726 wc.setDebugMode(1); 727 } 728 } 729 730 private static String JOB_ID_PREFIX = "job: "; 731 732 private void jobCommand(CommandLine commandLine) throws IOException, OozieCLIException { 733 XOozieClient wc = createXOozieClient(commandLine); 734 735 List<String> options = new ArrayList<String>(); 736 for (Option option : commandLine.getOptions()) { 737 options.add(option.getOpt()); 738 } 739 740 try { 741 if (options.contains(SUBMIT_OPTION)) { 742 System.out.println(JOB_ID_PREFIX + wc.submit(getConfiguration(wc, commandLine))); 743 } 744 else if (options.contains(START_OPTION)) { 745 wc.start(commandLine.getOptionValue(START_OPTION)); 746 } 747 else if (options.contains(DRYRUN_OPTION)) { 748 String[] dryrunStr = wc.dryrun(getConfiguration(wc, commandLine)).split("action for new instance"); 749 int arraysize = dryrunStr.length; 750 System.out.println("***coordJob after parsing: ***"); 751 System.out.println(dryrunStr[0]); 752 int aLen = dryrunStr.length - 1; 753 if (aLen < 0) { 754 aLen = 0; 755 } 756 System.out.println("***total coord actions is " + aLen + " ***"); 757 for (int i = 1; i <= arraysize - 1; i++) { 758 System.out.println(RULER); 759 System.out.println("coordAction instance: " + i + ":"); 760 System.out.println(dryrunStr[i]); 761 } 762 } 763 else if (options.contains(SUSPEND_OPTION)) { 764 wc.suspend(commandLine.getOptionValue(SUSPEND_OPTION)); 765 } 766 else if (options.contains(RESUME_OPTION)) { 767 wc.resume(commandLine.getOptionValue(RESUME_OPTION)); 768 } 769 else if (options.contains(KILL_OPTION)) { 770 wc.kill(commandLine.getOptionValue(KILL_OPTION)); 771 } 772 else if (options.contains(CHANGE_OPTION)) { 773 wc.change(commandLine.getOptionValue(CHANGE_OPTION), getChangeValue(commandLine)); 774 } 775 else if (options.contains(RUN_OPTION)) { 776 System.out.println(JOB_ID_PREFIX + wc.run(getConfiguration(wc, commandLine))); 777 } 778 else if (options.contains(RERUN_OPTION)) { 779 if (commandLine.getOptionValue(RERUN_OPTION).contains("-W")) { 780 wc.reRun(commandLine.getOptionValue(RERUN_OPTION), getConfiguration(wc, commandLine)); 781 } 782 else if (commandLine.getOptionValue(RERUN_OPTION).contains("-B")) { 783 String bundleJobId = commandLine.getOptionValue(RERUN_OPTION); 784 String coordScope = null; 785 String dateScope = null; 786 boolean refresh = false; 787 boolean noCleanup = false; 788 if (options.contains(ACTION_OPTION)) { 789 throw new OozieCLIException("Invalid options provided for bundle rerun. " + ACTION_OPTION 790 + " is not valid for bundle rerun"); 791 } 792 if (options.contains(DATE_OPTION)) { 793 dateScope = commandLine.getOptionValue(DATE_OPTION); 794 } 795 796 if (options.contains(RERUN_COORD_OPTION)) { 797 coordScope = commandLine.getOptionValue(RERUN_COORD_OPTION); 798 } 799 800 if (options.contains(RERUN_REFRESH_OPTION)) { 801 refresh = true; 802 } 803 if (options.contains(RERUN_NOCLEANUP_OPTION)) { 804 noCleanup = true; 805 } 806 wc.reRunBundle(bundleJobId, coordScope, dateScope, refresh, noCleanup); 807 if (coordScope != null && !coordScope.isEmpty()) { 808 System.out.println("Coordinators [" + coordScope + "] of bundle " + bundleJobId 809 + " are scheduled to rerun on date ranges [" + dateScope + "]."); 810 } 811 else { 812 System.out.println("All coordinators of bundle " + bundleJobId 813 + " are scheduled to rerun on the date ranges [" + dateScope + "]."); 814 } 815 } 816 else { 817 String coordJobId = commandLine.getOptionValue(RERUN_OPTION); 818 String scope = null; 819 String rerunType = null; 820 boolean refresh = false; 821 boolean noCleanup = false; 822 if (options.contains(DATE_OPTION) && options.contains(ACTION_OPTION)) { 823 throw new OozieCLIException("Invalid options provided for rerun: either" + DATE_OPTION + " or " 824 + ACTION_OPTION + " expected. Don't use both at the same time."); 825 } 826 if (options.contains(DATE_OPTION)) { 827 rerunType = RestConstants.JOB_COORD_RERUN_DATE; 828 scope = commandLine.getOptionValue(DATE_OPTION); 829 } 830 else if (options.contains(ACTION_OPTION)) { 831 rerunType = RestConstants.JOB_COORD_RERUN_ACTION; 832 scope = commandLine.getOptionValue(ACTION_OPTION); 833 } 834 else { 835 throw new OozieCLIException("Invalid options provided for rerun: " + DATE_OPTION + " or " 836 + ACTION_OPTION + " expected."); 837 } 838 if (options.contains(RERUN_REFRESH_OPTION)) { 839 refresh = true; 840 } 841 if (options.contains(RERUN_NOCLEANUP_OPTION)) { 842 noCleanup = true; 843 } 844 printRerunCoordActions(wc.reRunCoord(coordJobId, rerunType, scope, refresh, noCleanup)); 845 } 846 } 847 else if (options.contains(INFO_OPTION)) { 848 String timeZoneId = getTimeZoneId(commandLine); 849 if (commandLine.getOptionValue(INFO_OPTION).endsWith("-B")) { 850 String filter = commandLine.getOptionValue(FILTER_OPTION); 851 if (filter != null) { 852 throw new OozieCLIException("Filter option is currently not supported for a Bundle job"); 853 } 854 printBundleJob(wc.getBundleJobInfo(commandLine.getOptionValue(INFO_OPTION)), timeZoneId, 855 options.contains(VERBOSE_OPTION)); 856 } 857 else if (commandLine.getOptionValue(INFO_OPTION).endsWith("-C")) { 858 String s = commandLine.getOptionValue(OFFSET_OPTION); 859 int start = Integer.parseInt((s != null) ? s : "0"); 860 s = commandLine.getOptionValue(LEN_OPTION); 861 int len = Integer.parseInt((s != null) ? s : "0"); 862 String filter = commandLine.getOptionValue(FILTER_OPTION); 863 printCoordJob(wc.getCoordJobInfo(commandLine.getOptionValue(INFO_OPTION), filter, start, len), timeZoneId, 864 options.contains(VERBOSE_OPTION)); 865 } 866 else if (commandLine.getOptionValue(INFO_OPTION).contains("-C@")) { 867 String filter = commandLine.getOptionValue(FILTER_OPTION); 868 if (filter != null) { 869 throw new OozieCLIException("Filter option is not supported for a Coordinator action"); 870 } 871 printCoordAction(wc.getCoordActionInfo(commandLine.getOptionValue(INFO_OPTION)), timeZoneId); 872 } 873 else if (commandLine.getOptionValue(INFO_OPTION).contains("-W@")) { 874 String filter = commandLine.getOptionValue(FILTER_OPTION); 875 if (filter != null) { 876 throw new OozieCLIException("Filter option is not supported for a Workflow action"); 877 } 878 printWorkflowAction(wc.getWorkflowActionInfo(commandLine.getOptionValue(INFO_OPTION)), timeZoneId, 879 options.contains(VERBOSE_OPTION)); 880 } 881 else { 882 String filter = commandLine.getOptionValue(FILTER_OPTION); 883 if (filter != null) { 884 throw new OozieCLIException("Filter option is currently not supported for a Workflow job"); 885 } 886 String s = commandLine.getOptionValue(OFFSET_OPTION); 887 int start = Integer.parseInt((s != null) ? s : "0"); 888 s = commandLine.getOptionValue(LEN_OPTION); 889 String jobtype = commandLine.getOptionValue(JOBTYPE_OPTION); 890 jobtype = (jobtype != null) ? jobtype : "wf"; 891 int len = Integer.parseInt((s != null) ? s : "0"); 892 printJob(wc.getJobInfo(commandLine.getOptionValue(INFO_OPTION), start, len), timeZoneId, 893 options.contains(VERBOSE_OPTION)); 894 } 895 } 896 else if (options.contains(LOG_OPTION)) { 897 PrintStream ps = System.out; 898 if (commandLine.getOptionValue(LOG_OPTION).contains("-C")) { 899 String logRetrievalScope = null; 900 String logRetrievalType = null; 901 if (options.contains(ACTION_OPTION)) { 902 logRetrievalType = RestConstants.JOB_LOG_ACTION; 903 logRetrievalScope = commandLine.getOptionValue(ACTION_OPTION); 904 } 905 if (options.contains(DATE_OPTION)) { 906 logRetrievalType = RestConstants.JOB_LOG_DATE; 907 logRetrievalScope = commandLine.getOptionValue(DATE_OPTION); 908 } 909 try { 910 wc.getJobLog(commandLine.getOptionValue(LOG_OPTION), logRetrievalType, logRetrievalScope, ps); 911 } 912 finally { 913 ps.close(); 914 } 915 } 916 else { 917 if (!options.contains(ACTION_OPTION) && !options.contains(DATE_OPTION)) { 918 wc.getJobLog(commandLine.getOptionValue(LOG_OPTION), null, null, ps); 919 } 920 else { 921 throw new OozieCLIException("Invalid options provided for log retrieval. " + ACTION_OPTION 922 + " and " + DATE_OPTION + " are valid only for coordinator job log retrieval"); 923 } 924 } 925 } 926 else if (options.contains(DEFINITION_OPTION)) { 927 System.out.println(wc.getJobDefinition(commandLine.getOptionValue(DEFINITION_OPTION))); 928 } 929 else if (options.contains(CONFIG_CONTENT_OPTION)) { 930 if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-C")) { 931 System.out.println(wc.getCoordJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 932 } 933 else if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-W")) { 934 System.out.println(wc.getJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 935 } 936 else if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-B")) { 937 System.out 938 .println(wc.getBundleJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 939 } 940 else { 941 System.out.println("ERROR: job id [" + commandLine.getOptionValue(CONFIG_CONTENT_OPTION) 942 + "] doesn't end with either C or W or B"); 943 } 944 } 945 } 946 catch (OozieClientException ex) { 947 throw new OozieCLIException(ex.toString(), ex); 948 } 949 } 950 951 private void printCoordJob(CoordinatorJob coordJob, String timeZoneId, boolean verbose) { 952 System.out.println("Job ID : " + coordJob.getId()); 953 954 System.out.println(RULER); 955 956 List<CoordinatorAction> actions = coordJob.getActions(); 957 System.out.println("Job Name : " + maskIfNull(coordJob.getAppName())); 958 System.out.println("App Path : " + maskIfNull(coordJob.getAppPath())); 959 System.out.println("Status : " + coordJob.getStatus()); 960 System.out.println(RULER); 961 962 if (verbose) { 963 System.out.println("ID" + VERBOSE_DELIMITER + "Action Number" + VERBOSE_DELIMITER + "Console URL" 964 + VERBOSE_DELIMITER + "Error Code" + VERBOSE_DELIMITER + "Error Message" + VERBOSE_DELIMITER 965 + "External ID" + VERBOSE_DELIMITER + "External Status" + VERBOSE_DELIMITER + "Job ID" 966 + VERBOSE_DELIMITER + "Tracker URI" + VERBOSE_DELIMITER + "Created" + VERBOSE_DELIMITER 967 + "Nominal Time" + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Last Modified" 968 + VERBOSE_DELIMITER + "Missing Dependencies"); 969 System.out.println(RULER); 970 971 for (CoordinatorAction action : actions) { 972 String missingDep = action.getMissingDependencies(); 973 if(missingDep != null && !missingDep.isEmpty()) { 974 missingDep = missingDep.split(INSTANCE_SEPARATOR)[0]; 975 } 976 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER + action.getActionNumber() 977 + VERBOSE_DELIMITER + maskIfNull(action.getConsoleUrl()) + VERBOSE_DELIMITER 978 + maskIfNull(action.getErrorCode()) + VERBOSE_DELIMITER + maskIfNull(action.getErrorMessage()) 979 + VERBOSE_DELIMITER + maskIfNull(action.getExternalId()) + VERBOSE_DELIMITER 980 + maskIfNull(action.getExternalStatus()) + VERBOSE_DELIMITER + maskIfNull(action.getJobId()) 981 + VERBOSE_DELIMITER + maskIfNull(action.getTrackerUri()) + VERBOSE_DELIMITER 982 + maskDate(action.getCreatedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 983 + maskDate(action.getNominalTime(), timeZoneId, verbose) + action.getStatus() + VERBOSE_DELIMITER 984 + maskDate(action.getLastModifiedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 985 + maskIfNull(missingDep)); 986 987 System.out.println(RULER); 988 } 989 } 990 else { 991 System.out.println(String.format(COORD_ACTION_FORMATTER, "ID", "Status", "Ext ID", "Err Code", "Created", 992 "Nominal Time", "Last Mod")); 993 994 for (CoordinatorAction action : actions) { 995 System.out.println(String.format(COORD_ACTION_FORMATTER, maskIfNull(action.getId()), 996 action.getStatus(), maskIfNull(action.getExternalId()), maskIfNull(action.getErrorCode()), 997 maskDate(action.getCreatedTime(), timeZoneId, verbose), maskDate(action.getNominalTime(), timeZoneId, verbose), 998 maskDate(action.getLastModifiedTime(), timeZoneId, verbose))); 999 1000 System.out.println(RULER); 1001 } 1002 } 1003 } 1004 1005 private void printBundleJob(BundleJob bundleJob, String timeZoneId, boolean verbose) { 1006 System.out.println("Job ID : " + bundleJob.getId()); 1007 1008 System.out.println(RULER); 1009 1010 List<CoordinatorJob> coordinators = bundleJob.getCoordinators(); 1011 System.out.println("Job Name : " + maskIfNull(bundleJob.getAppName())); 1012 System.out.println("App Path : " + maskIfNull(bundleJob.getAppPath())); 1013 System.out.println("Status : " + bundleJob.getStatus()); 1014 System.out.println("Kickoff time : " + bundleJob.getKickoffTime()); 1015 System.out.println(RULER); 1016 1017 System.out.println(String.format(BUNDLE_COORD_JOBS_FORMATTER, "Job ID", "Status", "Freq", "Unit", "Started", 1018 "Next Materialized")); 1019 System.out.println(RULER); 1020 1021 for (CoordinatorJob job : coordinators) { 1022 System.out.println(String.format(BUNDLE_COORD_JOBS_FORMATTER, maskIfNull(job.getId()), job.getStatus(), 1023 job.getFrequency(), job.getTimeUnit(), maskDate(job.getStartTime(), timeZoneId, verbose), 1024 maskDate(job.getNextMaterializedTime(), timeZoneId, verbose))); 1025 1026 System.out.println(RULER); 1027 } 1028 } 1029 1030 private void printCoordAction(CoordinatorAction coordAction, String timeZoneId) { 1031 System.out.println("ID : " + maskIfNull(coordAction.getId())); 1032 1033 System.out.println(RULER); 1034 1035 System.out.println("Action Number : " + coordAction.getActionNumber()); 1036 System.out.println("Console URL : " + maskIfNull(coordAction.getConsoleUrl())); 1037 System.out.println("Error Code : " + maskIfNull(coordAction.getErrorCode())); 1038 System.out.println("Error Message : " + maskIfNull(coordAction.getErrorMessage())); 1039 System.out.println("External ID : " + maskIfNull(coordAction.getExternalId())); 1040 System.out.println("External Status : " + maskIfNull(coordAction.getExternalStatus())); 1041 System.out.println("Job ID : " + maskIfNull(coordAction.getJobId())); 1042 System.out.println("Tracker URI : " + maskIfNull(coordAction.getTrackerUri())); 1043 System.out.println("Created : " + maskDate(coordAction.getCreatedTime(), timeZoneId, false)); 1044 System.out.println("Nominal Time : " + maskDate(coordAction.getNominalTime(), timeZoneId, false)); 1045 System.out.println("Status : " + coordAction.getStatus()); 1046 System.out.println("Last Modified : " + maskDate(coordAction.getLastModifiedTime(), timeZoneId, false)); 1047 String missingDep = coordAction.getMissingDependencies(); 1048 if(missingDep != null && !missingDep.isEmpty()) { 1049 missingDep = missingDep.split(INSTANCE_SEPARATOR)[0]; 1050 } 1051 System.out.println("First Missing Dependency : " + maskIfNull(missingDep)); 1052 1053 System.out.println(RULER); 1054 } 1055 1056 private void printRerunCoordActions(List<CoordinatorAction> actions) { 1057 if (actions != null && actions.size() > 0) { 1058 System.out.println("Action ID" + VERBOSE_DELIMITER + "Nominal Time"); 1059 System.out.println(RULER); 1060 for (CoordinatorAction action : actions) { 1061 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER 1062 + maskDate(action.getNominalTime(), null,false)); 1063 } 1064 } 1065 else { 1066 System.out.println("No Actions match your rerun criteria!"); 1067 } 1068 } 1069 1070 private void printWorkflowAction(WorkflowAction action, String timeZoneId, boolean verbose) { 1071 System.out.println("ID : " + maskIfNull(action.getId())); 1072 1073 System.out.println(RULER); 1074 1075 System.out.println("Console URL : " + maskIfNull(action.getConsoleUrl())); 1076 System.out.println("Error Code : " + maskIfNull(action.getErrorCode())); 1077 System.out.println("Error Message : " + maskIfNull(action.getErrorMessage())); 1078 System.out.println("External ID : " + maskIfNull(action.getExternalId())); 1079 System.out.println("External Status : " + maskIfNull(action.getExternalStatus())); 1080 System.out.println("Name : " + maskIfNull(action.getName())); 1081 System.out.println("Retries : " + action.getRetries()); 1082 System.out.println("Tracker URI : " + maskIfNull(action.getTrackerUri())); 1083 System.out.println("Type : " + maskIfNull(action.getType())); 1084 System.out.println("Started : " + maskDate(action.getStartTime(), timeZoneId, verbose)); 1085 System.out.println("Status : " + action.getStatus()); 1086 System.out.println("Ended : " + maskDate(action.getEndTime(), timeZoneId, verbose)); 1087 1088 if (verbose) { 1089 System.out.println("External Stats : " + action.getStats()); 1090 System.out.println("External ChildIDs : " + action.getExternalChildIDs()); 1091 } 1092 1093 System.out.println(RULER); 1094 } 1095 1096 private static final String WORKFLOW_JOBS_FORMATTER = "%-41s%-13s%-10s%-10s%-10s%-24s%-24s"; 1097 private static final String COORD_JOBS_FORMATTER = "%-41s%-15s%-10s%-5s%-13s%-24s%-24s"; 1098 private static final String BUNDLE_JOBS_FORMATTER = "%-41s%-15s%-10s%-20s%-20s%-13s%-13s"; 1099 private static final String BUNDLE_COORD_JOBS_FORMATTER = "%-41s%-10s%-5s%-13s%-24s%-24s"; 1100 1101 private static final String WORKFLOW_ACTION_FORMATTER = "%-78s%-10s%-23s%-11s%-10s"; 1102 private static final String COORD_ACTION_FORMATTER = "%-43s%-10s%-37s%-10s%-21s%-21s"; 1103 private static final String BULK_RESPONSE_FORMATTER = "%-41s%-41s%-37s%-37s%-13s%-21s%-24s"; 1104 1105 private void printJob(WorkflowJob job, String timeZoneId, boolean verbose) throws IOException { 1106 System.out.println("Job ID : " + maskIfNull(job.getId())); 1107 1108 System.out.println(RULER); 1109 1110 System.out.println("Workflow Name : " + maskIfNull(job.getAppName())); 1111 System.out.println("App Path : " + maskIfNull(job.getAppPath())); 1112 System.out.println("Status : " + job.getStatus()); 1113 System.out.println("Run : " + job.getRun()); 1114 System.out.println("User : " + maskIfNull(job.getUser())); 1115 System.out.println("Group : " + maskIfNull(job.getGroup())); 1116 System.out.println("Created : " + maskDate(job.getCreatedTime(), timeZoneId, verbose)); 1117 System.out.println("Started : " + maskDate(job.getStartTime(), timeZoneId, verbose)); 1118 System.out.println("Last Modified : " + maskDate(job.getLastModifiedTime(), timeZoneId, verbose)); 1119 System.out.println("Ended : " + maskDate(job.getEndTime(), timeZoneId, verbose)); 1120 System.out.println("CoordAction ID: " + maskIfNull(job.getParentId())); 1121 1122 List<WorkflowAction> actions = job.getActions(); 1123 1124 if (actions != null && actions.size() > 0) { 1125 System.out.println(); 1126 System.out.println("Actions"); 1127 System.out.println(RULER); 1128 1129 if (verbose) { 1130 System.out.println("ID" + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "Error Code" 1131 + VERBOSE_DELIMITER + "Error Message" + VERBOSE_DELIMITER + "External ID" + VERBOSE_DELIMITER 1132 + "External Status" + VERBOSE_DELIMITER + "Name" + VERBOSE_DELIMITER + "Retries" 1133 + VERBOSE_DELIMITER + "Tracker URI" + VERBOSE_DELIMITER + "Type" + VERBOSE_DELIMITER 1134 + "Started" + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Ended"); 1135 System.out.println(RULER); 1136 1137 for (WorkflowAction action : job.getActions()) { 1138 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER 1139 + maskIfNull(action.getConsoleUrl()) + VERBOSE_DELIMITER 1140 + maskIfNull(action.getErrorCode()) + VERBOSE_DELIMITER 1141 + maskIfNull(action.getErrorMessage()) + VERBOSE_DELIMITER 1142 + maskIfNull(action.getExternalId()) + VERBOSE_DELIMITER 1143 + maskIfNull(action.getExternalStatus()) + VERBOSE_DELIMITER + maskIfNull(action.getName()) 1144 + VERBOSE_DELIMITER + action.getRetries() + VERBOSE_DELIMITER 1145 + maskIfNull(action.getTrackerUri()) + VERBOSE_DELIMITER + maskIfNull(action.getType()) 1146 + VERBOSE_DELIMITER + maskDate(action.getStartTime(), timeZoneId, verbose) 1147 + VERBOSE_DELIMITER + action.getStatus() + VERBOSE_DELIMITER 1148 + maskDate(action.getEndTime(), timeZoneId, verbose)); 1149 1150 System.out.println(RULER); 1151 } 1152 } 1153 else { 1154 System.out.println(String.format(WORKFLOW_ACTION_FORMATTER, "ID", "Status", "Ext ID", "Ext Status", 1155 "Err Code")); 1156 1157 System.out.println(RULER); 1158 1159 for (WorkflowAction action : job.getActions()) { 1160 System.out.println(String.format(WORKFLOW_ACTION_FORMATTER, maskIfNull(action.getId()), action 1161 .getStatus(), maskIfNull(action.getExternalId()), maskIfNull(action.getExternalStatus()), 1162 maskIfNull(action.getErrorCode()))); 1163 1164 System.out.println(RULER); 1165 } 1166 } 1167 } 1168 else { 1169 System.out.println(RULER); 1170 } 1171 1172 System.out.println(); 1173 } 1174 1175 private void jobsCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1176 XOozieClient wc = createXOozieClient(commandLine); 1177 1178 String filter = commandLine.getOptionValue(FILTER_OPTION); 1179 String s = commandLine.getOptionValue(OFFSET_OPTION); 1180 int start = Integer.parseInt((s != null) ? s : "0"); 1181 s = commandLine.getOptionValue(LEN_OPTION); 1182 String jobtype = commandLine.getOptionValue(JOBTYPE_OPTION); 1183 String timeZoneId = getTimeZoneId(commandLine); 1184 jobtype = (jobtype != null) ? jobtype : "wf"; 1185 int len = Integer.parseInt((s != null) ? s : "0"); 1186 String bulkFilterString = commandLine.getOptionValue(BULK_OPTION); 1187 1188 try { 1189 if (bulkFilterString != null) { 1190 printBulkJobs(wc.getBulkInfo(bulkFilterString, start, len), timeZoneId); 1191 } 1192 else if (jobtype.toLowerCase().contains("wf")) { 1193 printJobs(wc.getJobsInfo(filter, start, len), timeZoneId, commandLine.hasOption(VERBOSE_OPTION)); 1194 } 1195 else if (jobtype.toLowerCase().startsWith("coord")) { 1196 printCoordJobs(wc.getCoordJobsInfo(filter, start, len), timeZoneId, commandLine.hasOption(VERBOSE_OPTION)); 1197 } 1198 else if (jobtype.toLowerCase().startsWith("bundle")) { 1199 printBundleJobs(wc.getBundleJobsInfo(filter, start, len), timeZoneId, commandLine.hasOption(VERBOSE_OPTION)); 1200 } 1201 1202 } 1203 catch (OozieClientException ex) { 1204 throw new OozieCLIException(ex.toString(), ex); 1205 } 1206 } 1207 1208 private void printCoordJobs(List<CoordinatorJob> jobs, String timeZoneId, boolean verbose) throws IOException { 1209 if (jobs != null && jobs.size() > 0) { 1210 if (verbose) { 1211 System.out.println("Job ID" + VERBOSE_DELIMITER + "App Name" + VERBOSE_DELIMITER + "App Path" 1212 + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" 1213 + VERBOSE_DELIMITER + "Concurrency" + VERBOSE_DELIMITER + "Frequency" + VERBOSE_DELIMITER 1214 + "Time Unit" + VERBOSE_DELIMITER + "Time Zone" + VERBOSE_DELIMITER + "Time Out" 1215 + VERBOSE_DELIMITER + "Started" + VERBOSE_DELIMITER + "Next Materialize" + VERBOSE_DELIMITER 1216 + "Status" + VERBOSE_DELIMITER + "Last Action" + VERBOSE_DELIMITER + "Ended"); 1217 System.out.println(RULER); 1218 1219 for (CoordinatorJob job : jobs) { 1220 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1221 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1222 + maskIfNull(job.getConsoleUrl()) + VERBOSE_DELIMITER + maskIfNull(job.getUser()) 1223 + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) + VERBOSE_DELIMITER + job.getConcurrency() 1224 + VERBOSE_DELIMITER + job.getFrequency() + VERBOSE_DELIMITER + job.getTimeUnit() 1225 + VERBOSE_DELIMITER + maskIfNull(job.getTimeZone()) + VERBOSE_DELIMITER + job.getTimeout() 1226 + VERBOSE_DELIMITER + maskDate(job.getStartTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1227 + maskDate(job.getNextMaterializedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1228 + job.getStatus() + VERBOSE_DELIMITER 1229 + maskDate(job.getLastActionTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1230 + maskDate(job.getEndTime(), timeZoneId, verbose)); 1231 1232 System.out.println(RULER); 1233 } 1234 } 1235 else { 1236 System.out.println(String.format(COORD_JOBS_FORMATTER, "Job ID", "App Name", "Status", "Freq", "Unit", 1237 "Started", "Next Materialized")); 1238 System.out.println(RULER); 1239 1240 for (CoordinatorJob job : jobs) { 1241 System.out.println(String.format(COORD_JOBS_FORMATTER, maskIfNull(job.getId()), maskIfNull(job 1242 .getAppName()), job.getStatus(), job.getFrequency(), job.getTimeUnit(), maskDate(job 1243 .getStartTime(), timeZoneId, verbose), maskDate(job.getNextMaterializedTime(), timeZoneId, verbose))); 1244 1245 System.out.println(RULER); 1246 } 1247 } 1248 } 1249 else { 1250 System.out.println("No Jobs match your criteria!"); 1251 } 1252 } 1253 1254 private void printBulkJobs(List<BulkResponse> jobs, String timeZoneId) throws IOException { 1255 if (jobs != null && jobs.size() > 0) { 1256 System.out.println(String.format(BULK_RESPONSE_FORMATTER, "Bundle Name", "Coordinator Name", 1257 "Coord Action ID", "External ID", "Status", "Created Time", "Error Message")); 1258 1259 for (BulkResponse response : jobs) { 1260 System.out.println(String.format(BULK_RESPONSE_FORMATTER, maskIfNull((response.getBundle()).getAppName()), 1261 maskIfNull((response.getCoordinator()).getAppName()), maskIfNull((response.getAction()).getId()), 1262 maskIfNull((response.getAction()).getExternalId()), (response.getAction()).getStatus(), 1263 maskDate((response.getAction()).getCreatedTime(), timeZoneId, false), (response.getAction()).getErrorMessage())); 1264 System.out.println(RULER); 1265 } 1266 } 1267 else { 1268 System.out.println("Bulk request criteria did not match any coordinator actions"); 1269 } 1270 } 1271 1272 private void printBundleJobs(List<BundleJob> jobs, String timeZoneId, boolean verbose) throws IOException { 1273 if (jobs != null && jobs.size() > 0) { 1274 if (verbose) { 1275 System.out.println("Job ID" + VERBOSE_DELIMITER + "Bundle Name" + VERBOSE_DELIMITER + "Bundle Path" 1276 + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" + VERBOSE_DELIMITER + "Status" 1277 + VERBOSE_DELIMITER + "Kickoff" + VERBOSE_DELIMITER + "Pause" + VERBOSE_DELIMITER + "Created" 1278 + VERBOSE_DELIMITER + "Console URL"); 1279 System.out.println(RULER); 1280 1281 for (BundleJob job : jobs) { 1282 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1283 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1284 + maskIfNull(job.getUser()) + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) 1285 + VERBOSE_DELIMITER + job.getStatus() + VERBOSE_DELIMITER 1286 + maskDate(job.getKickoffTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1287 + maskDate(job.getPauseTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1288 + maskDate(job.getCreatedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1289 + maskIfNull(job.getConsoleUrl())); 1290 1291 System.out.println(RULER); 1292 } 1293 } 1294 else { 1295 System.out.println(String.format(BUNDLE_JOBS_FORMATTER, "Job ID", "Bundle Name", "Status", "Kickoff", 1296 "Created", "User", "Group")); 1297 System.out.println(RULER); 1298 1299 for (BundleJob job : jobs) { 1300 System.out.println(String.format(BUNDLE_JOBS_FORMATTER, maskIfNull(job.getId()), 1301 maskIfNull(job.getAppName()), job.getStatus(), 1302 maskDate(job.getKickoffTime(), timeZoneId, verbose), 1303 maskDate(job.getCreatedTime(), timeZoneId, verbose), maskIfNull(job.getUser()), 1304 maskIfNull(job.getGroup()))); 1305 System.out.println(RULER); 1306 } 1307 } 1308 } 1309 else { 1310 System.out.println("No Jobs match your criteria!"); 1311 } 1312 } 1313 1314 private void slaCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1315 XOozieClient wc = createXOozieClient(commandLine); 1316 String s = commandLine.getOptionValue(OFFSET_OPTION); 1317 int start = Integer.parseInt((s != null) ? s : "0"); 1318 s = commandLine.getOptionValue(LEN_OPTION); 1319 int len = Integer.parseInt((s != null) ? s : "100"); 1320 try { 1321 wc.getSlaInfo(start, len); 1322 } 1323 catch (OozieClientException ex) { 1324 throw new OozieCLIException(ex.toString(), ex); 1325 } 1326 } 1327 1328 private void adminCommand(CommandLine commandLine) throws OozieCLIException { 1329 XOozieClient wc = createXOozieClient(commandLine); 1330 1331 List<String> options = new ArrayList<String>(); 1332 for (Option option : commandLine.getOptions()) { 1333 options.add(option.getOpt()); 1334 } 1335 1336 try { 1337 SYSTEM_MODE status = SYSTEM_MODE.NORMAL; 1338 if (options.contains(VERSION_OPTION)) { 1339 System.out.println("Oozie server build version: " + wc.getServerBuildVersion()); 1340 } 1341 else if (options.contains(SYSTEM_MODE_OPTION)) { 1342 String systemModeOption = commandLine.getOptionValue(SYSTEM_MODE_OPTION).toUpperCase(); 1343 try { 1344 status = SYSTEM_MODE.valueOf(systemModeOption); 1345 } 1346 catch (Exception e) { 1347 throw new OozieCLIException("Invalid input provided for option: " + SYSTEM_MODE_OPTION 1348 + " value given :" + systemModeOption 1349 + " Expected values are: NORMAL/NOWEBSERVICE/SAFEMODE "); 1350 } 1351 wc.setSystemMode(status); 1352 System.out.println("System mode: " + status); 1353 } 1354 else if (options.contains(STATUS_OPTION)) { 1355 status = wc.getSystemMode(); 1356 System.out.println("System mode: " + status); 1357 } 1358 else if (options.contains(QUEUE_DUMP_OPTION)) { 1359 1360 List<String> list = wc.getQueueDump(); 1361 if (list != null && list.size() != 0) { 1362 for (String str : list) { 1363 System.out.println(str); 1364 } 1365 } 1366 else { 1367 System.out.println("QueueDump is null!"); 1368 } 1369 } 1370 } 1371 catch (OozieClientException ex) { 1372 throw new OozieCLIException(ex.toString(), ex); 1373 } 1374 } 1375 1376 private void versionCommand() throws OozieCLIException { 1377 System.out.println("Oozie client build version: " 1378 + BuildInfo.getBuildInfo().getProperty(BuildInfo.BUILD_VERSION)); 1379 } 1380 1381 private void printJobs(List<WorkflowJob> jobs, String timeZoneId, boolean verbose) throws IOException { 1382 if (jobs != null && jobs.size() > 0) { 1383 if (verbose) { 1384 System.out.println("Job ID" + VERBOSE_DELIMITER + "App Name" + VERBOSE_DELIMITER + "App Path" 1385 + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" 1386 + VERBOSE_DELIMITER + "Run" + VERBOSE_DELIMITER + "Created" + VERBOSE_DELIMITER + "Started" 1387 + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Last Modified" + VERBOSE_DELIMITER 1388 + "Ended"); 1389 System.out.println(RULER); 1390 1391 for (WorkflowJob job : jobs) { 1392 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1393 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1394 + maskIfNull(job.getConsoleUrl()) + VERBOSE_DELIMITER + maskIfNull(job.getUser()) 1395 + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) + VERBOSE_DELIMITER + job.getRun() 1396 + VERBOSE_DELIMITER + maskDate(job.getCreatedTime(), timeZoneId, verbose) 1397 + VERBOSE_DELIMITER + maskDate(job.getStartTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1398 + job.getStatus() + VERBOSE_DELIMITER 1399 + maskDate(job.getLastModifiedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1400 + maskDate(job.getEndTime(), timeZoneId, verbose)); 1401 1402 System.out.println(RULER); 1403 } 1404 } 1405 else { 1406 System.out.println(String.format(WORKFLOW_JOBS_FORMATTER, "Job ID", "App Name", "Status", "User", 1407 "Group", "Started", "Ended")); 1408 System.out.println(RULER); 1409 1410 for (WorkflowJob job : jobs) { 1411 System.out.println(String.format(WORKFLOW_JOBS_FORMATTER, maskIfNull(job.getId()), 1412 maskIfNull(job.getAppName()), job.getStatus(), maskIfNull(job.getUser()), 1413 maskIfNull(job.getGroup()), maskDate(job.getStartTime(), timeZoneId, verbose), 1414 maskDate(job.getEndTime(), timeZoneId, verbose))); 1415 1416 System.out.println(RULER); 1417 } 1418 } 1419 } 1420 else { 1421 System.out.println("No Jobs match your criteria!"); 1422 } 1423 } 1424 1425 private String maskIfNull(String value) { 1426 if (value != null && value.length() > 0) { 1427 return value; 1428 } 1429 return "-"; 1430 } 1431 1432 private String maskDate(Date date, String timeZoneId, boolean verbose) { 1433 if (date == null) { 1434 return "-"; 1435 } 1436 1437 SimpleDateFormat dateFormater = null; 1438 if (verbose) { 1439 dateFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz", Locale.US); 1440 } 1441 else { 1442 dateFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm zzz", Locale.US); 1443 } 1444 1445 if (timeZoneId != null) { 1446 dateFormater.setTimeZone(TimeZone.getTimeZone(timeZoneId)); 1447 } 1448 String dateString = dateFormater.format(date); 1449 // 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 1450 // to fit better 1451 Matcher m = GMT_OFFSET_SHORTEN_PATTERN.matcher(dateString); 1452 if (m.matches() && m.groupCount() == 2) { 1453 dateString = m.group(1) + m.group(2); 1454 } 1455 return dateString; 1456 } 1457 1458 private void validateCommand(CommandLine commandLine) throws OozieCLIException { 1459 String[] args = commandLine.getArgs(); 1460 if (args.length != 1) { 1461 throw new OozieCLIException("One file must be specified"); 1462 } 1463 File file = new File(args[0]); 1464 if (file.exists()) { 1465 try { 1466 List<StreamSource> sources = new ArrayList<StreamSource>(); 1467 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1468 "oozie-workflow-0.1.xsd"))); 1469 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1470 "shell-action-0.1.xsd"))); 1471 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1472 "shell-action-0.2.xsd"))); 1473 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1474 "shell-action-0.3.xsd"))); 1475 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1476 "email-action-0.1.xsd"))); 1477 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1478 "distcp-action-0.1.xsd"))); 1479 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1480 "distcp-action-0.2.xsd"))); 1481 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1482 "oozie-workflow-0.2.xsd"))); 1483 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1484 "oozie-workflow-0.2.5.xsd"))); 1485 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1486 "oozie-workflow-0.3.xsd"))); 1487 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1488 "oozie-workflow-0.4.xsd"))); 1489 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1490 "oozie-coordinator-0.1.xsd"))); 1491 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1492 "oozie-coordinator-0.2.xsd"))); 1493 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1494 "oozie-coordinator-0.3.xsd"))); 1495 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1496 "oozie-coordinator-0.4.xsd"))); 1497 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1498 "oozie-bundle-0.1.xsd"))); 1499 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1500 "oozie-bundle-0.2.xsd"))); 1501 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1502 "oozie-sla-0.1.xsd"))); 1503 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1504 "hive-action-0.2.xsd"))); 1505 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1506 "hive-action-0.3.xsd"))); 1507 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1508 "hive-action-0.4.xsd"))); 1509 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1510 "sqoop-action-0.2.xsd"))); 1511 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1512 "sqoop-action-0.3.xsd"))); 1513 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1514 "sqoop-action-0.4.xsd"))); 1515 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 1516 "ssh-action-0.1.xsd"))); 1517 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 1518 Schema schema = factory.newSchema(sources.toArray(new StreamSource[sources.size()])); 1519 Validator validator = schema.newValidator(); 1520 validator.validate(new StreamSource(new FileReader(file))); 1521 System.out.println("Valid worflow-app"); 1522 } 1523 catch (Exception ex) { 1524 throw new OozieCLIException("Invalid workflow-app, " + ex.toString(), ex); 1525 } 1526 } 1527 else { 1528 throw new OozieCLIException("File does not exists"); 1529 } 1530 } 1531 1532 private void pigCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1533 List<String> pigArgs = commandLine.getArgList(); 1534 if (pigArgs.size() > 0) { 1535 // checking is a pigArgs starts with -X (because CLIParser cannot check this) 1536 if (!pigArgs.get(0).equals("-X")) { 1537 throw new OozieCLIException("Unrecognized option: " + pigArgs.get(0) + " Expecting -X"); 1538 } 1539 pigArgs.remove(0); 1540 } 1541 1542 List<String> options = new ArrayList<String>(); 1543 for (Option option : commandLine.getOptions()) { 1544 options.add(option.getOpt()); 1545 } 1546 1547 if (!options.contains(PIGFILE_OPTION)) { 1548 throw new OozieCLIException("Need to specify -file <scriptfile>"); 1549 } 1550 1551 if (!options.contains(CONFIG_OPTION)) { 1552 throw new OozieCLIException("Need to specify -config <configfile>"); 1553 } 1554 1555 1556 try { 1557 XOozieClient wc = createXOozieClient(commandLine); 1558 Properties conf = getConfiguration(wc, commandLine); 1559 String script = commandLine.getOptionValue(PIGFILE_OPTION); 1560 System.out.println(JOB_ID_PREFIX + wc.submitPig(conf, script, pigArgs.toArray(new String[pigArgs.size()]))); 1561 } 1562 catch (OozieClientException ex) { 1563 throw new OozieCLIException(ex.toString(), ex); 1564 } 1565 } 1566 1567 private void infoCommand(CommandLine commandLine) throws OozieCLIException { 1568 for (Option option : commandLine.getOptions()) { 1569 String opt = option.getOpt(); 1570 if (opt.equals(INFO_TIME_ZONES_OPTION)) { 1571 printAvailableTimeZones(); 1572 } 1573 } 1574 } 1575 1576 private void printAvailableTimeZones() { 1577 System.out.println("The format is \"SHORT_NAME (ID)\"\nGive the ID to the -timezone argument"); 1578 System.out.println("GMT offsets can also be used (e.g. GMT-07:00, GMT-0700, GMT+05:30, GMT+0530)"); 1579 System.out.println("Available Time Zones:"); 1580 for (String tzId : TimeZone.getAvailableIDs()) { 1581 // skip id's that are like "Etc/GMT+01:00" because their display names are like "GMT-01:00", which is confusing 1582 if (!tzId.startsWith("Etc/GMT")) { 1583 TimeZone tZone = TimeZone.getTimeZone(tzId); 1584 System.out.println(" " + tZone.getDisplayName(false, TimeZone.SHORT) + " (" + tzId + ")"); 1585 } 1586 } 1587 } 1588 1589 1590 private void mrCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1591 try { 1592 XOozieClient wc = createXOozieClient(commandLine); 1593 Properties conf = getConfiguration(wc, commandLine); 1594 1595 String mapper = conf.getProperty(MAPRED_MAPPER); 1596 if (mapper == null) { 1597 throw new OozieCLIException("mapper is not specified in conf"); 1598 } 1599 1600 String reducer = conf.getProperty(MAPRED_REDUCER); 1601 if (reducer == null) { 1602 throw new OozieCLIException("reducer is not specified in conf"); 1603 } 1604 1605 String inputDir = conf.getProperty(MAPRED_INPUT); 1606 if (inputDir == null) { 1607 throw new OozieCLIException("mapred.input.dir is not specified in conf"); 1608 } 1609 1610 String outputDir = conf.getProperty(MAPRED_OUTPUT); 1611 if (outputDir == null) { 1612 throw new OozieCLIException("mapred.output.dir is not specified in conf"); 1613 } 1614 1615 System.out.println(JOB_ID_PREFIX + wc.submitMapReduce(conf)); 1616 } 1617 catch (OozieClientException ex) { 1618 throw new OozieCLIException(ex.toString(), ex); 1619 } 1620 } 1621 }