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