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