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