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.client;
019
020 import java.io.BufferedReader;
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.io.InputStreamReader;
024 import java.io.OutputStream;
025 import java.io.PrintStream;
026 import java.io.Reader;
027 import java.net.HttpURLConnection;
028 import java.net.URL;
029 import java.net.URLEncoder;
030 import java.util.ArrayList;
031 import java.util.Collections;
032 import java.util.Enumeration;
033 import java.util.HashMap;
034 import java.util.Iterator;
035 import java.util.List;
036 import java.util.Map;
037 import java.util.Properties;
038 import java.util.concurrent.Callable;
039
040 import javax.xml.parsers.DocumentBuilderFactory;
041 import javax.xml.transform.Transformer;
042 import javax.xml.transform.TransformerFactory;
043 import javax.xml.transform.dom.DOMSource;
044 import javax.xml.transform.stream.StreamResult;
045
046 import org.apache.oozie.BuildInfo;
047 import org.apache.oozie.client.rest.JsonTags;
048 import org.apache.oozie.client.rest.JsonToBean;
049 import org.apache.oozie.client.rest.RestConstants;
050 import org.json.simple.JSONArray;
051 import org.json.simple.JSONObject;
052 import org.json.simple.JSONValue;
053 import org.w3c.dom.Document;
054 import org.w3c.dom.Element;
055
056 /**
057 * Client API to submit and manage Oozie workflow jobs against an Oozie intance.
058 * <p/>
059 * This class is thread safe.
060 * <p/>
061 * Syntax for filter for the {@link #getJobsInfo(String)} {@link #getJobsInfo(String, int, int)} methods:
062 * <code>[NAME=VALUE][;NAME=VALUE]*</code>.
063 * <p/>
064 * Valid filter names are:
065 * <p/>
066 * <ul/>
067 * <li>name: the workflow application name from the workflow definition.</li>
068 * <li>user: the user that submitted the job.</li>
069 * <li>group: the group for the job.</li>
070 * <li>status: the status of the job.</li>
071 * </ul>
072 * <p/>
073 * The query will do an AND among all the filter names. The query will do an OR among all the filter values for the same
074 * name. Multiple values must be specified as different name value pairs.
075 */
076 public class OozieClient {
077
078 public static final long WS_PROTOCOL_VERSION_0 = 0;
079
080 public static final long WS_PROTOCOL_VERSION = 1;
081
082 public static final String USER_NAME = "user.name";
083
084 public static final String GROUP_NAME = "group.name";
085
086 public static final String APP_PATH = "oozie.wf.application.path";
087
088 public static final String COORDINATOR_APP_PATH = "oozie.coord.application.path";
089
090 public static final String BUNDLE_APP_PATH = "oozie.bundle.application.path";
091
092 public static final String BUNDLE_ID = "oozie.bundle.id";
093
094 public static final String EXTERNAL_ID = "oozie.wf.external.id";
095
096 public static final String WORKFLOW_NOTIFICATION_URL = "oozie.wf.workflow.notification.url";
097
098 public static final String ACTION_NOTIFICATION_URL = "oozie.wf.action.notification.url";
099
100 public static final String COORD_ACTION_NOTIFICATION_URL = "oozie.coord.action.notification.url";
101
102 public static final String RERUN_SKIP_NODES = "oozie.wf.rerun.skip.nodes";
103
104 public static final String RERUN_FAIL_NODES = "oozie.wf.rerun.failnodes";
105
106 public static final String LOG_TOKEN = "oozie.wf.log.token";
107
108 public static final String ACTION_MAX_RETRIES = "oozie.wf.action.max.retries";
109
110 public static final String ACTION_RETRY_INTERVAL = "oozie.wf.action.retry.interval";
111
112 public static final String FILTER_USER = "user";
113
114 public static final String FILTER_GROUP = "group";
115
116 public static final String FILTER_NAME = "name";
117
118 public static final String FILTER_STATUS = "status";
119
120 public static final String FILTER_FREQUENCY = "frequency";
121
122 public static final String FILTER_ID = "id";
123
124 public static final String CHANGE_VALUE_ENDTIME = "endtime";
125
126 public static final String CHANGE_VALUE_PAUSETIME = "pausetime";
127
128 public static final String CHANGE_VALUE_CONCURRENCY = "concurrency";
129
130 public static final String LIBPATH = "oozie.libpath";
131
132 public static final String USE_SYSTEM_LIBPATH = "oozie.use.system.libpath";
133
134 public static enum SYSTEM_MODE {
135 NORMAL, NOWEBSERVICE, SAFEMODE
136 };
137
138 /**
139 * debugMode =0 means no debugging. > 0 means debugging on.
140 */
141 public int debugMode = 0;
142
143 private String baseUrl;
144 private String protocolUrl;
145 private boolean validatedVersion = false;
146 private final Map<String, String> headers = new HashMap<String, String>();
147
148 protected OozieClient() {
149 }
150
151 /**
152 * Create a Workflow client instance.
153 *
154 * @param oozieUrl URL of the Oozie instance it will interact with.
155 */
156 public OozieClient(String oozieUrl) {
157 this.baseUrl = notEmpty(oozieUrl, "oozieUrl");
158 if (!this.baseUrl.endsWith("/")) {
159 this.baseUrl += "/";
160 }
161 }
162
163 /**
164 * Return the Oozie URL of the workflow client instance.
165 * <p/>
166 * This URL is the base URL fo the Oozie system, with not protocol versioning.
167 *
168 * @return the Oozie URL of the workflow client instance.
169 */
170 public String getOozieUrl() {
171 return baseUrl;
172 }
173
174 /**
175 * Return the Oozie URL used by the client and server for WS communications.
176 * <p/>
177 * This URL is the original URL plus the versioning element path.
178 *
179 * @return the Oozie URL used by the client and server for communication.
180 * @throws OozieClientException thrown in the client and the server are not protocol compatible.
181 */
182 public String getProtocolUrl() throws OozieClientException {
183 validateWSVersion();
184 return protocolUrl;
185 }
186
187 /**
188 * @return current debug Mode
189 */
190 public int getDebugMode() {
191 return debugMode;
192 }
193
194 /**
195 * Set debug mode.
196 *
197 * @param debugMode : 0 means no debugging. > 0 means debugging
198 */
199 public void setDebugMode(int debugMode) {
200 this.debugMode = debugMode;
201 }
202
203 /**
204 * Validate that the Oozie client and server instances are protocol compatible.
205 *
206 * @throws OozieClientException thrown in the client and the server are not protocol compatible.
207 */
208 public synchronized void validateWSVersion() throws OozieClientException {
209 if (!validatedVersion) {
210 try {
211 URL url = new URL(baseUrl + RestConstants.VERSIONS);
212 HttpURLConnection conn = createConnection(url, "GET");
213 if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
214 JSONArray array = (JSONArray) JSONValue.parse(new InputStreamReader(conn.getInputStream()));
215 if (array == null) {
216 throw new OozieClientException("HTTP error", "no response message");
217 }
218 if (!array.contains(WS_PROTOCOL_VERSION) && !array.contains(WS_PROTOCOL_VERSION_0)) {
219 StringBuilder msg = new StringBuilder();
220 msg.append("Supported version [").append(WS_PROTOCOL_VERSION).append(
221 "] or less, Unsupported versions[");
222 String separator = "";
223 for (Object version : array) {
224 msg.append(separator).append(version);
225 }
226 msg.append("]");
227 throw new OozieClientException(OozieClientException.UNSUPPORTED_VERSION, msg.toString());
228 }
229 if (array.contains(WS_PROTOCOL_VERSION)) {
230 protocolUrl = baseUrl + "v" + WS_PROTOCOL_VERSION + "/";
231 }
232 else {
233 if (array.contains(WS_PROTOCOL_VERSION_0)) {
234 protocolUrl = baseUrl + "v" + WS_PROTOCOL_VERSION_0 + "/";
235 }
236 }
237 }
238 else {
239 handleError(conn);
240 }
241 }
242 catch (IOException ex) {
243 throw new OozieClientException(OozieClientException.IO_ERROR, ex);
244 }
245 validatedVersion = true;
246 }
247 }
248
249 /**
250 * Create an empty configuration with just the {@link #USER_NAME} set to the JVM user name.
251 *
252 * @return an empty configuration.
253 */
254 public Properties createConfiguration() {
255 Properties conf = new Properties();
256 conf.setProperty(USER_NAME, System.getProperty("user.name"));
257 return conf;
258 }
259
260 /**
261 * Set a HTTP header to be used in the WS requests by the workflow instance.
262 *
263 * @param name header name.
264 * @param value header value.
265 */
266 public void setHeader(String name, String value) {
267 headers.put(notEmpty(name, "name"), notNull(value, "value"));
268 }
269
270 /**
271 * Get the value of a set HTTP header from the workflow instance.
272 *
273 * @param name header name.
274 * @return header value, <code>null</code> if not set.
275 */
276 public String getHeader(String name) {
277 return headers.get(notEmpty(name, "name"));
278 }
279
280 /**
281 * Get the set HTTP header
282 *
283 * @return map of header key and value
284 */
285 public Map<String, String> getHeaders() {
286 return headers;
287 }
288
289 /**
290 * Remove a HTTP header from the workflow client instance.
291 *
292 * @param name header name.
293 */
294 public void removeHeader(String name) {
295 headers.remove(notEmpty(name, "name"));
296 }
297
298 /**
299 * Return an iterator with all the header names set in the workflow instance.
300 *
301 * @return header names.
302 */
303 public Iterator<String> getHeaderNames() {
304 return Collections.unmodifiableMap(headers).keySet().iterator();
305 }
306
307 private URL createURL(String collection, String resource, Map<String, String> parameters) throws IOException,
308 OozieClientException {
309 validateWSVersion();
310 StringBuilder sb = new StringBuilder();
311 sb.append(protocolUrl).append(collection);
312 if (resource != null && resource.length() > 0) {
313 sb.append("/").append(resource);
314 }
315 if (parameters.size() > 0) {
316 String separator = "?";
317 for (Map.Entry<String, String> param : parameters.entrySet()) {
318 if (param.getValue() != null) {
319 sb.append(separator).append(URLEncoder.encode(param.getKey(), "UTF-8")).append("=").append(
320 URLEncoder.encode(param.getValue(), "UTF-8"));
321 separator = "&";
322 }
323 }
324 }
325 return new URL(sb.toString());
326 }
327
328 private boolean validateCommand(String url) {
329 {
330 if (protocolUrl.contains(baseUrl + "v0")) {
331 if (url.contains("dryrun") || url.contains("jobtype=c") || url.contains("systemmode")) {
332 return false;
333 }
334 }
335 }
336 return true;
337 }
338
339 /**
340 * Create http connection to oozie server.
341 *
342 * @param url
343 * @param method
344 * @return connection
345 * @throws IOException
346 * @throws OozieClientException
347 */
348 protected HttpURLConnection createConnection(URL url, String method) throws IOException, OozieClientException {
349 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
350 conn.setRequestMethod(method);
351 if (method.equals("POST") || method.equals("PUT")) {
352 conn.setDoOutput(true);
353 }
354 for (Map.Entry<String, String> header : headers.entrySet()) {
355 conn.setRequestProperty(header.getKey(), header.getValue());
356 }
357 return conn;
358 }
359
360 protected abstract class ClientCallable<T> implements Callable<T> {
361 private final String method;
362 private final String collection;
363 private final String resource;
364 private final Map<String, String> params;
365
366 public ClientCallable(String method, String collection, String resource, Map<String, String> params) {
367 this.method = method;
368 this.collection = collection;
369 this.resource = resource;
370 this.params = params;
371 }
372
373 public T call() throws OozieClientException {
374 try {
375 URL url = createURL(collection, resource, params);
376 if (validateCommand(url.toString())) {
377 if (getDebugMode() > 0) {
378 System.out.println("Connection URL:[" + url + "]");
379 }
380 HttpURLConnection conn = createConnection(url, method);
381 return call(conn);
382 }
383 else {
384 System.out.println("Option not supported in target server. Supported only on Oozie-2.0 or greater."
385 + " Use 'oozie help' for details");
386 throw new OozieClientException(OozieClientException.UNSUPPORTED_VERSION, new Exception());
387 }
388 }
389 catch (IOException ex) {
390 throw new OozieClientException(OozieClientException.IO_ERROR, ex);
391 }
392
393 }
394
395 protected abstract T call(HttpURLConnection conn) throws IOException, OozieClientException;
396 }
397
398 static void handleError(HttpURLConnection conn) throws IOException, OozieClientException {
399 int status = conn.getResponseCode();
400 String error = conn.getHeaderField(RestConstants.OOZIE_ERROR_CODE);
401 String message = conn.getHeaderField(RestConstants.OOZIE_ERROR_MESSAGE);
402
403 if (error == null) {
404 error = "HTTP error code: " + status;
405 }
406
407 if (message == null) {
408 message = conn.getResponseMessage();
409 }
410 throw new OozieClientException(error, message);
411 }
412
413 static Map<String, String> prepareParams(String... params) {
414 Map<String, String> map = new HashMap<String, String>();
415 for (int i = 0; i < params.length; i = i + 2) {
416 map.put(params[i], params[i + 1]);
417 }
418 return map;
419 }
420
421 public void writeToXml(Properties props, OutputStream out) throws IOException {
422 try {
423 Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
424 Element conf = doc.createElement("configuration");
425 doc.appendChild(conf);
426 conf.appendChild(doc.createTextNode("\n"));
427 for (Enumeration e = props.keys(); e.hasMoreElements();) {
428 String name = (String) e.nextElement();
429 Object object = props.get(name);
430 String value;
431 if (object instanceof String) {
432 value = (String) object;
433 }
434 else {
435 continue;
436 }
437 Element propNode = doc.createElement("property");
438 conf.appendChild(propNode);
439
440 Element nameNode = doc.createElement("name");
441 nameNode.appendChild(doc.createTextNode(name.trim()));
442 propNode.appendChild(nameNode);
443
444 Element valueNode = doc.createElement("value");
445 valueNode.appendChild(doc.createTextNode(value.trim()));
446 propNode.appendChild(valueNode);
447
448 conf.appendChild(doc.createTextNode("\n"));
449 }
450
451 DOMSource source = new DOMSource(doc);
452 StreamResult result = new StreamResult(out);
453 TransformerFactory transFactory = TransformerFactory.newInstance();
454 Transformer transformer = transFactory.newTransformer();
455 transformer.transform(source, result);
456 }
457 catch (Exception e) {
458 throw new IOException(e);
459 }
460 }
461
462 private class JobSubmit extends ClientCallable<String> {
463 private final Properties conf;
464
465 JobSubmit(Properties conf, boolean start) {
466 super("POST", RestConstants.JOBS, "", (start) ? prepareParams(RestConstants.ACTION_PARAM,
467 RestConstants.JOB_ACTION_START) : prepareParams());
468 this.conf = notNull(conf, "conf");
469 }
470
471 JobSubmit(String jobId, Properties conf) {
472 super("PUT", RestConstants.JOB, notEmpty(jobId, "jobId"), prepareParams(RestConstants.ACTION_PARAM,
473 RestConstants.JOB_ACTION_RERUN));
474 this.conf = notNull(conf, "conf");
475 }
476
477 public JobSubmit(Properties conf, String jobActionDryrun) {
478 super("POST", RestConstants.JOBS, "", prepareParams(RestConstants.ACTION_PARAM,
479 RestConstants.JOB_ACTION_DRYRUN));
480 this.conf = notNull(conf, "conf");
481 }
482
483 @Override
484 protected String call(HttpURLConnection conn) throws IOException, OozieClientException {
485 conn.setRequestProperty("content-type", RestConstants.XML_CONTENT_TYPE);
486 writeToXml(conf, conn.getOutputStream());
487 if (conn.getResponseCode() == HttpURLConnection.HTTP_CREATED) {
488 JSONObject json = (JSONObject) JSONValue.parse(new InputStreamReader(conn.getInputStream()));
489 return (String) json.get(JsonTags.JOB_ID);
490 }
491 if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
492 handleError(conn);
493 }
494 return null;
495 }
496 }
497
498 /**
499 * Submit a workflow job.
500 *
501 * @param conf job configuration.
502 * @return the job Id.
503 * @throws OozieClientException thrown if the job could not be submitted.
504 */
505 public String submit(Properties conf) throws OozieClientException {
506 return (new JobSubmit(conf, false)).call();
507 }
508
509 private class JobAction extends ClientCallable<Void> {
510
511 JobAction(String jobId, String action) {
512 super("PUT", RestConstants.JOB, notEmpty(jobId, "jobId"), prepareParams(RestConstants.ACTION_PARAM, action));
513 }
514
515 JobAction(String jobId, String action, String params) {
516 super("PUT", RestConstants.JOB, notEmpty(jobId, "jobId"), prepareParams(RestConstants.ACTION_PARAM, action,
517 RestConstants.JOB_CHANGE_VALUE, params));
518 }
519
520 @Override
521 protected Void call(HttpURLConnection conn) throws IOException, OozieClientException {
522 if (!(conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
523 handleError(conn);
524 }
525 return null;
526 }
527 }
528
529 /**
530 * dryrun for a given job
531 *
532 * @param conf Job configuration.
533 */
534 public String dryrun(Properties conf) throws OozieClientException {
535 return new JobSubmit(conf, RestConstants.JOB_ACTION_DRYRUN).call();
536 }
537
538 /**
539 * Start a workflow job.
540 *
541 * @param jobId job Id.
542 * @throws OozieClientException thrown if the job could not be started.
543 */
544 public void start(String jobId) throws OozieClientException {
545 new JobAction(jobId, RestConstants.JOB_ACTION_START).call();
546 }
547
548 /**
549 * Submit and start a workflow job.
550 *
551 * @param conf job configuration.
552 * @return the job Id.
553 * @throws OozieClientException thrown if the job could not be submitted.
554 */
555 public String run(Properties conf) throws OozieClientException {
556 return (new JobSubmit(conf, true)).call();
557 }
558
559 /**
560 * Rerun a workflow job.
561 *
562 * @param jobId job Id to rerun.
563 * @param conf configuration information for the rerun.
564 * @throws OozieClientException thrown if the job could not be started.
565 */
566 public void reRun(String jobId, Properties conf) throws OozieClientException {
567 new JobSubmit(jobId, conf).call();
568 }
569
570 /**
571 * Suspend a workflow job.
572 *
573 * @param jobId job Id.
574 * @throws OozieClientException thrown if the job could not be suspended.
575 */
576 public void suspend(String jobId) throws OozieClientException {
577 new JobAction(jobId, RestConstants.JOB_ACTION_SUSPEND).call();
578 }
579
580 /**
581 * Resume a workflow job.
582 *
583 * @param jobId job Id.
584 * @throws OozieClientException thrown if the job could not be resume.
585 */
586 public void resume(String jobId) throws OozieClientException {
587 new JobAction(jobId, RestConstants.JOB_ACTION_RESUME).call();
588 }
589
590 /**
591 * Kill a workflow job.
592 *
593 * @param jobId job Id.
594 * @throws OozieClientException thrown if the job could not be killed.
595 */
596 public void kill(String jobId) throws OozieClientException {
597 new JobAction(jobId, RestConstants.JOB_ACTION_KILL).call();
598 }
599
600 /**
601 * Change a coordinator job.
602 *
603 * @param jobId job Id.
604 * @param changeValue change value.
605 * @throws OozieClientException thrown if the job could not be changed.
606 */
607 public void change(String jobId, String changeValue) throws OozieClientException {
608 new JobAction(jobId, RestConstants.JOB_ACTION_CHANGE, changeValue).call();
609 }
610
611 private class JobInfo extends ClientCallable<WorkflowJob> {
612
613 JobInfo(String jobId, int start, int len) {
614 super("GET", RestConstants.JOB, notEmpty(jobId, "jobId"), prepareParams(RestConstants.JOB_SHOW_PARAM,
615 RestConstants.JOB_SHOW_INFO, RestConstants.OFFSET_PARAM, Integer.toString(start),
616 RestConstants.LEN_PARAM, Integer.toString(len)));
617 }
618
619 @Override
620 protected WorkflowJob call(HttpURLConnection conn) throws IOException, OozieClientException {
621 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
622 Reader reader = new InputStreamReader(conn.getInputStream());
623 JSONObject json = (JSONObject) JSONValue.parse(reader);
624 return JsonToBean.createWorkflowJob(json);
625 }
626 else {
627 handleError(conn);
628 }
629 return null;
630 }
631 }
632
633 private class WorkflowActionInfo extends ClientCallable<WorkflowAction> {
634 WorkflowActionInfo(String actionId) {
635 super("GET", RestConstants.JOB, notEmpty(actionId, "id"), prepareParams(RestConstants.JOB_SHOW_PARAM,
636 RestConstants.JOB_SHOW_INFO));
637 }
638
639 @Override
640 protected WorkflowAction call(HttpURLConnection conn) throws IOException, OozieClientException {
641 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
642 Reader reader = new InputStreamReader(conn.getInputStream());
643 JSONObject json = (JSONObject) JSONValue.parse(reader);
644 return JsonToBean.createWorkflowAction(json);
645 }
646 else {
647 handleError(conn);
648 }
649 return null;
650 }
651 }
652
653 /**
654 * Get the info of a workflow job.
655 *
656 * @param jobId job Id.
657 * @return the job info.
658 * @throws OozieClientException thrown if the job info could not be retrieved.
659 */
660 public WorkflowJob getJobInfo(String jobId) throws OozieClientException {
661 return getJobInfo(jobId, 0, 0);
662 }
663
664 /**
665 * Get the info of a workflow job and subset actions.
666 *
667 * @param jobId job Id.
668 * @param start starting index in the list of actions belonging to the job
669 * @param len number of actions to be returned
670 * @return the job info.
671 * @throws OozieClientException thrown if the job info could not be retrieved.
672 */
673 public WorkflowJob getJobInfo(String jobId, int start, int len) throws OozieClientException {
674 return new JobInfo(jobId, start, len).call();
675 }
676
677 /**
678 * Get the info of a workflow action.
679 *
680 * @param actionId Id.
681 * @return the workflow action info.
682 * @throws OozieClientException thrown if the job info could not be retrieved.
683 */
684 public WorkflowAction getWorkflowActionInfo(String actionId) throws OozieClientException {
685 return new WorkflowActionInfo(actionId).call();
686 }
687
688 /**
689 * Get the log of a workflow job.
690 *
691 * @param jobId job Id.
692 * @return the job log.
693 * @throws OozieClientException thrown if the job info could not be retrieved.
694 */
695 public String getJobLog(String jobId) throws OozieClientException {
696 return new JobLog(jobId).call();
697 }
698
699 /**
700 * Get the log of a job.
701 *
702 * @param jobId job Id.
703 * @param logRetrievalType Based on which filter criteria the log is retrieved
704 * @param logRetrievalScope Value for the retrieval type
705 * @param ps Printstream of command line interface
706 * @throws OozieClientException thrown if the job info could not be retrieved.
707 */
708 public void getJobLog(String jobId, String logRetrievalType, String logRetrievalScope, PrintStream ps)
709 throws OozieClientException {
710 new JobLog(jobId, logRetrievalType, logRetrievalScope, ps).call();
711 }
712
713 private class JobLog extends JobMetadata {
714 JobLog(String jobId) {
715 super(jobId, RestConstants.JOB_SHOW_LOG);
716 }
717
718 JobLog(String jobId, String logRetrievalType, String logRetrievalScope, PrintStream ps) {
719 super(jobId, logRetrievalType, logRetrievalScope, RestConstants.JOB_SHOW_LOG, ps);
720 }
721 }
722
723 /**
724 * Get the definition of a workflow job.
725 *
726 * @param jobId job Id.
727 * @return the job log.
728 * @throws OozieClientException thrown if the job info could not be retrieved.
729 */
730 public String getJobDefinition(String jobId) throws OozieClientException {
731 return new JobDefinition(jobId).call();
732 }
733
734 private class JobDefinition extends JobMetadata {
735
736 JobDefinition(String jobId) {
737 super(jobId, RestConstants.JOB_SHOW_DEFINITION);
738 }
739 }
740
741 private class JobMetadata extends ClientCallable<String> {
742 PrintStream printStream;
743
744 JobMetadata(String jobId, String metaType) {
745 super("GET", RestConstants.JOB, notEmpty(jobId, "jobId"), prepareParams(RestConstants.JOB_SHOW_PARAM,
746 metaType));
747 }
748
749 JobMetadata(String jobId, String logRetrievalType, String logRetrievalScope, String metaType, PrintStream ps) {
750 super("GET", RestConstants.JOB, notEmpty(jobId, "jobId"), prepareParams(RestConstants.JOB_SHOW_PARAM,
751 metaType, RestConstants.JOB_LOG_TYPE_PARAM, logRetrievalType, RestConstants.JOB_LOG_SCOPE_PARAM,
752 logRetrievalScope));
753 printStream = ps;
754 }
755
756 @Override
757 protected String call(HttpURLConnection conn) throws IOException, OozieClientException {
758 String returnVal = null;
759 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
760 InputStream is = conn.getInputStream();
761 InputStreamReader isr = new InputStreamReader(is);
762 try {
763 if (printStream != null) {
764 sendToOutputStream(isr, -1);
765 }
766 else {
767 returnVal = getReaderAsString(isr, -1);
768 }
769 }
770 finally {
771 isr.close();
772 }
773 }
774 else {
775 handleError(conn);
776 }
777 return returnVal;
778 }
779
780 /**
781 * Output the log to command line interface
782 *
783 * @param reader reader to read into a string.
784 * @param maxLen max content length allowed, if -1 there is no limit.
785 * @param ps Printstream of command line interface
786 * @throws IOException
787 */
788 private void sendToOutputStream(Reader reader, int maxLen) throws IOException {
789 if (reader == null) {
790 throw new IllegalArgumentException("reader cannot be null");
791 }
792 StringBuilder sb = new StringBuilder();
793 char[] buffer = new char[2048];
794 int read;
795 int count = 0;
796 int noOfCharstoFlush = 1024;
797 while ((read = reader.read(buffer)) > -1) {
798 count += read;
799 if ((maxLen > -1) && (count > maxLen)) {
800 break;
801 }
802 sb.append(buffer, 0, read);
803 if (sb.length() > noOfCharstoFlush) {
804 printStream.print(sb.toString());
805 sb = new StringBuilder("");
806 }
807 }
808 printStream.print(sb.toString());
809 }
810
811 /**
812 * Return a reader as string.
813 * <p/>
814 *
815 * @param reader reader to read into a string.
816 * @param maxLen max content length allowed, if -1 there is no limit.
817 * @return the reader content.
818 * @throws IOException thrown if the resource could not be read.
819 */
820 private String getReaderAsString(Reader reader, int maxLen) throws IOException {
821 if (reader == null) {
822 throw new IllegalArgumentException("reader cannot be null");
823 }
824 StringBuffer sb = new StringBuffer();
825 char[] buffer = new char[2048];
826 int read;
827 int count = 0;
828 while ((read = reader.read(buffer)) > -1) {
829 count += read;
830
831 // read up to maxLen chars;
832 if ((maxLen > -1) && (count > maxLen)) {
833 break;
834 }
835 sb.append(buffer, 0, read);
836 }
837 reader.close();
838 return sb.toString();
839 }
840 }
841
842 private class CoordJobInfo extends ClientCallable<CoordinatorJob> {
843
844 CoordJobInfo(String jobId, int start, int len) {
845 super("GET", RestConstants.JOB, notEmpty(jobId, "jobId"), prepareParams(RestConstants.JOB_SHOW_PARAM,
846 RestConstants.JOB_SHOW_INFO, RestConstants.OFFSET_PARAM, Integer.toString(start),
847 RestConstants.LEN_PARAM, Integer.toString(len)));
848 }
849
850 @Override
851 protected CoordinatorJob call(HttpURLConnection conn) throws IOException, OozieClientException {
852 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
853 Reader reader = new InputStreamReader(conn.getInputStream());
854 JSONObject json = (JSONObject) JSONValue.parse(reader);
855 return JsonToBean.createCoordinatorJob(json);
856 }
857 else {
858 handleError(conn);
859 }
860 return null;
861 }
862 }
863
864 private class BundleJobInfo extends ClientCallable<BundleJob> {
865
866 BundleJobInfo(String jobId) {
867 super("GET", RestConstants.JOB, notEmpty(jobId, "jobId"), prepareParams(RestConstants.JOB_SHOW_PARAM,
868 RestConstants.JOB_SHOW_INFO));
869 }
870
871 @Override
872 protected BundleJob call(HttpURLConnection conn) throws IOException, OozieClientException {
873 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
874 Reader reader = new InputStreamReader(conn.getInputStream());
875 JSONObject json = (JSONObject) JSONValue.parse(reader);
876 return JsonToBean.createBundleJob(json);
877 }
878 else {
879 handleError(conn);
880 }
881 return null;
882 }
883 }
884
885 private class CoordActionInfo extends ClientCallable<CoordinatorAction> {
886 CoordActionInfo(String actionId) {
887 super("GET", RestConstants.JOB, notEmpty(actionId, "id"), prepareParams(RestConstants.JOB_SHOW_PARAM,
888 RestConstants.JOB_SHOW_INFO));
889 }
890
891 @Override
892 protected CoordinatorAction call(HttpURLConnection conn) throws IOException, OozieClientException {
893 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
894 Reader reader = new InputStreamReader(conn.getInputStream());
895 JSONObject json = (JSONObject) JSONValue.parse(reader);
896 return JsonToBean.createCoordinatorAction(json);
897 }
898 else {
899 handleError(conn);
900 }
901 return null;
902 }
903 }
904
905 /**
906 * Get the info of a bundle job.
907 *
908 * @param jobId job Id.
909 * @return the job info.
910 * @throws OozieClientException thrown if the job info could not be retrieved.
911 */
912 public BundleJob getBundleJobInfo(String jobId) throws OozieClientException {
913 return new BundleJobInfo(jobId).call();
914 }
915
916 /**
917 * Get the info of a coordinator job.
918 *
919 * @param jobId job Id.
920 * @return the job info.
921 * @throws OozieClientException thrown if the job info could not be retrieved.
922 */
923 public CoordinatorJob getCoordJobInfo(String jobId) throws OozieClientException {
924 return new CoordJobInfo(jobId, 0, 0).call();
925 }
926
927 /**
928 * Get the info of a coordinator job and subset actions.
929 *
930 * @param jobId job Id.
931 * @param start starting index in the list of actions belonging to the job
932 * @param len number of actions to be returned
933 * @return the job info.
934 * @throws OozieClientException thrown if the job info could not be retrieved.
935 */
936 public CoordinatorJob getCoordJobInfo(String jobId, int start, int len) throws OozieClientException {
937 return new CoordJobInfo(jobId, start, len).call();
938 }
939
940 /**
941 * Get the info of a coordinator action.
942 *
943 * @param actionId Id.
944 * @return the coordinator action info.
945 * @throws OozieClientException thrown if the job info could not be retrieved.
946 */
947 public CoordinatorAction getCoordActionInfo(String actionId) throws OozieClientException {
948 return new CoordActionInfo(actionId).call();
949 }
950
951 private class JobsStatus extends ClientCallable<List<WorkflowJob>> {
952
953 JobsStatus(String filter, int start, int len) {
954 super("GET", RestConstants.JOBS, "", prepareParams(RestConstants.JOBS_FILTER_PARAM, filter,
955 RestConstants.JOBTYPE_PARAM, "wf", RestConstants.OFFSET_PARAM, Integer.toString(start),
956 RestConstants.LEN_PARAM, Integer.toString(len)));
957 }
958
959 @Override
960 @SuppressWarnings("unchecked")
961 protected List<WorkflowJob> call(HttpURLConnection conn) throws IOException, OozieClientException {
962 conn.setRequestProperty("content-type", RestConstants.XML_CONTENT_TYPE);
963 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
964 Reader reader = new InputStreamReader(conn.getInputStream());
965 JSONObject json = (JSONObject) JSONValue.parse(reader);
966 JSONArray workflows = (JSONArray) json.get(JsonTags.WORKFLOWS_JOBS);
967 if (workflows == null) {
968 workflows = new JSONArray();
969 }
970 return JsonToBean.createWorkflowJobList(workflows);
971 }
972 else {
973 handleError(conn);
974 }
975 return null;
976 }
977 }
978
979 private class CoordJobsStatus extends ClientCallable<List<CoordinatorJob>> {
980
981 CoordJobsStatus(String filter, int start, int len) {
982 super("GET", RestConstants.JOBS, "", prepareParams(RestConstants.JOBS_FILTER_PARAM, filter,
983 RestConstants.JOBTYPE_PARAM, "coord", RestConstants.OFFSET_PARAM, Integer.toString(start),
984 RestConstants.LEN_PARAM, Integer.toString(len)));
985 }
986
987 @Override
988 protected List<CoordinatorJob> call(HttpURLConnection conn) throws IOException, OozieClientException {
989 conn.setRequestProperty("content-type", RestConstants.XML_CONTENT_TYPE);
990 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
991 Reader reader = new InputStreamReader(conn.getInputStream());
992 JSONObject json = (JSONObject) JSONValue.parse(reader);
993 JSONArray jobs = (JSONArray) json.get(JsonTags.COORDINATOR_JOBS);
994 if (jobs == null) {
995 jobs = new JSONArray();
996 }
997 return JsonToBean.createCoordinatorJobList(jobs);
998 }
999 else {
1000 handleError(conn);
1001 }
1002 return null;
1003 }
1004 }
1005
1006 private class BundleJobsStatus extends ClientCallable<List<BundleJob>> {
1007
1008 BundleJobsStatus(String filter, int start, int len) {
1009 super("GET", RestConstants.JOBS, "", prepareParams(RestConstants.JOBS_FILTER_PARAM, filter,
1010 RestConstants.JOBTYPE_PARAM, "bundle", RestConstants.OFFSET_PARAM, Integer.toString(start),
1011 RestConstants.LEN_PARAM, Integer.toString(len)));
1012 }
1013
1014 @Override
1015 protected List<BundleJob> call(HttpURLConnection conn) throws IOException, OozieClientException {
1016 conn.setRequestProperty("content-type", RestConstants.XML_CONTENT_TYPE);
1017 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
1018 Reader reader = new InputStreamReader(conn.getInputStream());
1019 JSONObject json = (JSONObject) JSONValue.parse(reader);
1020 JSONArray jobs = (JSONArray) json.get(JsonTags.BUNDLE_JOBS);
1021 if (jobs == null) {
1022 jobs = new JSONArray();
1023 }
1024 return JsonToBean.createBundleJobList(jobs);
1025 }
1026 else {
1027 handleError(conn);
1028 }
1029 return null;
1030 }
1031 }
1032
1033 private class CoordRerun extends ClientCallable<List<CoordinatorAction>> {
1034
1035 CoordRerun(String jobId, String rerunType, String scope, boolean refresh, boolean noCleanup) {
1036 super("PUT", RestConstants.JOB, notEmpty(jobId, "jobId"), prepareParams(RestConstants.ACTION_PARAM,
1037 RestConstants.JOB_COORD_ACTION_RERUN, RestConstants.JOB_COORD_RERUN_TYPE_PARAM, rerunType,
1038 RestConstants.JOB_COORD_RERUN_SCOPE_PARAM, scope, RestConstants.JOB_COORD_RERUN_REFRESH_PARAM,
1039 Boolean.toString(refresh), RestConstants.JOB_COORD_RERUN_NOCLEANUP_PARAM, Boolean
1040 .toString(noCleanup)));
1041 }
1042
1043 @Override
1044 protected List<CoordinatorAction> call(HttpURLConnection conn) throws IOException, OozieClientException {
1045 conn.setRequestProperty("content-type", RestConstants.XML_CONTENT_TYPE);
1046 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
1047 Reader reader = new InputStreamReader(conn.getInputStream());
1048 JSONObject json = (JSONObject) JSONValue.parse(reader);
1049 JSONArray coordActions = (JSONArray) json.get(JsonTags.COORDINATOR_ACTIONS);
1050 return JsonToBean.createCoordinatorActionList(coordActions);
1051 }
1052 else {
1053 handleError(conn);
1054 }
1055 return null;
1056 }
1057 }
1058
1059 private class BundleRerun extends ClientCallable<Void> {
1060
1061 BundleRerun(String jobId, String coordScope, String dateScope, boolean refresh, boolean noCleanup) {
1062 super("PUT", RestConstants.JOB, notEmpty(jobId, "jobId"), prepareParams(RestConstants.ACTION_PARAM,
1063 RestConstants.JOB_BUNDLE_ACTION_RERUN, RestConstants.JOB_BUNDLE_RERUN_COORD_SCOPE_PARAM,
1064 coordScope, RestConstants.JOB_BUNDLE_RERUN_DATE_SCOPE_PARAM, dateScope,
1065 RestConstants.JOB_COORD_RERUN_REFRESH_PARAM, Boolean.toString(refresh),
1066 RestConstants.JOB_COORD_RERUN_NOCLEANUP_PARAM, Boolean.toString(noCleanup)));
1067 }
1068
1069 @Override
1070 protected Void call(HttpURLConnection conn) throws IOException, OozieClientException {
1071 conn.setRequestProperty("content-type", RestConstants.XML_CONTENT_TYPE);
1072 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
1073 return null;
1074 }
1075 else {
1076 handleError(conn);
1077 }
1078 return null;
1079 }
1080 }
1081
1082 /**
1083 * Rerun coordinator actions.
1084 *
1085 * @param jobId coordinator jobId
1086 * @param rerunType rerun type 'date' if -date is used, 'action-id' if -action is used
1087 * @param scope rerun scope for date or actionIds
1088 * @param refresh true if -refresh is given in command option
1089 * @param noCleanup true if -nocleanup is given in command option
1090 * @throws OozieClientException
1091 */
1092 public List<CoordinatorAction> reRunCoord(String jobId, String rerunType, String scope, boolean refresh,
1093 boolean noCleanup) throws OozieClientException {
1094 return new CoordRerun(jobId, rerunType, scope, refresh, noCleanup).call();
1095 }
1096
1097 /**
1098 * Rerun bundle coordinators.
1099 *
1100 * @param jobId bundle jobId
1101 * @param coordScope rerun scope for coordinator jobs
1102 * @param dateScope rerun scope for date
1103 * @param refresh true if -refresh is given in command option
1104 * @param noCleanup true if -nocleanup is given in command option
1105 * @throws OozieClientException
1106 */
1107 public Void reRunBundle(String jobId, String coordScope, String dateScope, boolean refresh, boolean noCleanup)
1108 throws OozieClientException {
1109 return new BundleRerun(jobId, coordScope, dateScope, refresh, noCleanup).call();
1110 }
1111
1112 /**
1113 * Return the info of the workflow jobs that match the filter.
1114 *
1115 * @param filter job filter. Refer to the {@link OozieClient} for the filter syntax.
1116 * @param start jobs offset, base 1.
1117 * @param len number of jobs to return.
1118 * @return a list with the workflow jobs info, without node details.
1119 * @throws OozieClientException thrown if the jobs info could not be retrieved.
1120 */
1121 public List<WorkflowJob> getJobsInfo(String filter, int start, int len) throws OozieClientException {
1122 return new JobsStatus(filter, start, len).call();
1123 }
1124
1125 /**
1126 * Return the info of the workflow jobs that match the filter.
1127 * <p/>
1128 * It returns the first 100 jobs that match the filter.
1129 *
1130 * @param filter job filter. Refer to the {@link OozieClient} for the filter syntax.
1131 * @return a list with the workflow jobs info, without node details.
1132 * @throws OozieClientException thrown if the jobs info could not be retrieved.
1133 */
1134 public List<WorkflowJob> getJobsInfo(String filter) throws OozieClientException {
1135 return getJobsInfo(filter, 1, 50);
1136 }
1137
1138 /**
1139 * Print sla info about coordinator and workflow jobs and actions.
1140 *
1141 * @param start starting offset
1142 * @param len number of results
1143 * @return
1144 * @throws OozieClientException
1145 */
1146 public void getSlaInfo(int start, int len) throws OozieClientException {
1147 new SlaInfo(start, len).call();
1148 }
1149
1150 private class SlaInfo extends ClientCallable<Void> {
1151
1152 SlaInfo(int start, int len) {
1153 super("GET", RestConstants.SLA, "", prepareParams(RestConstants.SLA_GT_SEQUENCE_ID,
1154 Integer.toString(start), RestConstants.MAX_EVENTS, Integer.toString(len)));
1155 }
1156
1157 @Override
1158 @SuppressWarnings("unchecked")
1159 protected Void call(HttpURLConnection conn) throws IOException, OozieClientException {
1160 conn.setRequestProperty("content-type", RestConstants.XML_CONTENT_TYPE);
1161 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
1162 BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
1163 String line = null;
1164 while ((line = br.readLine()) != null) {
1165 System.out.println(line);
1166 }
1167 }
1168 else {
1169 handleError(conn);
1170 }
1171 return null;
1172 }
1173 }
1174
1175 private class JobIdAction extends ClientCallable<String> {
1176
1177 JobIdAction(String externalId) {
1178 super("GET", RestConstants.JOBS, "", prepareParams(RestConstants.JOBTYPE_PARAM, "wf",
1179 RestConstants.JOBS_EXTERNAL_ID_PARAM, externalId));
1180 }
1181
1182 @Override
1183 @SuppressWarnings("unchecked")
1184 protected String call(HttpURLConnection conn) throws IOException, OozieClientException {
1185 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
1186 Reader reader = new InputStreamReader(conn.getInputStream());
1187 JSONObject json = (JSONObject) JSONValue.parse(reader);
1188 return (String) json.get(JsonTags.JOB_ID);
1189 }
1190 else {
1191 handleError(conn);
1192 }
1193 return null;
1194 }
1195 }
1196
1197 /**
1198 * Return the workflow job Id for an external Id.
1199 * <p/>
1200 * The external Id must have provided at job creation time.
1201 *
1202 * @param externalId external Id given at job creation time.
1203 * @return the workflow job Id for an external Id, <code>null</code> if none.
1204 * @throws OozieClientException thrown if the operation could not be done.
1205 */
1206 public String getJobId(String externalId) throws OozieClientException {
1207 return new JobIdAction(externalId).call();
1208 }
1209
1210 private class SetSystemMode extends ClientCallable<Void> {
1211
1212 public SetSystemMode(SYSTEM_MODE status) {
1213 super("PUT", RestConstants.ADMIN, RestConstants.ADMIN_STATUS_RESOURCE, prepareParams(
1214 RestConstants.ADMIN_SYSTEM_MODE_PARAM, status + ""));
1215 }
1216
1217 @Override
1218 public Void call(HttpURLConnection conn) throws IOException, OozieClientException {
1219 if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
1220 handleError(conn);
1221 }
1222 return null;
1223 }
1224 }
1225
1226 /**
1227 * Enable or disable safe mode. Used by OozieCLI. In safe mode, Oozie would not accept any commands except status
1228 * command to change and view the safe mode status.
1229 *
1230 * @param status true to enable safe mode, false to disable safe mode.
1231 * @throws OozieClientException if it fails to set the safe mode status.
1232 */
1233 public void setSystemMode(SYSTEM_MODE status) throws OozieClientException {
1234 new SetSystemMode(status).call();
1235 }
1236
1237 private class GetSystemMode extends ClientCallable<SYSTEM_MODE> {
1238
1239 GetSystemMode() {
1240 super("GET", RestConstants.ADMIN, RestConstants.ADMIN_STATUS_RESOURCE, prepareParams());
1241 }
1242
1243 @Override
1244 protected SYSTEM_MODE call(HttpURLConnection conn) throws IOException, OozieClientException {
1245 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
1246 Reader reader = new InputStreamReader(conn.getInputStream());
1247 JSONObject json = (JSONObject) JSONValue.parse(reader);
1248 return SYSTEM_MODE.valueOf((String) json.get(JsonTags.OOZIE_SYSTEM_MODE));
1249 }
1250 else {
1251 handleError(conn);
1252 }
1253 return SYSTEM_MODE.NORMAL;
1254 }
1255 }
1256
1257 /**
1258 * Returns if Oozie is in safe mode or not.
1259 *
1260 * @return true if safe mode is ON<br>
1261 * false if safe mode is OFF
1262 * @throws OozieClientException throw if it could not obtain the safe mode status.
1263 */
1264 /*
1265 * public boolean isInSafeMode() throws OozieClientException { return new GetSafeMode().call(); }
1266 */
1267 public SYSTEM_MODE getSystemMode() throws OozieClientException {
1268 return new GetSystemMode().call();
1269 }
1270
1271 private class GetBuildVersion extends ClientCallable<String> {
1272
1273 GetBuildVersion() {
1274 super("GET", RestConstants.ADMIN, RestConstants.ADMIN_BUILD_VERSION_RESOURCE, prepareParams());
1275 }
1276
1277 @Override
1278 protected String call(HttpURLConnection conn) throws IOException, OozieClientException {
1279 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
1280 Reader reader = new InputStreamReader(conn.getInputStream());
1281 JSONObject json = (JSONObject) JSONValue.parse(reader);
1282 return (String) json.get(JsonTags.BUILD_VERSION);
1283 }
1284 else {
1285 handleError(conn);
1286 }
1287 return null;
1288 }
1289 }
1290
1291 /**
1292 * Return the Oozie server build version.
1293 *
1294 * @return the Oozie server build version.
1295 * @throws OozieClientException throw if it the server build version could not be retrieved.
1296 */
1297 public String getServerBuildVersion() throws OozieClientException {
1298 return new GetBuildVersion().call();
1299 }
1300
1301 /**
1302 * Return the Oozie client build version.
1303 *
1304 * @return the Oozie client build version.
1305 */
1306 public String getClientBuildVersion() {
1307 return BuildInfo.getBuildInfo().getProperty(BuildInfo.BUILD_VERSION);
1308 }
1309
1310 /**
1311 * Return the info of the coordinator jobs that match the filter.
1312 *
1313 * @param filter job filter. Refer to the {@link OozieClient} for the filter syntax.
1314 * @param start jobs offset, base 1.
1315 * @param len number of jobs to return.
1316 * @return a list with the coordinator jobs info
1317 * @throws OozieClientException thrown if the jobs info could not be retrieved.
1318 */
1319 public List<CoordinatorJob> getCoordJobsInfo(String filter, int start, int len) throws OozieClientException {
1320 return new CoordJobsStatus(filter, start, len).call();
1321 }
1322
1323 /**
1324 * Return the info of the bundle jobs that match the filter.
1325 *
1326 * @param filter job filter. Refer to the {@link OozieClient} for the filter syntax.
1327 * @param start jobs offset, base 1.
1328 * @param len number of jobs to return.
1329 * @return a list with the bundle jobs info
1330 * @throws OozieClientException thrown if the jobs info could not be retrieved.
1331 */
1332 public List<BundleJob> getBundleJobsInfo(String filter, int start, int len) throws OozieClientException {
1333 return new BundleJobsStatus(filter, start, len).call();
1334 }
1335
1336 private class GetQueueDump extends ClientCallable<List<String>> {
1337 GetQueueDump() {
1338 super("GET", RestConstants.ADMIN, RestConstants.ADMIN_QUEUE_DUMP_RESOURCE, prepareParams());
1339 }
1340
1341 @Override
1342 protected List<String> call(HttpURLConnection conn) throws IOException, OozieClientException {
1343 if ((conn.getResponseCode() == HttpURLConnection.HTTP_OK)) {
1344 Reader reader = new InputStreamReader(conn.getInputStream());
1345 JSONObject json = (JSONObject) JSONValue.parse(reader);
1346 JSONArray queueDumpArray = (JSONArray) json.get(JsonTags.QUEUE_DUMP);
1347
1348 List<String> list = new ArrayList<String>();
1349 list.add("[Server Queue Dump]:");
1350 for (Object o : queueDumpArray) {
1351 JSONObject entry = (JSONObject) o;
1352 if (entry.get(JsonTags.CALLABLE_DUMP) != null) {
1353 String value = (String) entry.get(JsonTags.CALLABLE_DUMP);
1354 list.add(value);
1355 }
1356 }
1357 if (queueDumpArray.size() == 0) {
1358 list.add("Queue dump is null!");
1359 }
1360
1361 list.add("******************************************");
1362 list.add("[Server Uniqueness Map Dump]:");
1363
1364 JSONArray uniqueDumpArray = (JSONArray) json.get(JsonTags.UNIQUE_MAP_DUMP);
1365 for (Object o : uniqueDumpArray) {
1366 JSONObject entry = (JSONObject) o;
1367 if (entry.get(JsonTags.UNIQUE_ENTRY_DUMP) != null) {
1368 String value = (String) entry.get(JsonTags.UNIQUE_ENTRY_DUMP);
1369 list.add(value);
1370 }
1371 }
1372 if (uniqueDumpArray.size() == 0) {
1373 list.add("Uniqueness dump is null!");
1374 }
1375 return list;
1376 }
1377 else {
1378 handleError(conn);
1379 }
1380 return null;
1381 }
1382 }
1383
1384 /**
1385 * Return the Oozie queue's commands' dump
1386 *
1387 * @return the list of strings of callable identification in queue
1388 * @throws OozieClientException throw if it the queue dump could not be retrieved.
1389 */
1390 public List<String> getQueueDump() throws OozieClientException {
1391 return new GetQueueDump().call();
1392 }
1393
1394 /**
1395 * Check if the string is not null or not empty.
1396 *
1397 * @param str
1398 * @param name
1399 * @return string
1400 */
1401 public static String notEmpty(String str, String name) {
1402 if (str == null) {
1403 throw new IllegalArgumentException(name + " cannot be null");
1404 }
1405 if (str.length() == 0) {
1406 throw new IllegalArgumentException(name + " cannot be empty");
1407 }
1408 return str;
1409 }
1410
1411 /**
1412 * Check if the object is not null.
1413 *
1414 * @param <T>
1415 * @param obj
1416 * @param name
1417 * @return string
1418 */
1419 public static <T> T notNull(T obj, String name) {
1420 if (obj == null) {
1421 throw new IllegalArgumentException(name + " cannot be null");
1422 }
1423 return obj;
1424 }
1425
1426 }