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