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
019package org.apache.oozie;
020
021import java.util.ArrayList;
022import java.util.List;
023import java.util.Properties;
024
025import org.apache.oozie.client.CoordinatorAction;
026import org.apache.oozie.client.CoordinatorJob;
027import org.apache.oozie.client.OozieClient;
028import org.apache.oozie.client.OozieClientException;
029import org.apache.oozie.client.WorkflowJob;
030import org.apache.oozie.client.rest.RestConstants;
031import org.apache.oozie.command.CommandException;
032import org.apache.oozie.coord.CoordUtils;
033import org.apache.oozie.util.XConfiguration;
034
035/**
036 * Client API to submit and manage Oozie coordinator jobs against an Oozie
037 * instance.
038 * <p>
039 * This class is thread safe.
040 * <p>
041 * Syntax for filter for the {@link #getJobsInfo(String)}
042 * {@link #getJobsInfo(String, int, int)} methods:
043 * <code>[NAME=VALUE][;NAME=VALUE]*</code>.
044 * <p>
045 * Valid filter names are:
046 * <ul>
047 * <li>name: the coordinator application name from the coordinator definition.</li>
048 * <li>user: the user that submitted the job.</li>
049 * <li>group: the group for the job.</li>
050 * <li>status: the status of the job.</li>
051 * </ul>
052 * <p>
053 * The query will do an AND among all the filter names. The query will do an OR
054 * among all the filter values for the same name. Multiple values must be
055 * specified as different name value pairs.
056 */
057public class LocalOozieClientCoord extends BaseLocalOozieClient {
058
059    private final CoordinatorEngine coordEngine;
060
061    /**
062     * Create a coordinator client for Oozie local use.
063     * <p>
064     *
065     * @param coordEngine the engine instance to use.
066     */
067    public LocalOozieClientCoord(CoordinatorEngine coordEngine) {
068        super(coordEngine);
069        this.coordEngine = coordEngine;
070    }
071
072    /**
073     * Rerun coordinator actions.
074     *
075     * @param jobId coordinator jobId
076     * @param rerunType rerun type 'date' if -date is used, 'action-id' if
077     *        -action is used
078     * @param scope rerun scope for date or actionIds
079     * @param refresh true if -refresh is given in command option
080     * @param noCleanup true if -nocleanup is given in command option
081     * @throws OozieClientException if coordinators cannot be rerun
082     */
083    @Override
084    public List<CoordinatorAction> reRunCoord(String jobId, String rerunType, String scope, boolean refresh,
085                                              boolean noCleanup) throws OozieClientException {
086        return getCoordinatorActions(jobId, rerunType, scope, refresh, noCleanup, false, null);
087    }
088
089    /**
090     * Rerun coordinator actions with failed option.
091     *
092     * @param jobId coordinator jobId
093     * @param rerunType rerun type 'date' if -date is used, 'action-id' if
094     *        -action is used
095     * @param scope rerun scope for date or actionIds
096     * @param refresh true if -refresh is given in command option
097     * @param noCleanup true if -nocleanup is given in command option
098     * @param failed true if -failed is given in command option
099     * @param conf configuration information for the rerun
100     * @throws OozieClientException  if coordinators cannot be rerun
101     */
102    @Override
103    public List<CoordinatorAction> reRunCoord(String jobId, String rerunType, String scope, boolean refresh,
104            boolean noCleanup, boolean failed, Properties conf ) throws OozieClientException {
105        return getCoordinatorActions(jobId, rerunType, scope, refresh, noCleanup, failed, conf);
106    }
107
108    private List<CoordinatorAction> getCoordinatorActions(String jobId, String rerunType, String scope, boolean refresh,
109            boolean noCleanup, boolean failed, Properties prop) throws OozieClientException {
110        try {
111            XConfiguration conf = null;
112            if (prop != null) {
113                conf = new XConfiguration(prop);
114            }
115            if (!(rerunType.equals(RestConstants.JOB_COORD_SCOPE_DATE) || rerunType
116                    .equals(RestConstants.JOB_COORD_SCOPE_ACTION))) {
117                throw new CommandException(ErrorCode.E1018, "date or action expected.");
118            }
119            CoordinatorActionInfo coordInfo = coordEngine.reRun(jobId, rerunType, scope, Boolean.valueOf(refresh),
120                    Boolean.valueOf(noCleanup), Boolean.valueOf(failed), conf);
121            List<CoordinatorActionBean> actionBeans;
122            if (coordInfo != null) {
123                actionBeans = coordInfo.getCoordActions();
124            }
125            else {
126                actionBeans = CoordUtils.getCoordActions(rerunType, jobId, scope, false);
127            }
128            List<CoordinatorAction> actions = new ArrayList<CoordinatorAction>();
129            for (CoordinatorActionBean actionBean : actionBeans) {
130                actions.add(actionBean);
131            }
132            return actions;
133        }
134        catch(CommandException ce){
135            throw new OozieClientException(ce.getErrorCode().toString(), ce);
136        }
137        catch (BaseEngineException ex) {
138            throw new OozieClientException(ex.getErrorCode().toString(), ex);
139        }
140    }
141
142    /**
143     * Get the info of a coordinator job.
144     *
145     * @param jobId job Id.
146     * @return the job info.
147     * @throws org.apache.oozie.client.OozieClientException thrown if the job
148     *         info could not be retrieved.
149     */
150    @Override
151    public CoordinatorJob getCoordJobInfo(String jobId) throws OozieClientException {
152        try {
153            return coordEngine.getCoordJob(jobId);
154        }
155        catch (CoordinatorEngineException ex) {
156            throw new OozieClientException(ex.getErrorCode().toString(), ex);
157        }
158        catch (BaseEngineException bex) {
159            throw new OozieClientException(bex.getErrorCode().toString(), bex);
160        }
161    }
162
163    /**
164     * Get the info of a coordinator job.
165     *
166     * @param jobId job Id.
167     * @param filter filter the status filter
168     * @param start starting index in the list of actions belonging to the job
169     * @param len number of actions to be returned
170     * @return the job info.
171     * @throws org.apache.oozie.client.OozieClientException thrown if the job
172     *         info could not be retrieved.
173     */
174    @Override
175    public CoordinatorJob getCoordJobInfo(String jobId, String filter, int start, int len)
176            throws OozieClientException {
177        try {
178            return coordEngine.getCoordJob(jobId, filter, start, len, false);
179        }
180        catch (BaseEngineException bex) {
181            throw new OozieClientException(bex.getErrorCode().toString(), bex);
182        }
183    }
184
185    /**
186     * Get the info of a coordinator action.
187     *
188     * @param actionId Id.
189     * @return the coordinator action info.
190     * @throws OozieClientException thrown if the job info could not be
191     *         retrieved.
192     */
193    @Override
194    public CoordinatorAction getCoordActionInfo(String actionId) throws OozieClientException {
195        try {
196            return coordEngine.getCoordAction(actionId);
197        }
198        catch (BaseEngineException bex) {
199            throw new OozieClientException(bex.getErrorCode().toString(), bex);
200        }
201    }
202
203    /**
204     * Return the info of the coordinator jobs that match the filter.
205     *
206     * @param filter job filter. Refer to the {@link OozieClient} for the filter
207     *        syntax.
208     * @param start jobs offset, base 1.
209     * @param len number of jobs to return.
210     * @return a list with the coordinator jobs info
211     * @throws OozieClientException thrown if the jobs info could not be
212     *         retrieved.
213     */
214    @Override
215    public List<CoordinatorJob> getCoordJobsInfo(String filter, int start, int len) throws OozieClientException {
216        try {
217            CoordinatorJobInfo info = coordEngine.getCoordJobs(filter, start, len);
218            List<CoordinatorJob> jobs = new ArrayList<CoordinatorJob>();
219            List<CoordinatorJobBean> jobBeans = info.getCoordJobs();
220            for (CoordinatorJobBean jobBean : jobBeans) {
221                jobs.add(jobBean);
222            }
223            return jobs;
224
225        }
226        catch (CoordinatorEngineException ex) {
227            throw new OozieClientException(ex.getErrorCode().toString(), ex);
228        }
229    }
230
231    @Override
232    public String updateCoord(String jobId, Properties conf, String dryrun, String showDiff) throws OozieClientException {
233        try {
234            return coordEngine.updateJob(new XConfiguration(conf), jobId, Boolean.valueOf(dryrun), Boolean.valueOf(showDiff));
235        } catch (CoordinatorEngineException e) {
236            throw new OozieClientException(e.getErrorCode().toString(), e);
237        }
238    }
239
240    @Override
241    public String updateCoord(String jobId, String dryrun, String showDiff) throws OozieClientException {
242        try {
243            return coordEngine.updateJob(new XConfiguration(), jobId, Boolean.valueOf(dryrun), Boolean.valueOf(showDiff));
244        } catch (CoordinatorEngineException e) {
245            throw new OozieClientException(e.getErrorCode().toString(), e);
246        }
247    }
248
249    @Override
250    public CoordinatorJob getCoordJobInfo(String jobId, String filter, int start, int len, String order)
251            throws OozieClientException {
252        try {
253            return coordEngine.getCoordJob(jobId, filter, start, len, order.equalsIgnoreCase("DESC"));
254        } catch (BaseEngineException e) {
255            throw new OozieClientException(e.getErrorCode().toString(), e);
256        }
257    }
258
259    @Override
260    public List<CoordinatorAction> kill(String jobId, String rangeType, String scope) throws OozieClientException {
261        try {
262            return (List) coordEngine.killActions(jobId, rangeType, scope).getCoordActions();
263        } catch (CoordinatorEngineException e) {
264            throw new OozieClientException(e.getErrorCode().toString(), e);
265        }
266    }
267
268    @Override
269    public List<CoordinatorAction> ignore(String jobId, String scope) throws OozieClientException {
270        try {
271            return (List) coordEngine.ignore(jobId, RestConstants.JOB_COORD_SCOPE_ACTION, scope).getCoordActions();
272        } catch (CoordinatorEngineException e) {
273            throw new OozieClientException(e.getErrorCode().toString(), e);
274        }
275    }
276
277    @Override
278    public List<WorkflowJob> getWfsForCoordAction(String coordActionId) throws OozieClientException {
279        try {
280            return (List) coordEngine.getReruns(coordActionId);
281        } catch (CoordinatorEngineException e) {
282            throw new OozieClientException(e.getErrorCode().toString(), e);
283        }
284    }
285}