001    /**
002     * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *   http://www.apache.org/licenses/LICENSE-2.0
008     *
009     *  Unless required by applicable law or agreed to in writing, software
010     *  distributed under the License is distributed on an "AS IS" BASIS,
011     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     *  See the License for the specific language governing permissions and
013     *  limitations under the License. See accompanying LICENSE file.
014     */
015    package org.apache.oozie;
016    
017    import java.util.ArrayList;
018    import java.util.Collections;
019    import java.util.Iterator;
020    import java.util.List;
021    import java.util.Properties;
022    
023    import org.apache.oozie.client.CoordinatorAction;
024    import org.apache.oozie.client.CoordinatorJob;
025    import org.apache.oozie.client.OozieClient;
026    import org.apache.oozie.client.OozieClientException;
027    import org.apache.oozie.client.WorkflowJob;
028    import org.apache.oozie.client.rest.JsonCoordinatorAction;
029    import org.apache.oozie.client.rest.JsonCoordinatorJob;
030    import org.apache.oozie.util.XConfiguration;
031    
032    /**
033     * Client API to submit and manage Oozie coordinator jobs against an Oozie
034     * intance.
035     * <p/>
036     * This class is thread safe.
037     * <p/>
038     * Syntax for filter for the {@link #getJobsInfo(String)}
039     * {@link #getJobsInfo(String, int, int)} methods:
040     * <code>[NAME=VALUE][;NAME=VALUE]*</code>.
041     * <p/>
042     * Valid filter names are:
043     * <p/>
044     * <ul/>
045     * <li>name: the coordinator application name from the coordinator definition.</li>
046     * <li>user: the user that submitted the job.</li>
047     * <li>group: the group for the job.</li>
048     * <li>status: the status of the job.</li>
049     * </ul>
050     * <p/>
051     * The query will do an AND among all the filter names. The query will do an OR
052     * among all the filter values for the same name. Multiple values must be
053     * specified as different name value pairs.
054     */
055    public class LocalOozieClientCoord extends OozieClient {
056    
057        private final CoordinatorEngine coordEngine;
058    
059        /**
060         * Create a coordinator client for Oozie local use.
061         * <p/>
062         *
063         * @param coordEngine the engine instance to use.
064         */
065        public LocalOozieClientCoord(CoordinatorEngine coordEngine) {
066            this.coordEngine = coordEngine;
067        }
068    
069        /**
070         * Return the Oozie URL of the coordinator client instance.
071         * <p/>
072         * This URL is the base URL fo the Oozie system, with not protocol
073         * versioning.
074         *
075         * @return the Oozie URL of the coordinator client instance.
076         */
077        @Override
078        public String getOozieUrl() {
079            return "localoozie";
080        }
081    
082        /**
083         * Return the Oozie URL used by the client and server for WS communications.
084         * <p/>
085         * This URL is the original URL plus the versioning element path.
086         *
087         * @return the Oozie URL used by the client and server for communication.
088         * @throws org.apache.oozie.client.OozieClientException thrown in the client
089         *         and the server are not protocol compatible.
090         */
091        @Override
092        public String getProtocolUrl() throws OozieClientException {
093            return "localoozie";
094        }
095    
096        /**
097         * Validate that the Oozie client and server instances are protocol
098         * compatible.
099         *
100         * @throws org.apache.oozie.client.OozieClientException thrown in the client
101         *         and the server are not protocol compatible.
102         */
103        @Override
104        public synchronized void validateWSVersion() throws OozieClientException {
105        }
106    
107        /**
108         * Create an empty configuration with just the {@link #USER_NAME} set to the
109         * JVM user name and the {@link #GROUP_NAME} set to 'other'.
110         *
111         * @return an empty configuration.
112         */
113        @Override
114        public Properties createConfiguration() {
115            Properties conf = new Properties();
116            if (coordEngine != null) {
117                conf.setProperty(USER_NAME, coordEngine.getUser());
118            }
119            conf.setProperty(GROUP_NAME, "users");
120            return conf;
121        }
122    
123        /**
124         * Set a HTTP header to be used in the WS requests by the coordinator
125         * instance.
126         *
127         * @param name header name.
128         * @param value header value.
129         */
130        @Override
131        public void setHeader(String name, String value) {
132        }
133    
134        /**
135         * Get the value of a set HTTP header from the coordinator instance.
136         *
137         * @param name header name.
138         * @return header value, <code>null</code> if not set.
139         */
140        @Override
141        public String getHeader(String name) {
142            return null;
143        }
144    
145        /**
146         * Remove a HTTP header from the coordinator client instance.
147         *
148         * @param name header name.
149         */
150        @Override
151        public void removeHeader(String name) {
152        }
153    
154        /**
155         * Return an iterator with all the header names set in the coordinator
156         * instance.
157         *
158         * @return header names.
159         */
160        @Override
161        @SuppressWarnings("unchecked")
162        public Iterator<String> getHeaderNames() {
163            return Collections.EMPTY_SET.iterator();
164        }
165    
166        /**
167         * Submit a coordinator job.
168         *
169         * @param conf job configuration.
170         * @return the job Id.
171         * @throws org.apache.oozie.client.OozieClientException thrown if the job
172         *         could not be submitted.
173         */
174        @Override
175        public String submit(Properties conf) throws OozieClientException {
176            try {
177                return coordEngine.submitJob(new XConfiguration(conf), false);
178            }
179            catch (CoordinatorEngineException ex) {
180                throw new OozieClientException(ex.getErrorCode().toString(), ex);
181            }
182        }
183    
184        /**
185         * Start a coordinator job.
186         *
187         * @param jobId job Id.
188         * @throws org.apache.oozie.client.OozieClientException thrown if the job
189         *         could not be started.
190         */
191        @Override
192        @Deprecated
193        public void start(String jobId) throws OozieClientException {
194            try {
195                coordEngine.start(jobId);
196            }
197            catch (CoordinatorEngineException ex) {
198                throw new OozieClientException(ex.getErrorCode().toString(), ex);
199            }
200            catch (BaseEngineException bex) {
201                throw new OozieClientException(bex.getErrorCode().toString(), bex);
202            }
203        }
204    
205        /**
206         * Submit and start a coordinator job.
207         *
208         * @param conf job configuration.
209         * @return the job Id.
210         * @throws org.apache.oozie.client.OozieClientException thrown if the job
211         *         could not be submitted.
212         */
213        @Override
214        public String run(Properties conf) throws OozieClientException {
215            try {
216                return coordEngine.submitJob(new XConfiguration(conf), true);
217            }
218            catch (CoordinatorEngineException ex) {
219                throw new OozieClientException(ex.getErrorCode().toString(), ex);
220            }
221        }
222    
223        /**
224         * Rerun a workflow job.
225         *
226         * @param jobId job Id to rerun.
227         * @param conf configuration information for the rerun.
228         * @throws org.apache.oozie.client.OozieClientException thrown if the job
229         *         could not be started.
230         */
231        @Override
232        @Deprecated
233        public void reRun(String jobId, Properties conf) throws OozieClientException {
234            throw new OozieClientException(ErrorCode.E0301.toString(), "no-op");
235        }
236    
237        /**
238         * Rerun coordinator actions.
239         *
240         * @param jobId coordinator jobId
241         * @param rerunType rerun type 'date' if -date is used, 'action-id' if
242         *        -action is used
243         * @param scope rerun scope for date or actionIds
244         * @param refresh true if -refresh is given in command option
245         * @param noCleanup true if -nocleanup is given in command option
246         * @throws OozieClientException
247         */
248        @Override
249        public List<CoordinatorAction> reRunCoord(String jobId, String rerunType, String scope, boolean refresh,
250                boolean noCleanup) throws OozieClientException {
251            try {
252                CoordinatorActionInfo coordInfo = coordEngine.reRun(jobId, rerunType, scope, Boolean.valueOf(refresh),
253                        Boolean.valueOf(noCleanup));
254                List<CoordinatorActionBean> actionBeans = coordInfo.getCoordActions();
255                List<CoordinatorAction> actions = new ArrayList<CoordinatorAction>();
256                for (CoordinatorActionBean actionBean : actionBeans) {
257                    actions.add(actionBean);
258                }
259                return actions;
260            }
261            catch (BaseEngineException ex) {
262                throw new OozieClientException(ex.getErrorCode().toString(), ex);
263            }
264        }
265    
266        /**
267         * Suspend a coordinator job.
268         *
269         * @param jobId job Id.
270         * @throws org.apache.oozie.client.OozieClientException thrown if the job
271         *         could not be suspended.
272         */
273        @Override
274        public void suspend(String jobId) throws OozieClientException {
275            try {
276                coordEngine.suspend(jobId);
277            }
278            catch (CoordinatorEngineException ex) {
279                throw new OozieClientException(ex.getErrorCode().toString(), ex);
280            }
281        }
282    
283        /**
284         * Resume a coordinator job.
285         *
286         * @param jobId job Id.
287         * @throws org.apache.oozie.client.OozieClientException thrown if the job
288         *         could not be resume.
289         */
290        @Override
291        public void resume(String jobId) throws OozieClientException {
292            try {
293                coordEngine.resume(jobId);
294            }
295            catch (CoordinatorEngineException ex) {
296                throw new OozieClientException(ex.getErrorCode().toString(), ex);
297            }
298        }
299    
300        /**
301         * Kill a coordinator job.
302         *
303         * @param jobId job Id.
304         * @throws org.apache.oozie.client.OozieClientException thrown if the job
305         *         could not be killed.
306         */
307        @Override
308        public void kill(String jobId) throws OozieClientException {
309            try {
310                coordEngine.kill(jobId);
311            }
312            catch (CoordinatorEngineException ex) {
313                throw new OozieClientException(ex.getErrorCode().toString(), ex);
314            }
315        }
316    
317        /**
318         * Get the info of a workflow job.
319         *
320         * @param jobId job Id.
321         * @return the job info.
322         * @throws org.apache.oozie.client.OozieClientException thrown if the job
323         *         info could not be retrieved.
324         */
325        @Override
326        @Deprecated
327        public WorkflowJob getJobInfo(String jobId) throws OozieClientException {
328            throw new OozieClientException(ErrorCode.E0301.toString(), "no-op");
329        }
330    
331        /**
332         * Get the info of a coordinator job.
333         *
334         * @param jobId job Id.
335         * @return the job info.
336         * @throws org.apache.oozie.client.OozieClientException thrown if the job
337         *         info could not be retrieved.
338         */
339        @Override
340        public CoordinatorJob getCoordJobInfo(String jobId) throws OozieClientException {
341            try {
342                return coordEngine.getCoordJob(jobId);
343            }
344            catch (CoordinatorEngineException ex) {
345                throw new OozieClientException(ex.getErrorCode().toString(), ex);
346            }
347            catch (BaseEngineException bex) {
348                throw new OozieClientException(bex.getErrorCode().toString(), bex);
349            }
350        }
351    
352        /**
353         * Get the info of a coordinator action.
354         * 
355         * @param actionId Id.
356         * @return the coordinator action info.
357         * @throws OozieClientException thrown if the job info could not be
358         *         retrieved.
359         */
360        @Override
361        public CoordinatorAction getCoordActionInfo(String actionId) throws OozieClientException {
362            try {
363                return coordEngine.getCoordAction(actionId);
364            }
365            catch (CoordinatorEngineException ex) {
366                throw new OozieClientException(ex.getErrorCode().toString(), ex);
367            }
368            catch (BaseEngineException bex) {
369                throw new OozieClientException(bex.getErrorCode().toString(), bex);
370            }
371        }
372    
373        /**
374         * Return the info of the workflow jobs that match the filter.
375         *
376         * @param filter job filter. Refer to the {@link OozieClient} for the filter
377         *        syntax.
378         * @param start jobs offset, base 1.
379         * @param len number of jobs to return.
380         * @return a list with the workflow jobs info, without node details.
381         * @throws OozieClientException thrown if the jobs info could not be
382         *         retrieved.
383         */
384        @Override
385        @Deprecated
386        public List<WorkflowJob> getJobsInfo(String filter, int start, int len) throws OozieClientException {
387            throw new OozieClientException(ErrorCode.E0301.toString(), "no-op");
388        }
389    
390        /**
391         * Return the info of the coordinator jobs that match the filter.
392         *
393         * @param filter job filter. Refer to the {@link OozieClient} for the filter
394         *        syntax.
395         * @param start jobs offset, base 1.
396         * @param len number of jobs to return.
397         * @return a list with the coordinator jobs info
398         * @throws OozieClientException thrown if the jobs info could not be
399         *         retrieved.
400         */
401        @Override
402        public List<CoordinatorJob> getCoordJobsInfo(String filter, int start, int len) throws OozieClientException {
403            try {
404                CoordinatorJobInfo info = coordEngine.getCoordJobs(filter, start, len);
405                List<CoordinatorJob> jobs = new ArrayList<CoordinatorJob>();
406                List<CoordinatorJobBean> jobBeans = info.getCoordJobs();
407                for (CoordinatorJobBean jobBean : jobBeans) {
408                    jobs.add(jobBean);
409                }
410                return jobs;
411    
412            }
413            catch (CoordinatorEngineException ex) {
414                throw new OozieClientException(ex.getErrorCode().toString(), ex);
415            }
416        }
417    
418        /**
419         * Return the info of the workflow jobs that match the filter.
420         * <p/>
421         * It returns the first 100 jobs that match the filter.
422         *
423         * @param filter job filter. Refer to the {@link LocalOozieClient} for the
424         *        filter syntax.
425         * @return a list with the workflow jobs info, without node details.
426         * @throws org.apache.oozie.client.OozieClientException thrown if the jobs
427         *         info could not be retrieved.
428         */
429        @Override
430        @Deprecated
431        public List<WorkflowJob> getJobsInfo(String filter) throws OozieClientException {
432            throw new OozieClientException(ErrorCode.E0301.toString(), "no-op");
433        }
434    
435    }