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 019package org.apache.oozie.cli; 020 021import com.google.common.annotations.VisibleForTesting; 022import org.apache.commons.cli.CommandLine; 023import org.apache.commons.cli.Option; 024import org.apache.commons.cli.OptionBuilder; 025import org.apache.commons.cli.OptionGroup; 026import org.apache.commons.cli.Options; 027import org.apache.commons.cli.ParseException; 028import org.apache.oozie.BuildInfo; 029import org.apache.oozie.client.AuthOozieClient; 030import org.apache.oozie.client.BulkResponse; 031import org.apache.oozie.client.BundleJob; 032import org.apache.oozie.client.CoordinatorAction; 033import org.apache.oozie.client.CoordinatorJob; 034import org.apache.oozie.client.OozieClient; 035import org.apache.oozie.client.OozieClient.SYSTEM_MODE; 036import org.apache.oozie.client.OozieClientException; 037import org.apache.oozie.client.WorkflowAction; 038import org.apache.oozie.client.WorkflowJob; 039import org.apache.oozie.client.XOozieClient; 040import org.apache.oozie.client.rest.JsonTags; 041import org.apache.oozie.client.rest.JsonToBean; 042import org.apache.oozie.client.rest.RestConstants; 043import org.json.simple.JSONArray; 044import org.json.simple.JSONObject; 045import org.w3c.dom.DOMException; 046import org.w3c.dom.Document; 047import org.w3c.dom.Element; 048import org.w3c.dom.Node; 049import org.w3c.dom.NodeList; 050import org.w3c.dom.Text; 051import org.xml.sax.SAXException; 052 053import javax.xml.XMLConstants; 054import javax.xml.parsers.DocumentBuilder; 055import javax.xml.parsers.DocumentBuilderFactory; 056import javax.xml.parsers.ParserConfigurationException; 057import javax.xml.transform.stream.StreamSource; 058import javax.xml.validation.Schema; 059import javax.xml.validation.SchemaFactory; 060import javax.xml.validation.Validator; 061import java.io.File; 062import java.io.FileInputStream; 063import java.io.FileReader; 064import java.io.IOException; 065import java.io.InputStream; 066import java.io.PrintStream; 067import java.text.SimpleDateFormat; 068import java.util.ArrayList; 069import java.util.Date; 070import java.util.List; 071import java.util.Locale; 072import java.util.Map; 073import java.util.Properties; 074import java.util.TimeZone; 075import java.util.TreeMap; 076import java.util.concurrent.Callable; 077import java.util.regex.Matcher; 078import java.util.regex.Pattern; 079 080/** 081 * Oozie command line utility. 082 */ 083public class OozieCLI { 084 public static final String ENV_OOZIE_URL = "OOZIE_URL"; 085 public static final String ENV_OOZIE_DEBUG = "OOZIE_DEBUG"; 086 public static final String ENV_OOZIE_TIME_ZONE = "OOZIE_TIMEZONE"; 087 public static final String ENV_OOZIE_AUTH = "OOZIE_AUTH"; 088 public static final String OOZIE_RETRY_COUNT = "oozie.connection.retry.count"; 089 public static final String WS_HEADER_PREFIX = "header:"; 090 091 public static final String HELP_CMD = "help"; 092 public static final String VERSION_CMD = "version"; 093 public static final String JOB_CMD = "job"; 094 public static final String JOBS_CMD = "jobs"; 095 public static final String ADMIN_CMD = "admin"; 096 public static final String VALIDATE_CMD = "validate"; 097 public static final String SLA_CMD = "sla"; 098 public static final String PIG_CMD = "pig"; 099 public static final String HIVE_CMD = "hive"; 100 public static final String SQOOP_CMD = "sqoop"; 101 public static final String MR_CMD = "mapreduce"; 102 public static final String INFO_CMD = "info"; 103 104 public static final String OOZIE_OPTION = "oozie"; 105 public static final String CONFIG_OPTION = "config"; 106 public static final String SUBMIT_OPTION = "submit"; 107 public static final String OFFSET_OPTION = "offset"; 108 public static final String START_OPTION = "start"; 109 public static final String RUN_OPTION = "run"; 110 public static final String DRYRUN_OPTION = "dryrun"; 111 public static final String SUSPEND_OPTION = "suspend"; 112 public static final String RESUME_OPTION = "resume"; 113 public static final String KILL_OPTION = "kill"; 114 public static final String CHANGE_OPTION = "change"; 115 public static final String CHANGE_VALUE_OPTION = "value"; 116 public static final String RERUN_OPTION = "rerun"; 117 public static final String INFO_OPTION = "info"; 118 public static final String LOG_OPTION = "log"; 119 public static final String ERROR_LOG_OPTION = "errorlog"; 120 public static final String AUDIT_LOG_OPTION = "auditlog"; 121 122 public static final String ACTION_OPTION = "action"; 123 public static final String DEFINITION_OPTION = "definition"; 124 public static final String CONFIG_CONTENT_OPTION = "configcontent"; 125 public static final String SQOOP_COMMAND_OPTION = "command"; 126 public static final String SHOWDIFF_OPTION = "diff"; 127 public static final String UPDATE_OPTION = "update"; 128 public static final String IGNORE_OPTION = "ignore"; 129 public static final String POLL_OPTION = "poll"; 130 public static final String TIMEOUT_OPTION = "timeout"; 131 public static final String INTERVAL_OPTION = "interval"; 132 133 public static final String DO_AS_OPTION = "doas"; 134 135 public static final String LEN_OPTION = "len"; 136 public static final String FILTER_OPTION = "filter"; 137 public static final String JOBTYPE_OPTION = "jobtype"; 138 public static final String SYSTEM_MODE_OPTION = "systemmode"; 139 public static final String VERSION_OPTION = "version"; 140 public static final String STATUS_OPTION = "status"; 141 public static final String LOCAL_TIME_OPTION = "localtime"; 142 public static final String TIME_ZONE_OPTION = "timezone"; 143 public static final String QUEUE_DUMP_OPTION = "queuedump"; 144 public static final String DATE_OPTION = "date"; 145 public static final String RERUN_REFRESH_OPTION = "refresh"; 146 public static final String RERUN_NOCLEANUP_OPTION = "nocleanup"; 147 public static final String RERUN_FAILED_OPTION = "failed"; 148 public static final String ORDER_OPTION = "order"; 149 public static final String COORD_OPTION = "coordinator"; 150 151 public static final String UPDATE_SHARELIB_OPTION = "sharelibupdate"; 152 153 public static final String LIST_SHARELIB_LIB_OPTION = "shareliblist"; 154 155 public static final String SLA_DISABLE_ALERT = "sladisable"; 156 public static final String SLA_ENABLE_ALERT = "slaenable"; 157 public static final String SLA_CHANGE = "slachange"; 158 159 public static final String SERVER_CONFIGURATION_OPTION = "configuration"; 160 public static final String SERVER_OS_ENV_OPTION = "osenv"; 161 public static final String SERVER_JAVA_SYSTEM_PROPERTIES_OPTION = "javasysprops"; 162 163 public static final String METRICS_OPTION = "metrics"; 164 public static final String INSTRUMENTATION_OPTION = "instrumentation"; 165 166 public static final String AUTH_OPTION = "auth"; 167 168 public static final String VERBOSE_OPTION = "verbose"; 169 public static final String VERBOSE_DELIMITER = "\t"; 170 public static final String DEBUG_OPTION = "debug"; 171 172 public static final String SCRIPTFILE_OPTION = "file"; 173 174 public static final String INFO_TIME_ZONES_OPTION = "timezones"; 175 176 public static final String BULK_OPTION = "bulk"; 177 178 public static final String AVAILABLE_SERVERS_OPTION = "servers"; 179 180 public static final String ALL_WORKFLOWS_FOR_COORD_ACTION = "allruns"; 181 182 private static final String[] OOZIE_HELP = { 183 "the env variable '" + ENV_OOZIE_URL + "' is used as default value for the '-" + OOZIE_OPTION + "' option", 184 "the env variable '" + ENV_OOZIE_TIME_ZONE + "' is used as default value for the '-" + TIME_ZONE_OPTION + "' option", 185 "the env variable '" + ENV_OOZIE_AUTH + "' is used as default value for the '-" + AUTH_OPTION + "' option", 186 "custom headers for Oozie web services can be specified using '-D" + WS_HEADER_PREFIX + "NAME=VALUE'" }; 187 188 private static final String RULER; 189 private static final int LINE_WIDTH = 132; 190 191 private static final int RETRY_COUNT = 4; 192 193 private boolean used; 194 195 private static final String INSTANCE_SEPARATOR = "#"; 196 197 private static final String MAPRED_MAPPER = "mapred.mapper.class"; 198 private static final String MAPRED_MAPPER_2 = "mapreduce.map.class"; 199 private static final String MAPRED_REDUCER = "mapred.reducer.class"; 200 private static final String MAPRED_REDUCER_2 = "mapreduce.reduce.class"; 201 private static final String MAPRED_INPUT = "mapred.input.dir"; 202 private static final String MAPRED_OUTPUT = "mapred.output.dir"; 203 204 private static final Pattern GMT_OFFSET_SHORTEN_PATTERN = Pattern.compile("(.* )GMT((?:-|\\+)\\d{2}:\\d{2})"); 205 206 static { 207 StringBuilder sb = new StringBuilder(); 208 for (int i = 0; i < LINE_WIDTH; i++) { 209 sb.append("-"); 210 } 211 RULER = sb.toString(); 212 } 213 214 /** 215 * Entry point for the Oozie CLI when invoked from the command line. 216 * <p> 217 * Upon completion this method exits the JVM with '0' (success) or '-1' (failure). 218 * 219 * @param args options and arguments for the Oozie CLI. 220 */ 221 public static void main(String[] args) { 222 if (!System.getProperties().containsKey(AuthOozieClient.USE_AUTH_TOKEN_CACHE_SYS_PROP)) { 223 System.setProperty(AuthOozieClient.USE_AUTH_TOKEN_CACHE_SYS_PROP, "true"); 224 } 225 System.exit(new OozieCLI().run(args)); 226 } 227 228 /** 229 * Create an Oozie CLI instance. 230 */ 231 public OozieCLI() { 232 used = false; 233 } 234 235 /** 236 * Return Oozie CLI top help lines. 237 * 238 * @return help lines. 239 */ 240 protected String[] getCLIHelp() { 241 return OOZIE_HELP; 242 } 243 244 /** 245 * Add authentication specific options to oozie cli 246 * 247 * @param options the collection of options to add auth options 248 */ 249 protected void addAuthOptions(Options options) { 250 Option auth = new Option(AUTH_OPTION, true, "select authentication type [SIMPLE|KERBEROS]"); 251 options.addOption(auth); 252 } 253 254 /** 255 * Create option for command line option 'admin' 256 * @return admin options 257 */ 258 protected Options createAdminOptions() { 259 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 260 Option system_mode = new Option(SYSTEM_MODE_OPTION, true, 261 "Supported in Oozie-2.0 or later versions ONLY. Change oozie system mode [NORMAL|NOWEBSERVICE|SAFEMODE]"); 262 Option status = new Option(STATUS_OPTION, false, "show the current system status"); 263 Option version = new Option(VERSION_OPTION, false, "show Oozie server build version"); 264 Option queuedump = new Option(QUEUE_DUMP_OPTION, false, "show Oozie server queue elements"); 265 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 266 Option availServers = new Option(AVAILABLE_SERVERS_OPTION, false, "list available Oozie servers" 267 + " (more than one only if HA is enabled)"); 268 Option sharelibUpdate = new Option(UPDATE_SHARELIB_OPTION, false, "Update server to use a newer version of sharelib"); 269 Option serverConfiguration = new Option(SERVER_CONFIGURATION_OPTION, false, "show Oozie system configuration"); 270 Option osEnv = new Option(SERVER_OS_ENV_OPTION, false, "show Oozie system OS environment"); 271 Option javaSysProps = new Option(SERVER_JAVA_SYSTEM_PROPERTIES_OPTION, false, "show Oozie Java system properties"); 272 Option metrics = new Option(METRICS_OPTION, false, "show Oozie system metrics"); 273 Option instrumentation = new Option(INSTRUMENTATION_OPTION, false, "show Oozie system instrumentation"); 274 275 Option sharelib = new Option(LIST_SHARELIB_LIB_OPTION, false, 276 "List available sharelib that can be specified in a workflow action"); 277 sharelib.setOptionalArg(true); 278 279 Options adminOptions = new Options(); 280 adminOptions.addOption(oozie); 281 adminOptions.addOption(doAs); 282 OptionGroup group = new OptionGroup(); 283 group.addOption(system_mode); 284 group.addOption(status); 285 group.addOption(version); 286 group.addOption(queuedump); 287 group.addOption(availServers); 288 group.addOption(sharelibUpdate); 289 group.addOption(sharelib); 290 group.addOption(serverConfiguration); 291 group.addOption(osEnv); 292 group.addOption(javaSysProps); 293 group.addOption(metrics); 294 group.addOption(instrumentation); 295 adminOptions.addOptionGroup(group); 296 addAuthOptions(adminOptions); 297 return adminOptions; 298 } 299 300 /** 301 * Create option for command line option 'job' 302 * @return job options 303 */ 304 protected Options createJobOptions() { 305 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 306 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.xml' or '.properties'"); 307 Option submit = new Option(SUBMIT_OPTION, false, "submit a job"); 308 Option run = new Option(RUN_OPTION, false, "run a job"); 309 Option debug = new Option(DEBUG_OPTION, false, "Use debug mode to see debugging statements on stdout"); 310 Option rerun = new Option(RERUN_OPTION, true, 311 "rerun a job (coordinator requires -action or -date, bundle requires -coordinator or -date)"); 312 Option dryrun = new Option(DRYRUN_OPTION, false, "Dryrun a workflow (since 3.3.2) or coordinator (since 2.0) job without" 313 + " actually executing it"); 314 Option update = new Option(UPDATE_OPTION, true, "Update coord definition and properties"); 315 Option showdiff = new Option(SHOWDIFF_OPTION, true, 316 "Show diff of the new coord definition and properties with the existing one (default true)"); 317 Option start = new Option(START_OPTION, true, "start a job"); 318 Option suspend = new Option(SUSPEND_OPTION, true, "suspend a job"); 319 Option resume = new Option(RESUME_OPTION, true, "resume a job"); 320 Option kill = new Option(KILL_OPTION, true, "kill a job (coordinator can mention -action or -date)"); 321 Option change = new Option(CHANGE_OPTION, true, "change a coordinator or bundle job"); 322 Option changeValue = new Option(CHANGE_VALUE_OPTION, true, 323 "new endtime/concurrency/pausetime value for changing a coordinator job"); 324 Option info = new Option(INFO_OPTION, true, "info of a job"); 325 Option poll = new Option(POLL_OPTION, true, "poll Oozie until a job reaches a terminal state or a timeout occurs"); 326 Option offset = new Option(OFFSET_OPTION, true, "job info offset of actions (default '1', requires -info)"); 327 Option len = new Option(LEN_OPTION, true, "number of actions (default TOTAL ACTIONS, requires -info)"); 328 Option filter = new Option(FILTER_OPTION, true, 329 "<key><comparator><value>[;<key><comparator><value>]*\n" 330 + "(All Coordinator actions satisfying the filters will be retreived).\n" 331 + "key: status or nominaltime\n" 332 + "comparator: =, !=, <, <=, >, >=. = is used as OR and others as AND\n" 333 + "status: values are valid status like SUCCEEDED, KILLED etc. Only = and != apply for status\n" 334 + "nominaltime: time of format yyyy-MM-dd'T'HH:mm'Z'"); 335 Option order = new Option(ORDER_OPTION, true, 336 "order to show coord actions (default ascending order, 'desc' for descending order, requires -info)"); 337 Option localtime = new Option(LOCAL_TIME_OPTION, false, "use local time (same as passing your time zone to -" + 338 TIME_ZONE_OPTION + "). Overrides -" + TIME_ZONE_OPTION + " option"); 339 Option timezone = new Option(TIME_ZONE_OPTION, true, 340 "use time zone with the specified ID (default GMT).\nSee 'oozie info -timezones' for a list"); 341 Option log = new Option(LOG_OPTION, true, "job log"); 342 Option errorlog = new Option(ERROR_LOG_OPTION, true, "job error log"); 343 Option auditlog = new Option(AUDIT_LOG_OPTION, true, "job audit log"); 344 Option logFilter = new Option( 345 RestConstants.LOG_FILTER_OPTION, true, 346 "job log search parameter. Can be specified as -logfilter opt1=val1;opt2=val1;opt3=val1. " 347 + "Supported options are recent, start, end, loglevel, text, limit and debug"); 348 Option definition = new Option(DEFINITION_OPTION, true, "job definition"); 349 Option config_content = new Option(CONFIG_CONTENT_OPTION, true, "job configuration"); 350 Option verbose = new Option(VERBOSE_OPTION, false, "verbose mode"); 351 Option action = new Option(ACTION_OPTION, true, 352 "coordinator rerun/kill on action ids (requires -rerun/-kill); coordinator log retrieval on action ids" 353 + "(requires -log)"); 354 Option date = new Option(DATE_OPTION, true, 355 "coordinator/bundle rerun on action dates (requires -rerun); coordinator log retrieval on action dates (requires -log)"); 356 Option rerun_coord = new Option(COORD_OPTION, true, "bundle rerun on coordinator names (requires -rerun)"); 357 Option rerun_refresh = new Option(RERUN_REFRESH_OPTION, false, 358 "re-materialize the coordinator rerun actions (requires -rerun)"); 359 Option rerun_nocleanup = new Option(RERUN_NOCLEANUP_OPTION, false, 360 "do not clean up output-events of the coordiantor rerun actions (requires -rerun)"); 361 Option rerun_failed = new Option(RERUN_FAILED_OPTION, false, 362 "runs the failed workflow actions of the coordinator actions (requires -rerun)"); 363 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 364 "set/override value for given property").create("D"); 365 Option getAllWorkflows = new Option(ALL_WORKFLOWS_FOR_COORD_ACTION, false, 366 "Get workflow jobs corresponding to a coordinator action including all the reruns"); 367 Option ignore = new Option(IGNORE_OPTION, true, 368 "change status of a coordinator job or action to IGNORED" 369 + " (-action required to ignore coord actions)"); 370 Option timeout = new Option(TIMEOUT_OPTION, true, "timeout in minutes (default is 30, negative values indicate no " 371 + "timeout, requires -poll)"); 372 timeout.setType(Integer.class); 373 Option interval = new Option(INTERVAL_OPTION, true, "polling interval in minutes (default is 5, requires -poll)"); 374 interval.setType(Integer.class); 375 376 Option slaDisableAlert = new Option(SLA_DISABLE_ALERT, true, 377 "disables sla alerts for the job and its children"); 378 Option slaEnableAlert = new Option(SLA_ENABLE_ALERT, true, 379 "enables sla alerts for the job and its children"); 380 Option slaChange = new Option(SLA_CHANGE, true, 381 "Update sla param for jobs, supported param are should-start, should-end, nominal-time and max-duration"); 382 383 384 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 385 386 OptionGroup actions = new OptionGroup(); 387 actions.addOption(submit); 388 actions.addOption(start); 389 actions.addOption(run); 390 actions.addOption(dryrun); 391 actions.addOption(suspend); 392 actions.addOption(resume); 393 actions.addOption(kill); 394 actions.addOption(change); 395 actions.addOption(update); 396 actions.addOption(info); 397 actions.addOption(rerun); 398 actions.addOption(log); 399 actions.addOption(errorlog); 400 actions.addOption(auditlog); 401 actions.addOption(definition); 402 actions.addOption(config_content); 403 actions.addOption(ignore); 404 actions.addOption(poll); 405 actions.addOption(slaDisableAlert); 406 actions.addOption(slaEnableAlert); 407 actions.addOption(slaChange); 408 409 actions.setRequired(true); 410 Options jobOptions = new Options(); 411 jobOptions.addOption(oozie); 412 jobOptions.addOption(doAs); 413 jobOptions.addOption(config); 414 jobOptions.addOption(property); 415 jobOptions.addOption(changeValue); 416 jobOptions.addOption(localtime); 417 jobOptions.addOption(timezone); 418 jobOptions.addOption(verbose); 419 jobOptions.addOption(debug); 420 jobOptions.addOption(offset); 421 jobOptions.addOption(len); 422 jobOptions.addOption(filter); 423 jobOptions.addOption(order); 424 jobOptions.addOption(action); 425 jobOptions.addOption(date); 426 jobOptions.addOption(rerun_coord); 427 jobOptions.addOption(rerun_refresh); 428 jobOptions.addOption(rerun_nocleanup); 429 jobOptions.addOption(rerun_failed); 430 jobOptions.addOption(getAllWorkflows); 431 jobOptions.addOptionGroup(actions); 432 jobOptions.addOption(logFilter); 433 jobOptions.addOption(timeout); 434 jobOptions.addOption(interval); 435 addAuthOptions(jobOptions); 436 jobOptions.addOption(showdiff); 437 438 //Needed to make dryrun and update mutually exclusive options 439 OptionGroup updateOption = new OptionGroup(); 440 updateOption.addOption(dryrun); 441 jobOptions.addOptionGroup(updateOption); 442 443 return jobOptions; 444 } 445 446 /** 447 * Create option for command line option 'jobs' 448 * @return jobs options 449 */ 450 protected Options createJobsOptions() { 451 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 452 Option start = new Option(OFFSET_OPTION, true, "jobs offset (default '1')"); 453 Option jobtype = new Option(JOBTYPE_OPTION, true, 454 "job type ('Supported in Oozie-2.0 or later versions ONLY - 'coordinator' or 'bundle' or 'wf'(default))"); 455 Option len = new Option(LEN_OPTION, true, "number of jobs (default '100')"); 456 Option filter = new Option(FILTER_OPTION, true, 457 "user=<U>\\;name=<N>\\;group=<G>\\;status=<S>\\;frequency=<F>\\;unit=<M>" + 458 "\\;startcreatedtime=<SC>\\;endcreatedtime=<EC> \\;sortBy=<SB>" + 459 "(valid unit values are 'months', 'days', 'hours' or 'minutes'. " + 460 "startcreatedtime, endcreatedtime: time of format yyyy-MM-dd'T'HH:mm'Z'. " + 461 "valid values for sortBy are 'createdTime' or 'lastModifiedTime'.)"); 462 Option localtime = new Option(LOCAL_TIME_OPTION, false, "use local time (same as passing your time zone to -" + 463 TIME_ZONE_OPTION + "). Overrides -" + TIME_ZONE_OPTION + " option"); 464 Option kill = new Option(KILL_OPTION, false, "bulk kill operation"); 465 Option suspend = new Option(SUSPEND_OPTION, false, "bulk suspend operation"); 466 Option resume = new Option(RESUME_OPTION, false, "bulk resume operation"); 467 Option timezone = new Option(TIME_ZONE_OPTION, true, 468 "use time zone with the specified ID (default GMT).\nSee 'oozie info -timezones' for a list"); 469 Option verbose = new Option(VERBOSE_OPTION, false, "verbose mode"); 470 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 471 Option bulkMonitor = new Option(BULK_OPTION, true, "key-value pairs to filter bulk jobs response. e.g. bundle=<B>\\;" + 472 "coordinators=<C>\\;actionstatus=<S>\\;startcreatedtime=<SC>\\;endcreatedtime=<EC>\\;" + 473 "startscheduledtime=<SS>\\;endscheduledtime=<ES>\\; bundle, coordinators and actionstatus can be multiple comma separated values" + 474 "bundle and coordinators can be id(s) or appName(s) of those jobs. Specifying bundle is mandatory, other params are optional"); 475 start.setType(Integer.class); 476 len.setType(Integer.class); 477 Options jobsOptions = new Options(); 478 jobsOptions.addOption(oozie); 479 jobsOptions.addOption(doAs); 480 jobsOptions.addOption(localtime); 481 jobsOptions.addOption(kill); 482 jobsOptions.addOption(suspend); 483 jobsOptions.addOption(resume); 484 jobsOptions.addOption(timezone); 485 jobsOptions.addOption(start); 486 jobsOptions.addOption(len); 487 jobsOptions.addOption(oozie); 488 jobsOptions.addOption(filter); 489 jobsOptions.addOption(jobtype); 490 jobsOptions.addOption(verbose); 491 jobsOptions.addOption(bulkMonitor); 492 addAuthOptions(jobsOptions); 493 return jobsOptions; 494 } 495 496 /** 497 * Create option for command line option 'sla' 498 * 499 * @return sla options 500 */ 501 protected Options createSlaOptions() { 502 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 503 Option start = new Option(OFFSET_OPTION, true, "start offset (default '0')"); 504 Option len = new Option(LEN_OPTION, true, "number of results (default '100', max '1000')"); 505 Option filter = new Option(FILTER_OPTION, true, "filter of SLA events. e.g., jobid=<J>\\;appname=<A>"); 506 start.setType(Integer.class); 507 len.setType(Integer.class); 508 Options slaOptions = new Options(); 509 slaOptions.addOption(start); 510 slaOptions.addOption(len); 511 slaOptions.addOption(filter); 512 slaOptions.addOption(oozie); 513 addAuthOptions(slaOptions); 514 return slaOptions; 515 } 516 517 /** 518 * Create option for command line option 'validate' 519 * 520 * @return validate options 521 */ 522 protected Options createValidateOptions() { 523 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 524 Options validateOption = new Options(); 525 validateOption.addOption(oozie); 526 addAuthOptions(validateOption); 527 return validateOption; 528 } 529 530 /** 531 * Create option for command line option 'pig' or 'hive' 532 * @return pig or hive options 533 */ 534 @SuppressWarnings("static-access") 535 protected Options createScriptLanguageOptions(String jobType) { 536 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 537 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.properties'"); 538 Option file = new Option(SCRIPTFILE_OPTION, true, jobType + " script"); 539 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 540 "set/override value for given property").create("D"); 541 Option params = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 542 "set parameters for script").create("P"); 543 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 544 Options Options = new Options(); 545 Options.addOption(oozie); 546 Options.addOption(doAs); 547 Options.addOption(config); 548 Options.addOption(property); 549 Options.addOption(params); 550 Options.addOption(file); 551 addAuthOptions(Options); 552 return Options; 553 } 554 555 /** 556 * Create option for command line option 'sqoop' 557 * @return sqoop options 558 */ 559 @SuppressWarnings("static-access") 560 protected Options createSqoopCLIOptions() { 561 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 562 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.properties'"); 563 Option command = OptionBuilder.withArgName(SQOOP_COMMAND_OPTION).hasArgs().withValueSeparator().withDescription( 564 "sqoop command").create(SQOOP_COMMAND_OPTION); 565 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 566 "set/override value for given property").create("D"); 567 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 568 Options Options = new Options(); 569 Options.addOption(oozie); 570 Options.addOption(doAs); 571 Options.addOption(config); 572 Options.addOption(property); 573 Options.addOption(command); 574 addAuthOptions(Options); 575 return Options; 576 } 577 578 /** 579 * Create option for command line option 'info' 580 * @return info options 581 */ 582 protected Options createInfoOptions() { 583 Option timezones = new Option(INFO_TIME_ZONES_OPTION, false, "display a list of available time zones"); 584 Options infoOptions = new Options(); 585 infoOptions.addOption(timezones); 586 return infoOptions; 587 } 588 589 /** 590 * Create option for command line option 'mapreduce' 591 * @return mapreduce options 592 */ 593 @SuppressWarnings("static-access") 594 protected Options createMROptions() { 595 Option oozie = new Option(OOZIE_OPTION, true, "Oozie URL"); 596 Option config = new Option(CONFIG_OPTION, true, "job configuration file '.properties'"); 597 Option property = OptionBuilder.withArgName("property=value").hasArgs(2).withValueSeparator().withDescription( 598 "set/override value for given property").create("D"); 599 Option doAs = new Option(DO_AS_OPTION, true, "doAs user, impersonates as the specified user"); 600 Options mrOptions = new Options(); 601 mrOptions.addOption(oozie); 602 mrOptions.addOption(doAs); 603 mrOptions.addOption(config); 604 mrOptions.addOption(property); 605 addAuthOptions(mrOptions); 606 return mrOptions; 607 } 608 609 /** 610 * Run a CLI programmatically. 611 * <p> 612 * It does not exit the JVM. 613 * <p> 614 * A CLI instance can be used only once. 615 * 616 * @param args options and arguments for the Oozie CLI. 617 * @return '0' (success), '-1' (failure). 618 */ 619 public synchronized int run(String[] args) { 620 if (used) { 621 throw new IllegalStateException("CLI instance already used"); 622 } 623 used = true; 624 final CLIParser parser = getCLIParser(); 625 try { 626 final CLIParser.Command command = parser.parse(args); 627 628 String doAsUser = command.getCommandLine().getOptionValue(DO_AS_OPTION); 629 630 if (doAsUser != null) { 631 OozieClient.doAs(doAsUser, new Callable<Void>() { 632 @Override 633 public Void call() throws Exception { 634 processCommand(parser, command); 635 return null; 636 } 637 }); 638 } 639 else { 640 processCommand(parser, command); 641 } 642 return 0; 643 } 644 catch (OozieCLIException ex) { 645 System.err.println("Error: " + ex.getMessage()); 646 return -1; 647 } 648 catch (ParseException ex) { 649 System.err.println("Invalid sub-command: " + ex.getMessage()); 650 System.err.println(); 651 System.err.println(parser.shortHelp()); 652 return -1; 653 } 654 catch (Exception ex) { 655 ex.printStackTrace(); 656 System.err.println(ex.getMessage()); 657 return -1; 658 } 659 } 660 661 @VisibleForTesting 662 public CLIParser getCLIParser(){ 663 CLIParser parser = new CLIParser(OOZIE_OPTION, getCLIHelp()); 664 parser.addCommand(HELP_CMD, "", "display usage for all commands or specified command", new Options(), false); 665 parser.addCommand(VERSION_CMD, "", "show client version", new Options(), false); 666 parser.addCommand(JOB_CMD, "", "job operations", createJobOptions(), false); 667 parser.addCommand(JOBS_CMD, "", "jobs status", createJobsOptions(), false); 668 parser.addCommand(ADMIN_CMD, "", "admin operations", createAdminOptions(), false); 669 parser.addCommand(VALIDATE_CMD, "", "validate a workflow, coordinator, bundle XML file", createValidateOptions(), true); 670 parser.addCommand(SLA_CMD, "", "sla operations (Deprecated with Oozie 4.0)", createSlaOptions(), false); 671 parser.addCommand(PIG_CMD, "-X ", "submit a pig job, everything after '-X' are pass-through parameters to pig, any '-D' " 672 + "arguments after '-X' are put in <configuration>", createScriptLanguageOptions(PIG_CMD), true); 673 parser.addCommand(HIVE_CMD, "-X ", "submit a hive job, everything after '-X' are pass-through parameters to hive, any '-D' " 674 + "arguments after '-X' are put in <configuration>", createScriptLanguageOptions(HIVE_CMD), true); 675 parser.addCommand(SQOOP_CMD, "-X ", "submit a sqoop job, everything after '-X' are pass-through parameters " + 676 "to sqoop, any '-D' arguments after '-X' are put in <configuration>", createSqoopCLIOptions(), true); 677 parser.addCommand(INFO_CMD, "", "get more detailed info about specific topics", createInfoOptions(), false); 678 parser.addCommand(MR_CMD, "", "submit a mapreduce job", createMROptions(), false); 679 return parser; 680 } 681 682 public void processCommand(CLIParser parser, CLIParser.Command command) throws Exception { 683 if (command.getName().equals(HELP_CMD)) { 684 parser.showHelp(command.getCommandLine()); 685 } 686 else if (command.getName().equals(JOB_CMD)) { 687 jobCommand(command.getCommandLine()); 688 } 689 else if (command.getName().equals(JOBS_CMD)) { 690 jobsCommand(command.getCommandLine()); 691 } 692 else if (command.getName().equals(ADMIN_CMD)) { 693 adminCommand(command.getCommandLine()); 694 } 695 else if (command.getName().equals(VERSION_CMD)) { 696 versionCommand(); 697 } 698 else if (command.getName().equals(VALIDATE_CMD)) { 699 validateCommand(command.getCommandLine()); 700 } 701 else if (command.getName().equals(SLA_CMD)) { 702 slaCommand(command.getCommandLine()); 703 } 704 else if (command.getName().equals(PIG_CMD)) { 705 scriptLanguageCommand(command.getCommandLine(), PIG_CMD); 706 } 707 else if (command.getName().equals(HIVE_CMD)) { 708 scriptLanguageCommand(command.getCommandLine(), HIVE_CMD); 709 } 710 else if (command.getName().equals(SQOOP_CMD)) { 711 sqoopCommand(command.getCommandLine()); 712 } 713 else if (command.getName().equals(INFO_CMD)) { 714 infoCommand(command.getCommandLine()); 715 } 716 else if (command.getName().equals(MR_CMD)){ 717 mrCommand(command.getCommandLine()); 718 } 719 } 720 protected String getOozieUrl(CommandLine commandLine) { 721 String url = commandLine.getOptionValue(OOZIE_OPTION); 722 if (url == null) { 723 url = System.getenv(ENV_OOZIE_URL); 724 if (url == null) { 725 throw new IllegalArgumentException( 726 "Oozie URL is not available neither in command option or in the environment"); 727 } 728 } 729 return url; 730 } 731 732 private String getTimeZoneId(CommandLine commandLine) 733 { 734 if (commandLine.hasOption(LOCAL_TIME_OPTION)) { 735 return null; 736 } 737 if (commandLine.hasOption(TIME_ZONE_OPTION)) { 738 return commandLine.getOptionValue(TIME_ZONE_OPTION); 739 } 740 String timeZoneId = System.getenv(ENV_OOZIE_TIME_ZONE); 741 if (timeZoneId != null) { 742 return timeZoneId; 743 } 744 return "GMT"; 745 } 746 747 // Canibalized from Hadoop <code>Configuration.loadResource()</code>. 748 private Properties parse(InputStream is, Properties conf) throws IOException { 749 try { 750 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 751 docBuilderFactory.setNamespaceAware(true); 752 // support for includes in the xml file 753 docBuilderFactory.setXIncludeAware(true); 754 // ignore all comments inside the xml file 755 docBuilderFactory.setIgnoringComments(true); 756 docBuilderFactory.setExpandEntityReferences(false); 757 docBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); 758 DocumentBuilder builder = docBuilderFactory.newDocumentBuilder(); 759 Document doc = builder.parse(is); 760 return parseDocument(doc, conf); 761 } 762 catch (SAXException e) { 763 throw new IOException(e); 764 } 765 catch (ParserConfigurationException e) { 766 throw new IOException(e); 767 } 768 } 769 770 // Canibalized from Hadoop <code>Configuration.loadResource()</code>. 771 private Properties parseDocument(Document doc, Properties conf) throws IOException { 772 try { 773 Element root = doc.getDocumentElement(); 774 if (!"configuration".equals(root.getLocalName())) { 775 throw new RuntimeException("bad conf file: top-level element not <configuration>"); 776 } 777 NodeList props = root.getChildNodes(); 778 for (int i = 0; i < props.getLength(); i++) { 779 Node propNode = props.item(i); 780 if (!(propNode instanceof Element)) { 781 continue; 782 } 783 Element prop = (Element) propNode; 784 if (!"property".equals(prop.getLocalName())) { 785 throw new RuntimeException("bad conf file: element not <property>"); 786 } 787 NodeList fields = prop.getChildNodes(); 788 String attr = null; 789 String value = null; 790 for (int j = 0; j < fields.getLength(); j++) { 791 Node fieldNode = fields.item(j); 792 if (!(fieldNode instanceof Element)) { 793 continue; 794 } 795 Element field = (Element) fieldNode; 796 if ("name".equals(field.getLocalName()) && field.hasChildNodes()) { 797 attr = ((Text) field.getFirstChild()).getData(); 798 } 799 if ("value".equals(field.getLocalName()) && field.hasChildNodes()) { 800 value = ((Text) field.getFirstChild()).getData(); 801 } 802 } 803 804 if (attr != null && value != null) { 805 conf.setProperty(attr, value); 806 } 807 } 808 return conf; 809 } 810 catch (DOMException e) { 811 throw new IOException(e); 812 } 813 } 814 815 private Properties getConfiguration(OozieClient wc, CommandLine commandLine) throws IOException { 816 if (!isConfigurationSpecified(wc, commandLine)) { 817 throw new IOException("configuration is not specified"); 818 } 819 Properties conf = wc.createConfiguration(); 820 String configFile = commandLine.getOptionValue(CONFIG_OPTION); 821 if (configFile != null) { 822 File file = new File(configFile); 823 if (!file.exists()) { 824 throw new IOException("configuration file [" + configFile + "] not found"); 825 } 826 if (configFile.endsWith(".properties")) { 827 conf.load(new FileReader(file)); 828 } 829 else if (configFile.endsWith(".xml")) { 830 parse(new FileInputStream(configFile), conf); 831 } 832 else { 833 throw new IllegalArgumentException("configuration must be a '.properties' or a '.xml' file"); 834 } 835 } 836 if (commandLine.hasOption("D")) { 837 Properties commandLineProperties = commandLine.getOptionProperties("D"); 838 conf.putAll(commandLineProperties); 839 } 840 return conf; 841 } 842 843 /** 844 * Check if configuration has specified 845 * @param wc 846 * @param commandLine 847 * @return 848 * @throws IOException 849 */ 850 private boolean isConfigurationSpecified(OozieClient wc, CommandLine commandLine) throws IOException { 851 boolean isConf = false; 852 String configFile = commandLine.getOptionValue(CONFIG_OPTION); 853 if (configFile == null) { 854 isConf = false; 855 } 856 else { 857 isConf = new File(configFile).exists(); 858 } 859 if (commandLine.hasOption("D")) { 860 isConf = true; 861 } 862 return isConf; 863 } 864 865 /** 866 * @param commandLine command line string. 867 * @return change value specified by -value. 868 * @throws OozieCLIException 869 */ 870 private String getChangeValue(CommandLine commandLine) throws OozieCLIException { 871 String changeValue = commandLine.getOptionValue(CHANGE_VALUE_OPTION); 872 873 if (changeValue == null) { 874 throw new OozieCLIException("-value option needs to be specified for -change option"); 875 } 876 877 return changeValue; 878 } 879 880 protected void addHeader(OozieClient wc) { 881 for (Map.Entry entry : System.getProperties().entrySet()) { 882 String key = (String) entry.getKey(); 883 if (key.startsWith(WS_HEADER_PREFIX)) { 884 String header = key.substring(WS_HEADER_PREFIX.length()); 885 wc.setHeader(header, (String) entry.getValue()); 886 } 887 } 888 } 889 890 /** 891 * Get auth option from command line 892 * 893 * @param commandLine the command line object 894 * @return auth option 895 */ 896 protected String getAuthOption(CommandLine commandLine) { 897 String authOpt = commandLine.getOptionValue(AUTH_OPTION); 898 if (authOpt == null) { 899 authOpt = System.getenv(ENV_OOZIE_AUTH); 900 } 901 if (commandLine.hasOption(DEBUG_OPTION)) { 902 System.out.println(" Auth type : " + authOpt); 903 } 904 return authOpt; 905 } 906 907 /** 908 * Create a OozieClient. 909 * <p> 910 * It injects any '-Dheader:' as header to the the {@link org.apache.oozie.client.OozieClient}. 911 * 912 * @param commandLine the parsed command line options. 913 * @return a pre configured eXtended workflow client. 914 * @throws OozieCLIException thrown if the OozieClient could not be configured. 915 */ 916 protected OozieClient createOozieClient(CommandLine commandLine) throws OozieCLIException { 917 return createXOozieClient(commandLine); 918 } 919 920 /** 921 * Create a XOozieClient. 922 * <p> 923 * It injects any '-Dheader:' as header to the the {@link org.apache.oozie.client.OozieClient}. 924 * 925 * @param commandLine the parsed command line options. 926 * @return a pre configured eXtended workflow client. 927 * @throws OozieCLIException thrown if the XOozieClient could not be configured. 928 */ 929 protected XOozieClient createXOozieClient(CommandLine commandLine) throws OozieCLIException { 930 XOozieClient wc = new AuthOozieClient(getOozieUrl(commandLine), getAuthOption(commandLine)); 931 addHeader(wc); 932 setDebugMode(wc,commandLine.hasOption(DEBUG_OPTION)); 933 setRetryCount(wc); 934 return wc; 935 } 936 937 protected void setDebugMode(OozieClient wc, boolean debugOpt) { 938 939 String debug = System.getenv(ENV_OOZIE_DEBUG); 940 if (debug != null && !debug.isEmpty()) { 941 int debugVal = 0; 942 try { 943 debugVal = Integer.parseInt(debug.trim()); 944 } 945 catch (Exception ex) { 946 System.out.println("Unable to parse the debug settings. May be not an integer [" + debug + "]"); 947 ex.printStackTrace(); 948 } 949 wc.setDebugMode(debugVal); 950 } 951 else if(debugOpt){ // CLI argument "-debug" used 952 wc.setDebugMode(1); 953 } 954 } 955 956 protected void setRetryCount(OozieClient wc) { 957 String retryCount = System.getProperty(OOZIE_RETRY_COUNT); 958 if (retryCount != null && !retryCount.isEmpty()) { 959 try { 960 int retry = Integer.parseInt(retryCount.trim()); 961 wc.setRetryCount(retry); 962 } 963 catch (Exception ex) { 964 System.err.println("Unable to parse the retry settings. May be not an integer [" + retryCount + "]"); 965 ex.printStackTrace(); 966 } 967 } 968 } 969 970 private static String JOB_ID_PREFIX = "job: "; 971 972 private void jobCommand(CommandLine commandLine) throws IOException, OozieCLIException { 973 XOozieClient wc = createXOozieClient(commandLine); 974 975 List<String> options = new ArrayList<String>(); 976 for (Option option : commandLine.getOptions()) { 977 options.add(option.getOpt()); 978 } 979 980 try { 981 if (options.contains(SUBMIT_OPTION)) { 982 System.out.println(JOB_ID_PREFIX + wc.submit(getConfiguration(wc, commandLine))); 983 } 984 else if (options.contains(START_OPTION)) { 985 wc.start(commandLine.getOptionValue(START_OPTION)); 986 } 987 else if (options.contains(DRYRUN_OPTION) && !options.contains(UPDATE_OPTION)) { 988 String dryrunStr = wc.dryrun(getConfiguration(wc, commandLine)); 989 if (dryrunStr.equals("OK")) { // workflow 990 System.out.println("OK"); 991 } else { // coordinator 992 String[] dryrunStrs = dryrunStr.split("action for new instance"); 993 int arraysize = dryrunStrs.length; 994 System.out.println("***coordJob after parsing: ***"); 995 System.out.println(dryrunStrs[0]); 996 int aLen = dryrunStrs.length - 1; 997 if (aLen < 0) { 998 aLen = 0; 999 } 1000 System.out.println("***total coord actions is " + aLen + " ***"); 1001 for (int i = 1; i <= arraysize - 1; i++) { 1002 System.out.println(RULER); 1003 System.out.println("coordAction instance: " + i + ":"); 1004 System.out.println(dryrunStrs[i]); 1005 } 1006 } 1007 } 1008 else if (options.contains(SUSPEND_OPTION)) { 1009 wc.suspend(commandLine.getOptionValue(SUSPEND_OPTION)); 1010 } 1011 else if (options.contains(RESUME_OPTION)) { 1012 wc.resume(commandLine.getOptionValue(RESUME_OPTION)); 1013 } 1014 else if (options.contains(IGNORE_OPTION)) { 1015 String ignoreScope = null; 1016 if (options.contains(ACTION_OPTION)) { 1017 ignoreScope = commandLine.getOptionValue(ACTION_OPTION); 1018 if (ignoreScope == null || ignoreScope.isEmpty()) { 1019 throw new OozieCLIException("-" + ACTION_OPTION + " is empty"); 1020 } 1021 } 1022 printCoordActionsStatus(wc.ignore(commandLine.getOptionValue(IGNORE_OPTION), ignoreScope)); 1023 } 1024 else if (options.contains(KILL_OPTION)) { 1025 if (commandLine.getOptionValue(KILL_OPTION).contains("-C") 1026 && (options.contains(DATE_OPTION) || options.contains(ACTION_OPTION))) { 1027 String coordJobId = commandLine.getOptionValue(KILL_OPTION); 1028 String scope = null; 1029 String rangeType = null; 1030 if (options.contains(DATE_OPTION) && options.contains(ACTION_OPTION)) { 1031 throw new OozieCLIException("Invalid options provided for rerun: either" + DATE_OPTION + " or " 1032 + ACTION_OPTION + " expected. Don't use both at the same time."); 1033 } 1034 if (options.contains(DATE_OPTION)) { 1035 rangeType = RestConstants.JOB_COORD_SCOPE_DATE; 1036 scope = commandLine.getOptionValue(DATE_OPTION); 1037 } 1038 else if (options.contains(ACTION_OPTION)) { 1039 rangeType = RestConstants.JOB_COORD_SCOPE_ACTION; 1040 scope = commandLine.getOptionValue(ACTION_OPTION); 1041 } 1042 else { 1043 throw new OozieCLIException("Invalid options provided for rerun: " + DATE_OPTION + " or " 1044 + ACTION_OPTION + " expected."); 1045 } 1046 printCoordActions(wc.kill(coordJobId, rangeType, scope)); 1047 } 1048 else { 1049 wc.kill(commandLine.getOptionValue(KILL_OPTION)); 1050 } 1051 } 1052 else if (options.contains(CHANGE_OPTION)) { 1053 wc.change(commandLine.getOptionValue(CHANGE_OPTION), getChangeValue(commandLine)); 1054 } 1055 else if (options.contains(RUN_OPTION)) { 1056 System.out.println(JOB_ID_PREFIX + wc.run(getConfiguration(wc, commandLine))); 1057 } 1058 else if (options.contains(RERUN_OPTION)) { 1059 if (commandLine.getOptionValue(RERUN_OPTION).contains("-W")) { 1060 if (isConfigurationSpecified(wc, commandLine)) { 1061 wc.reRun(commandLine.getOptionValue(RERUN_OPTION), getConfiguration(wc, commandLine)); 1062 } 1063 else { 1064 wc.reRun(commandLine.getOptionValue(RERUN_OPTION), new Properties()); 1065 } 1066 } 1067 else if (commandLine.getOptionValue(RERUN_OPTION).contains("-B")) { 1068 String bundleJobId = commandLine.getOptionValue(RERUN_OPTION); 1069 String coordScope = null; 1070 String dateScope = null; 1071 boolean refresh = false; 1072 boolean noCleanup = false; 1073 if (options.contains(ACTION_OPTION)) { 1074 throw new OozieCLIException("Invalid options provided for bundle rerun. " + ACTION_OPTION 1075 + " is not valid for bundle rerun"); 1076 } 1077 if (options.contains(DATE_OPTION)) { 1078 dateScope = commandLine.getOptionValue(DATE_OPTION); 1079 } 1080 1081 if (options.contains(COORD_OPTION)) { 1082 coordScope = commandLine.getOptionValue(COORD_OPTION); 1083 } 1084 1085 if (options.contains(RERUN_REFRESH_OPTION)) { 1086 refresh = true; 1087 } 1088 if (options.contains(RERUN_NOCLEANUP_OPTION)) { 1089 noCleanup = true; 1090 } 1091 wc.reRunBundle(bundleJobId, coordScope, dateScope, refresh, noCleanup); 1092 if (coordScope != null && !coordScope.isEmpty()) { 1093 System.out.println("Coordinators [" + coordScope + "] of bundle " + bundleJobId 1094 + " are scheduled to rerun on date ranges [" + dateScope + "]."); 1095 } 1096 else { 1097 System.out.println("All coordinators of bundle " + bundleJobId 1098 + " are scheduled to rerun on the date ranges [" + dateScope + "]."); 1099 } 1100 } 1101 else { 1102 String coordJobId = commandLine.getOptionValue(RERUN_OPTION); 1103 String scope = null; 1104 String rerunType = null; 1105 boolean refresh = false; 1106 boolean noCleanup = false; 1107 boolean failed = false; 1108 if (options.contains(DATE_OPTION) && options.contains(ACTION_OPTION)) { 1109 throw new OozieCLIException("Invalid options provided for rerun: either" + DATE_OPTION + " or " 1110 + ACTION_OPTION + " expected. Don't use both at the same time."); 1111 } 1112 if (options.contains(DATE_OPTION)) { 1113 rerunType = RestConstants.JOB_COORD_SCOPE_DATE; 1114 scope = commandLine.getOptionValue(DATE_OPTION); 1115 } 1116 else if (options.contains(ACTION_OPTION)) { 1117 rerunType = RestConstants.JOB_COORD_SCOPE_ACTION; 1118 scope = commandLine.getOptionValue(ACTION_OPTION); 1119 } 1120 else { 1121 throw new OozieCLIException("Invalid options provided for rerun: " + DATE_OPTION + " or " 1122 + ACTION_OPTION + " expected."); 1123 } 1124 if (options.contains(RERUN_REFRESH_OPTION)) { 1125 refresh = true; 1126 } 1127 if (options.contains(RERUN_NOCLEANUP_OPTION)) { 1128 noCleanup = true; 1129 } 1130 1131 Properties props = null; 1132 if(isConfigurationSpecified(wc, commandLine)) { 1133 props = getConfiguration(wc, commandLine); 1134 } 1135 1136 if (options.contains(RERUN_FAILED_OPTION)) { 1137 failed = true; 1138 } 1139 1140 printCoordActions(wc.reRunCoord(coordJobId, rerunType, scope, refresh, noCleanup, failed, props)); 1141 } 1142 } 1143 else if (options.contains(INFO_OPTION)) { 1144 String timeZoneId = getTimeZoneId(commandLine); 1145 final String optionValue = commandLine.getOptionValue(INFO_OPTION); 1146 if (optionValue.endsWith("-B")) { 1147 String filter = commandLine.getOptionValue(FILTER_OPTION); 1148 if (filter != null) { 1149 throw new OozieCLIException("Filter option is currently not supported for a Bundle job"); 1150 } 1151 printBundleJob(wc.getBundleJobInfo(optionValue), timeZoneId, 1152 options.contains(VERBOSE_OPTION)); 1153 } 1154 else if (optionValue.endsWith("-C")) { 1155 String s = commandLine.getOptionValue(OFFSET_OPTION); 1156 int start = Integer.parseInt((s != null) ? s : "-1"); 1157 s = commandLine.getOptionValue(LEN_OPTION); 1158 int len = Integer.parseInt((s != null) ? s : "-1"); 1159 String filter = commandLine.getOptionValue(FILTER_OPTION); 1160 String order = commandLine.getOptionValue(ORDER_OPTION); 1161 printCoordJob(wc.getCoordJobInfo(optionValue, filter, start, len, order), timeZoneId, 1162 options.contains(VERBOSE_OPTION)); 1163 } 1164 else if (optionValue.contains("-C@")) { 1165 if (options.contains(ALL_WORKFLOWS_FOR_COORD_ACTION)) { 1166 printWfsForCoordAction(wc.getWfsForCoordAction(optionValue), timeZoneId); 1167 } 1168 else { 1169 String filter = commandLine.getOptionValue(FILTER_OPTION); 1170 if (filter != null) { 1171 throw new OozieCLIException("Filter option is not supported for a Coordinator action"); 1172 } 1173 printCoordAction(wc.getCoordActionInfo(optionValue), timeZoneId); 1174 } 1175 } 1176 else if (optionValue.contains("-W@")) { 1177 String filter = commandLine.getOptionValue(FILTER_OPTION); 1178 if (filter != null) { 1179 throw new OozieCLIException("Filter option is not supported for a Workflow action"); 1180 } 1181 printWorkflowAction(wc.getWorkflowActionInfo(optionValue), timeZoneId, 1182 options.contains(VERBOSE_OPTION)); 1183 } 1184 else { 1185 String filter = commandLine.getOptionValue(FILTER_OPTION); 1186 if (filter != null) { 1187 throw new OozieCLIException("Filter option is currently not supported for a Workflow job"); 1188 } 1189 String s = commandLine.getOptionValue(OFFSET_OPTION); 1190 int start = Integer.parseInt((s != null) ? s : "0"); 1191 s = commandLine.getOptionValue(LEN_OPTION); 1192 String jobtype = commandLine.getOptionValue(JOBTYPE_OPTION); 1193 jobtype = (jobtype != null) ? jobtype : "wf"; 1194 int len = Integer.parseInt((s != null) ? s : "0"); 1195 printJob(wc.getJobInfo(optionValue, start, len), timeZoneId, 1196 options.contains(VERBOSE_OPTION)); 1197 } 1198 } 1199 else if (options.contains(LOG_OPTION)) { 1200 PrintStream ps = System.out; 1201 String logFilter = null; 1202 if (options.contains(RestConstants.LOG_FILTER_OPTION)) { 1203 logFilter = commandLine.getOptionValue(RestConstants.LOG_FILTER_OPTION); 1204 } 1205 if (commandLine.getOptionValue(LOG_OPTION).contains("-C")) { 1206 String logRetrievalScope = null; 1207 String logRetrievalType = null; 1208 if (options.contains(ACTION_OPTION)) { 1209 logRetrievalType = RestConstants.JOB_LOG_ACTION; 1210 logRetrievalScope = commandLine.getOptionValue(ACTION_OPTION); 1211 } 1212 if (options.contains(DATE_OPTION)) { 1213 logRetrievalType = RestConstants.JOB_LOG_DATE; 1214 logRetrievalScope = commandLine.getOptionValue(DATE_OPTION); 1215 } 1216 try { 1217 wc.getJobLog(commandLine.getOptionValue(LOG_OPTION), logRetrievalType, logRetrievalScope, 1218 logFilter, ps); 1219 } 1220 finally { 1221 ps.close(); 1222 } 1223 } 1224 else { 1225 if (!options.contains(ACTION_OPTION) && !options.contains(DATE_OPTION)) { 1226 wc.getJobLog(commandLine.getOptionValue(LOG_OPTION), null, null, logFilter, ps); 1227 } 1228 else { 1229 throw new OozieCLIException("Invalid options provided for log retrieval. " + ACTION_OPTION 1230 + " and " + DATE_OPTION + " are valid only for coordinator job log retrieval"); 1231 } 1232 } 1233 } 1234 else if (options.contains(ERROR_LOG_OPTION)) { 1235 PrintStream ps = System.out; 1236 try { 1237 wc.getJobErrorLog(commandLine.getOptionValue(ERROR_LOG_OPTION), ps); 1238 } 1239 finally { 1240 ps.close(); 1241 } 1242 } 1243 else if (options.contains(AUDIT_LOG_OPTION)) { 1244 PrintStream ps = System.out; 1245 try { 1246 wc.getJobAuditLog(commandLine.getOptionValue(AUDIT_LOG_OPTION), ps); 1247 } 1248 finally { 1249 ps.close(); 1250 } 1251 } 1252 else if (options.contains(DEFINITION_OPTION)) { 1253 System.out.println(wc.getJobDefinition(commandLine.getOptionValue(DEFINITION_OPTION))); 1254 } 1255 else if (options.contains(CONFIG_CONTENT_OPTION)) { 1256 if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-C")) { 1257 System.out.println(wc.getCoordJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 1258 } 1259 else if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-W")) { 1260 System.out.println(wc.getJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 1261 } 1262 else if (commandLine.getOptionValue(CONFIG_CONTENT_OPTION).endsWith("-B")) { 1263 System.out 1264 .println(wc.getBundleJobInfo(commandLine.getOptionValue(CONFIG_CONTENT_OPTION)).getConf()); 1265 } 1266 else { 1267 System.out.println("ERROR: job id [" + commandLine.getOptionValue(CONFIG_CONTENT_OPTION) 1268 + "] doesn't end with either C or W or B"); 1269 } 1270 } 1271 else if (options.contains(UPDATE_OPTION)) { 1272 String coordJobId = commandLine.getOptionValue(UPDATE_OPTION); 1273 Properties conf = null; 1274 1275 String dryrun = ""; 1276 String showdiff = ""; 1277 1278 if (commandLine.getOptionValue(CONFIG_OPTION) != null) { 1279 conf = getConfiguration(wc, commandLine); 1280 } 1281 if (options.contains(DRYRUN_OPTION)) { 1282 dryrun = "true"; 1283 } 1284 if (commandLine.getOptionValue(SHOWDIFF_OPTION) != null) { 1285 showdiff = commandLine.getOptionValue(SHOWDIFF_OPTION); 1286 } 1287 if (conf == null) { 1288 System.out.println(wc.updateCoord(coordJobId, dryrun, showdiff)); 1289 } 1290 else { 1291 System.out.println(wc.updateCoord(coordJobId, conf, dryrun, showdiff)); 1292 } 1293 } 1294 else if (options.contains(POLL_OPTION)) { 1295 String jobId = commandLine.getOptionValue(POLL_OPTION); 1296 int timeout = 30; 1297 int interval = 5; 1298 String timeoutS = commandLine.getOptionValue(TIMEOUT_OPTION); 1299 if (timeoutS != null) { 1300 timeout = Integer.parseInt(timeoutS); 1301 } 1302 String intervalS = commandLine.getOptionValue(INTERVAL_OPTION); 1303 if (intervalS != null) { 1304 interval = Integer.parseInt(intervalS); 1305 } 1306 boolean verbose = commandLine.hasOption(VERBOSE_OPTION); 1307 wc.pollJob(jobId, timeout, interval, verbose); 1308 } 1309 else if (options.contains(SLA_ENABLE_ALERT)) { 1310 slaAlertCommand(commandLine.getOptionValue(SLA_ENABLE_ALERT), wc, commandLine, options); 1311 } 1312 else if (options.contains(SLA_DISABLE_ALERT)) { 1313 slaAlertCommand(commandLine.getOptionValue(SLA_DISABLE_ALERT), wc, commandLine, options); 1314 } 1315 else if (options.contains(SLA_CHANGE)) { 1316 slaAlertCommand(commandLine.getOptionValue(SLA_CHANGE), wc, commandLine, options); 1317 } 1318 } 1319 catch (OozieClientException ex) { 1320 throw new OozieCLIException(ex.toString(), ex); 1321 } 1322 } 1323 1324 @VisibleForTesting 1325 void printCoordJob(CoordinatorJob coordJob, String timeZoneId, boolean verbose) { 1326 System.out.println("Job ID : " + coordJob.getId()); 1327 1328 System.out.println(RULER); 1329 1330 List<CoordinatorAction> actions = coordJob.getActions(); 1331 System.out.println("Job Name : " + maskIfNull(coordJob.getAppName())); 1332 System.out.println("App Path : " + maskIfNull(coordJob.getAppPath())); 1333 System.out.println("Status : " + coordJob.getStatus()); 1334 System.out.println("Start Time : " + maskDate(coordJob.getStartTime(), timeZoneId, false)); 1335 System.out.println("End Time : " + maskDate(coordJob.getEndTime(), timeZoneId, false)); 1336 System.out.println("Pause Time : " + maskDate(coordJob.getPauseTime(), timeZoneId, false)); 1337 System.out.println("Concurrency : " + coordJob.getConcurrency()); 1338 System.out.println(RULER); 1339 1340 if (verbose) { 1341 System.out.println("ID" + VERBOSE_DELIMITER + "Action Number" + VERBOSE_DELIMITER + "Console URL" 1342 + VERBOSE_DELIMITER + "Error Code" + VERBOSE_DELIMITER + "Error Message" + VERBOSE_DELIMITER 1343 + "External ID" + VERBOSE_DELIMITER + "External Status" + VERBOSE_DELIMITER + "Job ID" 1344 + VERBOSE_DELIMITER + "Tracker URI" + VERBOSE_DELIMITER + "Created" + VERBOSE_DELIMITER 1345 + "Nominal Time" + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Last Modified" 1346 + VERBOSE_DELIMITER + "Missing Dependencies"); 1347 System.out.println(RULER); 1348 1349 for (CoordinatorAction action : actions) { 1350 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER + action.getActionNumber() 1351 + VERBOSE_DELIMITER + maskIfNull(action.getConsoleUrl()) + VERBOSE_DELIMITER 1352 + maskIfNull(action.getErrorCode()) + VERBOSE_DELIMITER + maskIfNull(action.getErrorMessage()) 1353 + VERBOSE_DELIMITER + maskIfNull(action.getExternalId()) + VERBOSE_DELIMITER 1354 + maskIfNull(action.getExternalStatus()) + VERBOSE_DELIMITER + maskIfNull(action.getJobId()) 1355 + VERBOSE_DELIMITER + maskIfNull(action.getTrackerUri()) + VERBOSE_DELIMITER 1356 + maskDate(action.getCreatedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1357 + maskDate(action.getNominalTime(), timeZoneId, verbose) + action.getStatus() + VERBOSE_DELIMITER 1358 + maskDate(action.getLastModifiedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1359 + maskIfNull(getFirstMissingDependencies(action))); 1360 1361 System.out.println(RULER); 1362 } 1363 } 1364 else { 1365 System.out.println(String.format(COORD_ACTION_FORMATTER, "ID", "Status", "Ext ID", "Err Code", "Created", 1366 "Nominal Time", "Last Mod")); 1367 1368 for (CoordinatorAction action : actions) { 1369 System.out.println(String.format(COORD_ACTION_FORMATTER, maskIfNull(action.getId()), 1370 action.getStatus(), maskIfNull(action.getExternalId()), maskIfNull(action.getErrorCode()), 1371 maskDate(action.getCreatedTime(), timeZoneId, verbose), maskDate(action.getNominalTime(), timeZoneId, verbose), 1372 maskDate(action.getLastModifiedTime(), timeZoneId, verbose))); 1373 1374 System.out.println(RULER); 1375 } 1376 } 1377 } 1378 1379 @VisibleForTesting 1380 void printBundleJob(BundleJob bundleJob, String timeZoneId, boolean verbose) { 1381 System.out.println("Job ID : " + bundleJob.getId()); 1382 1383 System.out.println(RULER); 1384 1385 List<CoordinatorJob> coordinators = bundleJob.getCoordinators(); 1386 System.out.println("Job Name : " + maskIfNull(bundleJob.getAppName())); 1387 System.out.println("App Path : " + maskIfNull(bundleJob.getAppPath())); 1388 System.out.println("Status : " + bundleJob.getStatus()); 1389 System.out.println("Kickoff time : " + bundleJob.getKickoffTime()); 1390 System.out.println(RULER); 1391 1392 System.out.println(String.format(BUNDLE_COORD_JOBS_FORMATTER, "Job ID", "Status", "Freq", "Unit", "Started", 1393 "Next Materialized")); 1394 System.out.println(RULER); 1395 1396 for (CoordinatorJob job : coordinators) { 1397 System.out.println(String.format(BUNDLE_COORD_JOBS_FORMATTER, maskIfNull(job.getId()), job.getStatus(), 1398 job.getFrequency(), job.getTimeUnit(), maskDate(job.getStartTime(), timeZoneId, verbose), 1399 maskDate(job.getNextMaterializedTime(), timeZoneId, verbose))); 1400 1401 System.out.println(RULER); 1402 } 1403 } 1404 1405 @VisibleForTesting 1406 void printCoordAction(CoordinatorAction coordAction, String timeZoneId) { 1407 System.out.println("ID : " + maskIfNull(coordAction.getId())); 1408 1409 System.out.println(RULER); 1410 1411 System.out.println("Action Number : " + coordAction.getActionNumber()); 1412 System.out.println("Console URL : " + maskIfNull(coordAction.getConsoleUrl())); 1413 System.out.println("Error Code : " + maskIfNull(coordAction.getErrorCode())); 1414 System.out.println("Error Message : " + maskIfNull(coordAction.getErrorMessage())); 1415 System.out.println("External ID : " + maskIfNull(coordAction.getExternalId())); 1416 System.out.println("External Status : " + maskIfNull(coordAction.getExternalStatus())); 1417 System.out.println("Job ID : " + maskIfNull(coordAction.getJobId())); 1418 System.out.println("Tracker URI : " + maskIfNull(coordAction.getTrackerUri())); 1419 System.out.println("Created : " + maskDate(coordAction.getCreatedTime(), timeZoneId, false)); 1420 System.out.println("Nominal Time : " + maskDate(coordAction.getNominalTime(), timeZoneId, false)); 1421 System.out.println("Status : " + coordAction.getStatus()); 1422 System.out.println("Last Modified : " + maskDate(coordAction.getLastModifiedTime(), timeZoneId, false)); 1423 System.out.println("First Missing Dependency : " + maskIfNull(getFirstMissingDependencies(coordAction))); 1424 1425 System.out.println(RULER); 1426 } 1427 1428 private void printCoordActions(List<CoordinatorAction> actions) { 1429 if (actions != null && actions.size() > 0) { 1430 System.out.println("Action ID" + VERBOSE_DELIMITER + "Nominal Time"); 1431 System.out.println(RULER); 1432 for (CoordinatorAction action : actions) { 1433 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER 1434 + maskDate(action.getNominalTime(), null,false)); 1435 } 1436 } 1437 else { 1438 System.out.println("No Actions match your criteria!"); 1439 } 1440 } 1441 1442 private void printCoordActionsStatus(List<CoordinatorAction> actions) { 1443 if (actions != null && actions.size() > 0) { 1444 System.out.println("Action ID" + VERBOSE_DELIMITER + "Nominal Time" + VERBOSE_DELIMITER + "Status"); 1445 System.out.println(RULER); 1446 for (CoordinatorAction action : actions) { 1447 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER 1448 + maskDate(action.getNominalTime(), null, false) + VERBOSE_DELIMITER 1449 + maskIfNull(action.getStatus().name())); 1450 } 1451 } 1452 } 1453 1454 @VisibleForTesting 1455 void printWorkflowAction(WorkflowAction action, String timeZoneId, boolean verbose) { 1456 1457 System.out.println("ID : " + maskIfNull(action.getId())); 1458 1459 System.out.println(RULER); 1460 1461 System.out.println("Console URL : " + maskIfNull(action.getConsoleUrl())); 1462 System.out.println("Error Code : " + maskIfNull(action.getErrorCode())); 1463 System.out.println("Error Message : " + maskIfNull(action.getErrorMessage())); 1464 System.out.println("External ID : " + maskIfNull(action.getExternalId())); 1465 System.out.println("External Status : " + maskIfNull(action.getExternalStatus())); 1466 System.out.println("Name : " + maskIfNull(action.getName())); 1467 System.out.println("Retries : " + action.getRetries()); 1468 System.out.println("Tracker URI : " + maskIfNull(action.getTrackerUri())); 1469 System.out.println("Type : " + maskIfNull(action.getType())); 1470 System.out.println("Started : " + maskDate(action.getStartTime(), timeZoneId, verbose)); 1471 System.out.println("Status : " + action.getStatus()); 1472 System.out.println("Ended : " + maskDate(action.getEndTime(), timeZoneId, verbose)); 1473 1474 if (verbose) { 1475 System.out.println("External Stats : " + action.getStats()); 1476 System.out.println("External ChildIDs : " + action.getExternalChildIDs()); 1477 } 1478 1479 System.out.println(RULER); 1480 } 1481 1482 private static final String WORKFLOW_JOBS_FORMATTER = "%-41s%-13s%-10s%-10s%-10s%-24s%-24s"; 1483 private static final String COORD_JOBS_FORMATTER = "%-41s%-15s%-10s%-5s%-13s%-24s%-24s"; 1484 private static final String BUNDLE_JOBS_FORMATTER = "%-41s%-15s%-10s%-20s%-20s%-13s%-13s"; 1485 private static final String BUNDLE_COORD_JOBS_FORMATTER = "%-41s%-15s%-5s%-13s%-24s%-24s"; 1486 1487 private static final String WORKFLOW_ACTION_FORMATTER = "%-78s%-10s%-23s%-11s%-10s"; 1488 private static final String COORD_ACTION_FORMATTER = "%-43s%-10s%-37s%-10s%-21s%-21s"; 1489 private static final String BULK_RESPONSE_FORMATTER = "%-13s%-38s%-13s%-41s%-10s%-38s%-21s%-38s"; 1490 1491 @VisibleForTesting 1492 void printJob(WorkflowJob job, String timeZoneId, boolean verbose) throws IOException { 1493 System.out.println("Job ID : " + maskIfNull(job.getId())); 1494 1495 System.out.println(RULER); 1496 1497 System.out.println("Workflow Name : " + maskIfNull(job.getAppName())); 1498 System.out.println("App Path : " + maskIfNull(job.getAppPath())); 1499 System.out.println("Status : " + job.getStatus()); 1500 System.out.println("Run : " + job.getRun()); 1501 System.out.println("User : " + maskIfNull(job.getUser())); 1502 System.out.println("Group : " + maskIfNull(job.getGroup())); 1503 System.out.println("Created : " + maskDate(job.getCreatedTime(), timeZoneId, verbose)); 1504 System.out.println("Started : " + maskDate(job.getStartTime(), timeZoneId, verbose)); 1505 System.out.println("Last Modified : " + maskDate(job.getLastModifiedTime(), timeZoneId, verbose)); 1506 System.out.println("Ended : " + maskDate(job.getEndTime(), timeZoneId, verbose)); 1507 System.out.println("CoordAction ID: " + maskIfNull(job.getParentId())); 1508 1509 List<WorkflowAction> actions = job.getActions(); 1510 1511 if (actions != null && actions.size() > 0) { 1512 System.out.println(); 1513 System.out.println("Actions"); 1514 System.out.println(RULER); 1515 1516 if (verbose) { 1517 System.out.println("ID" + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "Error Code" 1518 + VERBOSE_DELIMITER + "Error Message" + VERBOSE_DELIMITER + "External ID" + VERBOSE_DELIMITER 1519 + "External Status" + VERBOSE_DELIMITER + "Name" + VERBOSE_DELIMITER + "Retries" 1520 + VERBOSE_DELIMITER + "Tracker URI" + VERBOSE_DELIMITER + "Type" + VERBOSE_DELIMITER 1521 + "Started" + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Ended"); 1522 System.out.println(RULER); 1523 1524 for (WorkflowAction action : job.getActions()) { 1525 System.out.println(maskIfNull(action.getId()) + VERBOSE_DELIMITER 1526 + maskIfNull(action.getConsoleUrl()) + VERBOSE_DELIMITER 1527 + maskIfNull(action.getErrorCode()) + VERBOSE_DELIMITER 1528 + maskIfNull(action.getErrorMessage()) + VERBOSE_DELIMITER 1529 + maskIfNull(action.getExternalId()) + VERBOSE_DELIMITER 1530 + maskIfNull(action.getExternalStatus()) + VERBOSE_DELIMITER + maskIfNull(action.getName()) 1531 + VERBOSE_DELIMITER + action.getRetries() + VERBOSE_DELIMITER 1532 + maskIfNull(action.getTrackerUri()) + VERBOSE_DELIMITER + maskIfNull(action.getType()) 1533 + VERBOSE_DELIMITER + maskDate(action.getStartTime(), timeZoneId, verbose) 1534 + VERBOSE_DELIMITER + action.getStatus() + VERBOSE_DELIMITER 1535 + maskDate(action.getEndTime(), timeZoneId, verbose)); 1536 1537 System.out.println(RULER); 1538 } 1539 } 1540 else { 1541 System.out.println(String.format(WORKFLOW_ACTION_FORMATTER, "ID", "Status", "Ext ID", "Ext Status", 1542 "Err Code")); 1543 1544 System.out.println(RULER); 1545 1546 for (WorkflowAction action : job.getActions()) { 1547 System.out.println(String.format(WORKFLOW_ACTION_FORMATTER, maskIfNull(action.getId()), action 1548 .getStatus(), maskIfNull(action.getExternalId()), maskIfNull(action.getExternalStatus()), 1549 maskIfNull(action.getErrorCode()))); 1550 1551 System.out.println(RULER); 1552 } 1553 } 1554 } 1555 else { 1556 System.out.println(RULER); 1557 } 1558 1559 System.out.println(); 1560 } 1561 1562 private void jobsCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1563 XOozieClient wc = createXOozieClient(commandLine); 1564 1565 List<String> options = new ArrayList<String>(); 1566 for (Option option : commandLine.getOptions()) { 1567 options.add(option.getOpt()); 1568 } 1569 1570 String filter = commandLine.getOptionValue(FILTER_OPTION); 1571 String s = commandLine.getOptionValue(OFFSET_OPTION); 1572 int start = Integer.parseInt((s != null) ? s : "0"); 1573 s = commandLine.getOptionValue(LEN_OPTION); 1574 String jobtype = commandLine.getOptionValue(JOBTYPE_OPTION); 1575 String timeZoneId = getTimeZoneId(commandLine); 1576 jobtype = (jobtype != null) ? jobtype : "wf"; 1577 int len = Integer.parseInt((s != null) ? s : "0"); 1578 String bulkFilterString = commandLine.getOptionValue(BULK_OPTION); 1579 1580 try { 1581 if (options.contains(KILL_OPTION)) { 1582 printBulkModifiedJobs(wc.killJobs(filter, jobtype, start, len), timeZoneId, "killed"); 1583 } 1584 else if (options.contains(SUSPEND_OPTION)) { 1585 printBulkModifiedJobs(wc.suspendJobs(filter, jobtype, start, len), timeZoneId, "suspended"); 1586 } 1587 else if (options.contains(RESUME_OPTION)) { 1588 printBulkModifiedJobs(wc.resumeJobs(filter, jobtype, start, len), timeZoneId, "resumed"); 1589 } 1590 else if (bulkFilterString != null) { 1591 printBulkJobs(wc.getBulkInfo(bulkFilterString, start, len), timeZoneId, commandLine.hasOption(VERBOSE_OPTION)); 1592 } 1593 else if (jobtype.toLowerCase().contains("wf")) { 1594 printJobs(wc.getJobsInfo(filter, start, len), timeZoneId, commandLine.hasOption(VERBOSE_OPTION)); 1595 } 1596 else if (jobtype.toLowerCase().startsWith("coord")) { 1597 printCoordJobs(wc.getCoordJobsInfo(filter, start, len), timeZoneId, commandLine.hasOption(VERBOSE_OPTION)); 1598 } 1599 else if (jobtype.toLowerCase().startsWith("bundle")) { 1600 printBundleJobs(wc.getBundleJobsInfo(filter, start, len), timeZoneId, commandLine.hasOption(VERBOSE_OPTION)); 1601 } 1602 1603 } 1604 catch (OozieClientException ex) { 1605 throw new OozieCLIException(ex.toString(), ex); 1606 } 1607 } 1608 1609 @VisibleForTesting 1610 void printBulkModifiedJobs(JSONObject json, String timeZoneId, String action) throws IOException { 1611 if (json.containsKey(JsonTags.WORKFLOWS_JOBS)) { 1612 JSONArray workflows = (JSONArray) json.get(JsonTags.WORKFLOWS_JOBS); 1613 if (workflows == null) { 1614 workflows = new JSONArray(); 1615 } 1616 List<WorkflowJob> wfs = JsonToBean.createWorkflowJobList(workflows); 1617 if (wfs.isEmpty()) { 1618 System.out.println("bulk modify command did not modify any jobs"); 1619 } 1620 else { 1621 System.out.println("the following jobs have been " + action); 1622 printJobs(wfs, timeZoneId, false); 1623 } 1624 } 1625 else if (json.containsKey(JsonTags.COORDINATOR_JOBS)) { 1626 JSONArray coordinators = (JSONArray) json.get(JsonTags.COORDINATOR_JOBS); 1627 if (coordinators == null) { 1628 coordinators = new JSONArray(); 1629 } 1630 List<CoordinatorJob> coords = JsonToBean.createCoordinatorJobList(coordinators); 1631 if (coords.isEmpty()) { 1632 System.out.println("bulk modify command did not modify any jobs"); 1633 } 1634 else { 1635 System.out.println("the following jobs have been " + action); 1636 printCoordJobs(coords, timeZoneId, false); 1637 } 1638 } 1639 else { 1640 JSONArray bundles = (JSONArray) json.get(JsonTags.BUNDLE_JOBS); 1641 if (bundles == null) { 1642 bundles = new JSONArray(); 1643 } 1644 List<BundleJob> bundleJobs = JsonToBean.createBundleJobList(bundles); 1645 if (bundleJobs.isEmpty()) { 1646 System.out.println("bulk modify command did not modify any jobs"); 1647 } 1648 else { 1649 System.out.println("the following jobs have been " + action); 1650 printBundleJobs(bundleJobs, timeZoneId, false); 1651 } 1652 } 1653 } 1654 1655 @VisibleForTesting 1656 void printCoordJobs(List<CoordinatorJob> jobs, String timeZoneId, boolean verbose) throws IOException { 1657 if (jobs != null && jobs.size() > 0) { 1658 if (verbose) { 1659 System.out.println("Job ID" + VERBOSE_DELIMITER + "App Name" + VERBOSE_DELIMITER + "App Path" 1660 + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" 1661 + VERBOSE_DELIMITER + "Concurrency" + VERBOSE_DELIMITER + "Frequency" + VERBOSE_DELIMITER 1662 + "Time Unit" + VERBOSE_DELIMITER + "Time Zone" + VERBOSE_DELIMITER + "Time Out" 1663 + VERBOSE_DELIMITER + "Started" + VERBOSE_DELIMITER + "Next Materialize" + VERBOSE_DELIMITER 1664 + "Status" + VERBOSE_DELIMITER + "Last Action" + VERBOSE_DELIMITER + "Ended"); 1665 System.out.println(RULER); 1666 1667 for (CoordinatorJob job : jobs) { 1668 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1669 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1670 + maskIfNull(job.getConsoleUrl()) + VERBOSE_DELIMITER + maskIfNull(job.getUser()) 1671 + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) + VERBOSE_DELIMITER + job.getConcurrency() 1672 + VERBOSE_DELIMITER + job.getFrequency() + VERBOSE_DELIMITER + job.getTimeUnit() 1673 + VERBOSE_DELIMITER + maskIfNull(job.getTimeZone()) + VERBOSE_DELIMITER + job.getTimeout() 1674 + VERBOSE_DELIMITER + maskDate(job.getStartTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1675 + maskDate(job.getNextMaterializedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1676 + job.getStatus() + VERBOSE_DELIMITER 1677 + maskDate(job.getLastActionTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1678 + maskDate(job.getEndTime(), timeZoneId, verbose)); 1679 1680 System.out.println(RULER); 1681 } 1682 } 1683 else { 1684 System.out.println(String.format(COORD_JOBS_FORMATTER, "Job ID", "App Name", "Status", "Freq", "Unit", 1685 "Started", "Next Materialized")); 1686 System.out.println(RULER); 1687 1688 for (CoordinatorJob job : jobs) { 1689 System.out.println(String.format(COORD_JOBS_FORMATTER, maskIfNull(job.getId()), maskIfNull(job 1690 .getAppName()), job.getStatus(), job.getFrequency(), job.getTimeUnit(), maskDate(job 1691 .getStartTime(), timeZoneId, verbose), maskDate(job.getNextMaterializedTime(), timeZoneId, verbose))); 1692 1693 System.out.println(RULER); 1694 } 1695 } 1696 } 1697 else { 1698 System.out.println("No Jobs match your criteria!"); 1699 } 1700 } 1701 1702 @VisibleForTesting 1703 void printBulkJobs(List<BulkResponse> jobs, String timeZoneId, boolean verbose) throws IOException { 1704 if (jobs != null && jobs.size() > 0) { 1705 for (BulkResponse response : jobs) { 1706 BundleJob bundle = response.getBundle(); 1707 CoordinatorJob coord = response.getCoordinator(); 1708 CoordinatorAction action = response.getAction(); 1709 if (verbose) { 1710 System.out.println(); 1711 System.out.println("Bundle Name : " + maskIfNull(bundle.getAppName())); 1712 1713 System.out.println(RULER); 1714 1715 System.out.println("Bundle ID : " + maskIfNull(bundle.getId())); 1716 System.out.println("Coordinator Name : " + maskIfNull(coord.getAppName())); 1717 System.out.println("Coord Action ID : " + maskIfNull(action.getId())); 1718 System.out.println("Action Status : " + action.getStatus()); 1719 System.out.println("External ID : " + maskIfNull(action.getExternalId())); 1720 System.out.println("Created Time : " + maskDate(action.getCreatedTime(), timeZoneId, false)); 1721 System.out.println("User : " + maskIfNull(bundle.getUser())); 1722 System.out.println("Error Message : " + maskIfNull(action.getErrorMessage())); 1723 System.out.println(RULER); 1724 } 1725 else { 1726 System.out.println(String.format(BULK_RESPONSE_FORMATTER, "Bundle Name", "Bundle ID", "Coord Name", 1727 "Coord Action ID", "Status", "External ID", "Created Time", "Error Message")); 1728 System.out.println(RULER); 1729 System.out 1730 .println(String.format(BULK_RESPONSE_FORMATTER, maskIfNull(bundle.getAppName()), 1731 maskIfNull(bundle.getId()), maskIfNull(coord.getAppName()), 1732 maskIfNull(action.getId()), action.getStatus(), maskIfNull(action.getExternalId()), 1733 maskDate(action.getCreatedTime(), timeZoneId, false), 1734 maskIfNull(action.getErrorMessage()))); 1735 System.out.println(RULER); 1736 } 1737 } 1738 } 1739 else { 1740 System.out.println("Bulk request criteria did not match any coordinator actions"); 1741 } 1742 } 1743 1744 @VisibleForTesting 1745 void printBundleJobs(List<BundleJob> jobs, String timeZoneId, boolean verbose) throws IOException { 1746 if (jobs != null && jobs.size() > 0) { 1747 if (verbose) { 1748 System.out.println("Job ID" + VERBOSE_DELIMITER + "Bundle Name" + VERBOSE_DELIMITER + "Bundle Path" 1749 + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" + VERBOSE_DELIMITER + "Status" 1750 + VERBOSE_DELIMITER + "Kickoff" + VERBOSE_DELIMITER + "Pause" + VERBOSE_DELIMITER + "Created" 1751 + VERBOSE_DELIMITER + "Console URL"); 1752 System.out.println(RULER); 1753 1754 for (BundleJob job : jobs) { 1755 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1756 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1757 + maskIfNull(job.getUser()) + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) 1758 + VERBOSE_DELIMITER + job.getStatus() + VERBOSE_DELIMITER 1759 + maskDate(job.getKickoffTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1760 + maskDate(job.getPauseTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1761 + maskDate(job.getCreatedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1762 + maskIfNull(job.getConsoleUrl())); 1763 1764 System.out.println(RULER); 1765 } 1766 } 1767 else { 1768 System.out.println(String.format(BUNDLE_JOBS_FORMATTER, "Job ID", "Bundle Name", "Status", "Kickoff", 1769 "Created", "User", "Group")); 1770 System.out.println(RULER); 1771 1772 for (BundleJob job : jobs) { 1773 System.out.println(String.format(BUNDLE_JOBS_FORMATTER, maskIfNull(job.getId()), 1774 maskIfNull(job.getAppName()), job.getStatus(), 1775 maskDate(job.getKickoffTime(), timeZoneId, verbose), 1776 maskDate(job.getCreatedTime(), timeZoneId, verbose), maskIfNull(job.getUser()), 1777 maskIfNull(job.getGroup()))); 1778 System.out.println(RULER); 1779 } 1780 } 1781 } 1782 else { 1783 System.out.println("No Jobs match your criteria!"); 1784 } 1785 } 1786 1787 private void slaCommand(CommandLine commandLine) throws IOException, OozieCLIException { 1788 XOozieClient wc = createXOozieClient(commandLine); 1789 List<String> options = new ArrayList<String>(); 1790 for (Option option : commandLine.getOptions()) { 1791 options.add(option.getOpt()); 1792 } 1793 1794 String s = commandLine.getOptionValue(OFFSET_OPTION); 1795 int start = Integer.parseInt((s != null) ? s : "0"); 1796 s = commandLine.getOptionValue(LEN_OPTION); 1797 int len = Integer.parseInt((s != null) ? s : "100"); 1798 String filter = commandLine.getOptionValue(FILTER_OPTION); 1799 1800 try { 1801 wc.getSlaInfo(start, len, filter); 1802 } 1803 catch (OozieClientException ex) { 1804 throw new OozieCLIException(ex.toString(), ex); 1805 } 1806 } 1807 1808 private void adminCommand(CommandLine commandLine) throws OozieCLIException { 1809 XOozieClient wc = createXOozieClient(commandLine); 1810 1811 List<String> options = new ArrayList<String>(); 1812 for (Option option : commandLine.getOptions()) { 1813 options.add(option.getOpt()); 1814 } 1815 1816 try { 1817 SYSTEM_MODE status = SYSTEM_MODE.NORMAL; 1818 if (options.contains(VERSION_OPTION)) { 1819 System.out.println("Oozie server build version: " + wc.getServerBuildVersion()); 1820 } 1821 else if (options.contains(SYSTEM_MODE_OPTION)) { 1822 String systemModeOption = commandLine.getOptionValue(SYSTEM_MODE_OPTION).toUpperCase(); 1823 try { 1824 status = SYSTEM_MODE.valueOf(systemModeOption); 1825 } 1826 catch (Exception e) { 1827 throw new OozieCLIException("Invalid input provided for option: " + SYSTEM_MODE_OPTION 1828 + " value given :" + systemModeOption 1829 + " Expected values are: NORMAL/NOWEBSERVICE/SAFEMODE "); 1830 } 1831 wc.setSystemMode(status); 1832 System.out.println("System mode: " + status); 1833 } 1834 else if (options.contains(STATUS_OPTION)) { 1835 status = wc.getSystemMode(); 1836 System.out.println("System mode: " + status); 1837 } 1838 1839 else if (options.contains(UPDATE_SHARELIB_OPTION)) { 1840 System.out.println(wc.updateShareLib()); 1841 } 1842 1843 else if (options.contains(LIST_SHARELIB_LIB_OPTION)) { 1844 String sharelibKey = null; 1845 if (commandLine.getArgList().size() > 0) { 1846 sharelibKey = (String) commandLine.getArgList().get(0); 1847 } 1848 System.out.println(wc.listShareLib(sharelibKey)); 1849 } 1850 1851 else if (options.contains(QUEUE_DUMP_OPTION)) { 1852 1853 List<String> list = wc.getQueueDump(); 1854 if (list != null && list.size() != 0) { 1855 for (String str : list) { 1856 System.out.println(str); 1857 } 1858 } 1859 else { 1860 System.out.println("QueueDump is null!"); 1861 } 1862 } 1863 else if (options.contains(AVAILABLE_SERVERS_OPTION)) { 1864 Map<String, String> availableOozieServers = new TreeMap<String, String>(wc.getAvailableOozieServers()); 1865 for (Map.Entry<String, String> ent : availableOozieServers.entrySet()) { 1866 System.out.println(ent.getKey() + " : " + ent.getValue()); 1867 } 1868 } else if (options.contains(SERVER_CONFIGURATION_OPTION)) { 1869 Map<String, String> serverConfig = new TreeMap<String, String>(wc.getServerConfiguration()); 1870 for (Map.Entry<String, String> ent : serverConfig.entrySet()) { 1871 System.out.println(ent.getKey() + " : " + ent.getValue()); 1872 } 1873 } else if (options.contains(SERVER_OS_ENV_OPTION)) { 1874 Map<String, String> osEnv = new TreeMap<String, String>(wc.getOSEnv()); 1875 for (Map.Entry<String, String> ent : osEnv.entrySet()) { 1876 System.out.println(ent.getKey() + " : " + ent.getValue()); 1877 } 1878 } else if (options.contains(SERVER_JAVA_SYSTEM_PROPERTIES_OPTION)) { 1879 Map<String, String> javaSysProps = new TreeMap<String, String>(wc.getJavaSystemProperties()); 1880 for (Map.Entry<String, String> ent : javaSysProps.entrySet()) { 1881 System.out.println(ent.getKey() + " : " + ent.getValue()); 1882 } 1883 } else if (options.contains(METRICS_OPTION)) { 1884 OozieClient.Metrics metrics = wc.getMetrics(); 1885 if (metrics == null) { 1886 System.out.println("Metrics are unavailable. Try Instrumentation (-" + INSTRUMENTATION_OPTION + ") instead"); 1887 } else { 1888 printMetrics(metrics); 1889 } 1890 } else if (options.contains(INSTRUMENTATION_OPTION)) { 1891 OozieClient.Instrumentation instrumentation = wc.getInstrumentation(); 1892 if (instrumentation == null) { 1893 System.out.println("Instrumentation is unavailable. Try Metrics (-" + METRICS_OPTION + ") instead"); 1894 } else { 1895 printInstrumentation(instrumentation); 1896 } 1897 } 1898 } 1899 catch (OozieClientException ex) { 1900 throw new OozieCLIException(ex.toString(), ex); 1901 } 1902 } 1903 1904 private void versionCommand() throws OozieCLIException { 1905 System.out.println("Oozie client build version: " 1906 + BuildInfo.getBuildInfo().getProperty(BuildInfo.BUILD_VERSION)); 1907 } 1908 1909 @VisibleForTesting 1910 void printJobs(List<WorkflowJob> jobs, String timeZoneId, boolean verbose) throws IOException { 1911 if (jobs != null && jobs.size() > 0) { 1912 if (verbose) { 1913 System.out.println("Job ID" + VERBOSE_DELIMITER + "App Name" + VERBOSE_DELIMITER + "App Path" 1914 + VERBOSE_DELIMITER + "Console URL" + VERBOSE_DELIMITER + "User" + VERBOSE_DELIMITER + "Group" 1915 + VERBOSE_DELIMITER + "Run" + VERBOSE_DELIMITER + "Created" + VERBOSE_DELIMITER + "Started" 1916 + VERBOSE_DELIMITER + "Status" + VERBOSE_DELIMITER + "Last Modified" + VERBOSE_DELIMITER 1917 + "Ended"); 1918 System.out.println(RULER); 1919 1920 for (WorkflowJob job : jobs) { 1921 System.out.println(maskIfNull(job.getId()) + VERBOSE_DELIMITER + maskIfNull(job.getAppName()) 1922 + VERBOSE_DELIMITER + maskIfNull(job.getAppPath()) + VERBOSE_DELIMITER 1923 + maskIfNull(job.getConsoleUrl()) + VERBOSE_DELIMITER + maskIfNull(job.getUser()) 1924 + VERBOSE_DELIMITER + maskIfNull(job.getGroup()) + VERBOSE_DELIMITER + job.getRun() 1925 + VERBOSE_DELIMITER + maskDate(job.getCreatedTime(), timeZoneId, verbose) 1926 + VERBOSE_DELIMITER + maskDate(job.getStartTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1927 + job.getStatus() + VERBOSE_DELIMITER 1928 + maskDate(job.getLastModifiedTime(), timeZoneId, verbose) + VERBOSE_DELIMITER 1929 + maskDate(job.getEndTime(), timeZoneId, verbose)); 1930 1931 System.out.println(RULER); 1932 } 1933 } 1934 else { 1935 System.out.println(String.format(WORKFLOW_JOBS_FORMATTER, "Job ID", "App Name", "Status", "User", 1936 "Group", "Started", "Ended")); 1937 System.out.println(RULER); 1938 1939 for (WorkflowJob job : jobs) { 1940 System.out.println(String.format(WORKFLOW_JOBS_FORMATTER, maskIfNull(job.getId()), 1941 maskIfNull(job.getAppName()), job.getStatus(), maskIfNull(job.getUser()), 1942 maskIfNull(job.getGroup()), maskDate(job.getStartTime(), timeZoneId, verbose), 1943 maskDate(job.getEndTime(), timeZoneId, verbose))); 1944 1945 System.out.println(RULER); 1946 } 1947 } 1948 } 1949 else { 1950 System.out.println("No Jobs match your criteria!"); 1951 } 1952 } 1953 1954 void printWfsForCoordAction(List<WorkflowJob> jobs, String timeZoneId) throws IOException { 1955 if (jobs != null && jobs.size() > 0) { 1956 System.out.println(String.format("%-41s%-10s%-24s%-24s", "Job ID", "Status", "Started", "Ended")); 1957 System.out.println(RULER); 1958 1959 for (WorkflowJob job : jobs) { 1960 System.out 1961 .println(String.format("%-41s%-10s%-24s%-24s", maskIfNull(job.getId()), job.getStatus(), 1962 maskDate(job.getStartTime(), timeZoneId, false), 1963 maskDate(job.getEndTime(), timeZoneId, false))); 1964 System.out.println(RULER); 1965 } 1966 } 1967 } 1968 1969 private String maskIfNull(String value) { 1970 if (value != null && value.length() > 0) { 1971 return value; 1972 } 1973 return "-"; 1974 } 1975 1976 private String maskDate(Date date, String timeZoneId, boolean verbose) { 1977 if (date == null) { 1978 return "-"; 1979 } 1980 1981 SimpleDateFormat dateFormater = null; 1982 if (verbose) { 1983 dateFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz", Locale.US); 1984 } 1985 else { 1986 dateFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm zzz", Locale.US); 1987 } 1988 1989 if (timeZoneId != null) { 1990 dateFormater.setTimeZone(TimeZone.getTimeZone(timeZoneId)); 1991 } 1992 String dateString = dateFormater.format(date); 1993 // 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 1994 // to fit better 1995 Matcher m = GMT_OFFSET_SHORTEN_PATTERN.matcher(dateString); 1996 if (m.matches() && m.groupCount() == 2) { 1997 dateString = m.group(1) + m.group(2); 1998 } 1999 return dateString; 2000 } 2001 2002 private void validateCommand(CommandLine commandLine) throws OozieCLIException { 2003 String[] args = commandLine.getArgs(); 2004 if (args.length != 1) { 2005 throw new OozieCLIException("One file must be specified"); 2006 } 2007 try { 2008 XOozieClient wc = createXOozieClient(commandLine); 2009 String result = wc.validateXML(args[0].toString()); 2010 if (result == null) { 2011 // TODO This is only for backward compatibility. Need to remove after 4.2.0 higher version. 2012 System.out.println("Using client-side validation. Check out Oozie server version."); 2013 validateCommandV41(commandLine); 2014 return; 2015 } 2016 System.out.println(result); 2017 } catch (OozieClientException e) { 2018 throw new OozieCLIException(e.getMessage(), e); 2019 } 2020 } 2021 2022 /** 2023 * Validate on client-side. This is only for backward compatibility. Need to removed after <tt>4.2.0</tt> higher version. 2024 * @param commandLine 2025 * @throws OozieCLIException 2026 */ 2027 @Deprecated 2028 @VisibleForTesting 2029 void validateCommandV41(CommandLine commandLine) throws OozieCLIException { 2030 String[] args = commandLine.getArgs(); 2031 if (args.length != 1) { 2032 throw new OozieCLIException("One file must be specified"); 2033 } 2034 File file = new File(args[0]); 2035 if (file.exists()) { 2036 try { 2037 List<StreamSource> sources = new ArrayList<StreamSource>(); 2038 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2039 "oozie-workflow-0.1.xsd"))); 2040 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2041 "shell-action-0.1.xsd"))); 2042 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2043 "shell-action-0.2.xsd"))); 2044 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2045 "shell-action-0.3.xsd"))); 2046 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2047 "email-action-0.1.xsd"))); 2048 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2049 "email-action-0.2.xsd"))); 2050 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2051 "distcp-action-0.1.xsd"))); 2052 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2053 "distcp-action-0.2.xsd"))); 2054 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2055 "oozie-workflow-0.2.xsd"))); 2056 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2057 "oozie-workflow-0.2.5.xsd"))); 2058 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2059 "oozie-workflow-0.3.xsd"))); 2060 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2061 "oozie-workflow-0.4.xsd"))); 2062 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2063 "oozie-workflow-0.4.5.xsd"))); 2064 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2065 "oozie-workflow-0.5.xsd"))); 2066 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2067 "oozie-coordinator-0.1.xsd"))); 2068 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2069 "oozie-coordinator-0.2.xsd"))); 2070 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2071 "oozie-coordinator-0.3.xsd"))); 2072 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2073 "oozie-coordinator-0.4.xsd"))); 2074 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2075 "oozie-bundle-0.1.xsd"))); 2076 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2077 "oozie-bundle-0.2.xsd"))); 2078 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2079 "oozie-sla-0.1.xsd"))); 2080 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2081 "oozie-sla-0.2.xsd"))); 2082 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2083 "hive-action-0.2.xsd"))); 2084 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2085 "hive-action-0.3.xsd"))); 2086 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2087 "hive-action-0.4.xsd"))); 2088 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2089 "hive-action-0.5.xsd"))); 2090 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2091 "hive-action-0.6.xsd"))); 2092 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2093 "sqoop-action-0.2.xsd"))); 2094 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2095 "sqoop-action-0.3.xsd"))); 2096 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2097 "sqoop-action-0.4.xsd"))); 2098 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2099 "ssh-action-0.1.xsd"))); 2100 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2101 "ssh-action-0.2.xsd"))); 2102 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2103 "hive2-action-0.1.xsd"))); 2104 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2105 "hive2-action-0.2.xsd"))); 2106 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2107 "spark-action-0.1.xsd"))); 2108 sources.add(new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream( 2109 "spark-action-0.2.xsd"))); 2110 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 2111 Schema schema = factory.newSchema(sources.toArray(new StreamSource[sources.size()])); 2112 Validator validator = schema.newValidator(); 2113 validator.validate(new StreamSource(new FileReader(file))); 2114 System.out.println("Valid workflow-app"); 2115 } 2116 catch (Exception ex) { 2117 throw new OozieCLIException("Invalid app definition, " + ex.toString(), ex); 2118 } 2119 } 2120 else { 2121 throw new OozieCLIException("File does not exists"); 2122 } 2123 } 2124 2125 private void scriptLanguageCommand(CommandLine commandLine, String jobType) throws IOException, OozieCLIException { 2126 List<String> args = commandLine.getArgList(); 2127 if (args.size() > 0) { 2128 // checking if args starts with -X (because CLIParser cannot check this) 2129 if (!args.get(0).equals("-X")) { 2130 throw new OozieCLIException("Unrecognized option: " + args.get(0) + " Expecting -X"); 2131 } 2132 args.remove(0); 2133 } 2134 2135 if (!commandLine.hasOption(SCRIPTFILE_OPTION)) { 2136 throw new OozieCLIException("Need to specify -file <scriptfile>"); 2137 } 2138 2139 if (!commandLine.hasOption(CONFIG_OPTION)) { 2140 throw new OozieCLIException("Need to specify -config <configfile>"); 2141 } 2142 2143 try { 2144 XOozieClient wc = createXOozieClient(commandLine); 2145 Properties conf = getConfiguration(wc, commandLine); 2146 String script = commandLine.getOptionValue(SCRIPTFILE_OPTION); 2147 List<String> paramsList = new ArrayList<String>(); 2148 if (commandLine.hasOption("P")) { 2149 Properties params = commandLine.getOptionProperties("P"); 2150 for (String key : params.stringPropertyNames()) { 2151 paramsList.add(key + "=" + params.getProperty(key)); 2152 } 2153 } 2154 System.out.println(JOB_ID_PREFIX + wc.submitScriptLanguage(conf, script, args.toArray(new String[args.size()]), 2155 paramsList.toArray(new String[paramsList.size()]), jobType)); 2156 } 2157 catch (OozieClientException ex) { 2158 throw new OozieCLIException(ex.toString(), ex); 2159 } 2160 } 2161 2162 private void sqoopCommand(CommandLine commandLine) throws IOException, OozieCLIException { 2163 List<String> args = commandLine.getArgList(); 2164 if (args.size() > 0) { 2165 // checking if args starts with -X (because CLIParser cannot check this) 2166 if (!args.get(0).equals("-X")) { 2167 throw new OozieCLIException("Unrecognized option: " + args.get(0) + " Expecting -X"); 2168 } 2169 args.remove(0); 2170 } 2171 2172 if (!commandLine.hasOption(SQOOP_COMMAND_OPTION)) { 2173 throw new OozieCLIException("Need to specify -command"); 2174 } 2175 2176 if (!commandLine.hasOption(CONFIG_OPTION)) { 2177 throw new OozieCLIException("Need to specify -config <configfile>"); 2178 } 2179 2180 try { 2181 XOozieClient wc = createXOozieClient(commandLine); 2182 Properties conf = getConfiguration(wc, commandLine); 2183 String[] command = commandLine.getOptionValues(SQOOP_COMMAND_OPTION); 2184 System.out.println(JOB_ID_PREFIX + wc.submitSqoop(conf, command, args.toArray(new String[args.size()]))); 2185 } 2186 catch (OozieClientException ex) { 2187 throw new OozieCLIException(ex.toString(), ex); 2188 } 2189 } 2190 2191 private void infoCommand(CommandLine commandLine) throws OozieCLIException { 2192 for (Option option : commandLine.getOptions()) { 2193 String opt = option.getOpt(); 2194 if (opt.equals(INFO_TIME_ZONES_OPTION)) { 2195 printAvailableTimeZones(); 2196 } 2197 } 2198 } 2199 2200 private void printAvailableTimeZones() { 2201 System.out.println("The format is \"SHORT_NAME (ID)\"\nGive the ID to the -timezone argument"); 2202 System.out.println("GMT offsets can also be used (e.g. GMT-07:00, GMT-0700, GMT+05:30, GMT+0530)"); 2203 System.out.println("Available Time Zones:"); 2204 for (String tzId : TimeZone.getAvailableIDs()) { 2205 // skip id's that are like "Etc/GMT+01:00" because their display names are like "GMT-01:00", which is confusing 2206 if (!tzId.startsWith("Etc/GMT")) { 2207 TimeZone tZone = TimeZone.getTimeZone(tzId); 2208 System.out.println(" " + tZone.getDisplayName(false, TimeZone.SHORT) + " (" + tzId + ")"); 2209 } 2210 } 2211 } 2212 2213 2214 private void mrCommand(CommandLine commandLine) throws IOException, OozieCLIException { 2215 try { 2216 XOozieClient wc = createXOozieClient(commandLine); 2217 Properties conf = getConfiguration(wc, commandLine); 2218 2219 String mapper = conf.getProperty(MAPRED_MAPPER, conf.getProperty(MAPRED_MAPPER_2)); 2220 if (mapper == null) { 2221 throw new OozieCLIException("mapper (" + MAPRED_MAPPER + " or " + MAPRED_MAPPER_2 + ") must be specified in conf"); 2222 } 2223 2224 String reducer = conf.getProperty(MAPRED_REDUCER, conf.getProperty(MAPRED_REDUCER_2)); 2225 if (reducer == null) { 2226 throw new OozieCLIException("reducer (" + MAPRED_REDUCER + " or " + MAPRED_REDUCER_2 2227 + ") must be specified in conf"); 2228 } 2229 2230 String inputDir = conf.getProperty(MAPRED_INPUT); 2231 if (inputDir == null) { 2232 throw new OozieCLIException("input dir (" + MAPRED_INPUT +") must be specified in conf"); 2233 } 2234 2235 String outputDir = conf.getProperty(MAPRED_OUTPUT); 2236 if (outputDir == null) { 2237 throw new OozieCLIException("output dir (" + MAPRED_OUTPUT +") must be specified in conf"); 2238 } 2239 2240 System.out.println(JOB_ID_PREFIX + wc.submitMapReduce(conf)); 2241 } 2242 catch (OozieClientException ex) { 2243 throw new OozieCLIException(ex.toString(), ex); 2244 } 2245 } 2246 2247 private String getFirstMissingDependencies(CoordinatorAction action) { 2248 StringBuilder allDeps = new StringBuilder(); 2249 String missingDep = action.getMissingDependencies(); 2250 boolean depExists = false; 2251 if (missingDep != null && !missingDep.isEmpty()) { 2252 allDeps.append(missingDep.split(INSTANCE_SEPARATOR)[0]); 2253 depExists = true; 2254 } 2255 String pushDeps = action.getPushMissingDependencies(); 2256 if (pushDeps != null && !pushDeps.isEmpty()) { 2257 if(depExists) { 2258 allDeps.append(INSTANCE_SEPARATOR); 2259 } 2260 allDeps.append(pushDeps.split(INSTANCE_SEPARATOR)[0]); 2261 } 2262 return allDeps.toString(); 2263 } 2264 2265 private void slaAlertCommand(String jobIds, OozieClient wc, CommandLine commandLine, List<String> options) 2266 throws OozieCLIException, OozieClientException { 2267 String actions = null, coordinators = null, dates = null; 2268 2269 if (options.contains(ACTION_OPTION)) { 2270 actions = commandLine.getOptionValue(ACTION_OPTION); 2271 } 2272 2273 if (options.contains(DATE_OPTION)) { 2274 dates = commandLine.getOptionValue(DATE_OPTION); 2275 } 2276 2277 if (options.contains(COORD_OPTION)) { 2278 coordinators = commandLine.getOptionValue(COORD_OPTION); 2279 if (coordinators == null) { 2280 throw new OozieCLIException("No value specified for -coordinator option"); 2281 } 2282 } 2283 2284 if (options.contains(SLA_ENABLE_ALERT)) { 2285 wc.slaEnableAlert(jobIds, actions, dates, coordinators); 2286 } 2287 else if (options.contains(SLA_DISABLE_ALERT)) { 2288 wc.slaDisableAlert(jobIds, actions, dates, coordinators); 2289 } 2290 else if (options.contains(SLA_CHANGE)) { 2291 String newSlaParams = commandLine.getOptionValue(CHANGE_VALUE_OPTION); 2292 wc.slaChange(jobIds, actions, dates, coordinators, newSlaParams); 2293 } 2294 } 2295 2296 private void printMetrics(OozieClient.Metrics metrics) { 2297 System.out.println("COUNTERS"); 2298 System.out.println("--------"); 2299 Map<String, Long> counters = new TreeMap<String, Long>(metrics.getCounters()); 2300 for (Map.Entry<String, Long> ent : counters.entrySet()) { 2301 System.out.println(ent.getKey() + " : " + ent.getValue()); 2302 } 2303 System.out.println("\nGAUGES"); 2304 System.out.println("------"); 2305 Map<String, Object> gauges = new TreeMap<String, Object>(metrics.getGauges()); 2306 for (Map.Entry<String, Object> ent : gauges.entrySet()) { 2307 System.out.println(ent.getKey() + " : " + ent.getValue()); 2308 } 2309 System.out.println("\nTIMERS"); 2310 System.out.println("------"); 2311 Map<String, OozieClient.Metrics.Timer> timers = new TreeMap<String, OozieClient.Metrics.Timer>(metrics.getTimers()); 2312 for (Map.Entry<String, OozieClient.Metrics.Timer> ent : timers.entrySet()) { 2313 System.out.println(ent.getKey()); 2314 System.out.println(ent.getValue()); 2315 } 2316 System.out.println("\nHISTOGRAMS"); 2317 System.out.println("----------"); 2318 Map<String, OozieClient.Metrics.Histogram> histograms = 2319 new TreeMap<String, OozieClient.Metrics.Histogram>(metrics.getHistograms()); 2320 for (Map.Entry<String, OozieClient.Metrics.Histogram> ent : histograms.entrySet()) { 2321 System.out.println(ent.getKey()); 2322 System.out.println(ent.getValue()); 2323 } 2324 } 2325 2326 private void printInstrumentation(OozieClient.Instrumentation instrumentation) { 2327 System.out.println("COUNTERS"); 2328 System.out.println("--------"); 2329 Map<String, Long> counters = new TreeMap<String, Long>(instrumentation.getCounters()); 2330 for (Map.Entry<String, Long> ent : counters.entrySet()) { 2331 System.out.println(ent.getKey() + " : " + ent.getValue()); 2332 } 2333 System.out.println("\nVARIABLES"); 2334 System.out.println("---------"); 2335 Map<String, Object> variables = new TreeMap<String, Object>(instrumentation.getVariables()); 2336 for (Map.Entry<String, Object> ent : variables.entrySet()) { 2337 System.out.println(ent.getKey() + " : " + ent.getValue()); 2338 } 2339 System.out.println("\nSAMPLERS"); 2340 System.out.println("---------"); 2341 Map<String, Double> samplers = new TreeMap<String, Double>(instrumentation.getSamplers()); 2342 for (Map.Entry<String, Double> ent : samplers.entrySet()) { 2343 System.out.println(ent.getKey() + " : " + ent.getValue()); 2344 } 2345 System.out.println("\nTIMERS"); 2346 System.out.println("---------"); 2347 Map<String, OozieClient.Instrumentation.Timer> timers = 2348 new TreeMap<String, OozieClient.Instrumentation.Timer>(instrumentation.getTimers()); 2349 for (Map.Entry<String, OozieClient.Instrumentation.Timer> ent : timers.entrySet()) { 2350 System.out.println(ent.getKey()); 2351 System.out.println(ent.getValue()); 2352 } 2353 } 2354}