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 */
018package org.apache.oozie;
019
020import java.util.ArrayList;
021import java.util.Collections;
022import java.util.Iterator;
023import java.util.List;
024import java.util.Properties;
025
026import org.apache.oozie.client.CoordinatorAction;
027import org.apache.oozie.client.CoordinatorJob;
028import org.apache.oozie.client.OozieClient;
029import org.apache.oozie.client.OozieClientException;
030import org.apache.oozie.client.WorkflowJob;
031import org.apache.oozie.client.rest.JsonCoordinatorAction;
032import org.apache.oozie.client.rest.JsonCoordinatorJob;
033import org.apache.oozie.client.rest.RestConstants;
034import org.apache.oozie.command.CommandException;
035import org.apache.oozie.command.coord.CoordRerunXCommand;
036import 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 */
061public 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}