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.servlet;
016
017 import java.io.IOException;
018 import java.util.List;
019
020 import javax.servlet.http.HttpServletRequest;
021 import javax.servlet.http.HttpServletResponse;
022
023 import org.apache.hadoop.conf.Configuration;
024 import org.apache.oozie.CoordinatorEngine;
025 import org.apache.oozie.CoordinatorEngineException;
026 import org.apache.oozie.CoordinatorJobBean;
027 import org.apache.oozie.CoordinatorJobInfo;
028 import org.apache.oozie.DagEngine;
029 import org.apache.oozie.DagEngineException;
030 import org.apache.oozie.ErrorCode;
031 import org.apache.oozie.WorkflowJobBean;
032 import org.apache.oozie.WorkflowsInfo;
033 import org.apache.oozie.client.OozieClient;
034 import org.apache.oozie.client.rest.JsonTags;
035 import org.apache.oozie.client.rest.RestConstants;
036 import org.apache.oozie.service.CoordinatorEngineService;
037 import org.apache.oozie.service.DagEngineService;
038 import org.apache.oozie.service.Services;
039 import org.apache.oozie.util.XLog;
040 import org.apache.oozie.util.XmlUtils;
041 import org.json.simple.JSONObject;
042
043 public class V1JobsServlet extends BaseJobsServlet {
044
045 private static final String INSTRUMENTATION_NAME = "v1jobs";
046
047 public V1JobsServlet() {
048 super(INSTRUMENTATION_NAME);
049 }
050
051 /**
052 * v1 service implementation to submit a job, either workflow or coordinator
053 */
054 @Override
055 protected JSONObject submitJob(HttpServletRequest request, Configuration conf) throws XServletException,
056 IOException {
057 JSONObject json = null;
058
059 String jobType = request.getParameter(RestConstants.JOBTYPE_PARAM);
060
061 if (jobType == null) {
062 String wfPath = conf.get(OozieClient.APP_PATH);
063 String coordPath = conf.get(OozieClient.COORDINATOR_APP_PATH);
064
065 ServletUtilities.ValidateAppPath(wfPath, coordPath);
066
067 if (wfPath != null) {
068 json = submitWorkflowJob(request, conf);
069 }
070 else {
071 json = submitCoordinatorJob(request, conf);
072 }
073 }
074 else { // This is a http submission job
075 if (jobType.equals("pig") || jobType.equals("mapreduce")) {
076 json = submitHttpJob(request, conf, jobType);
077 }
078 else {
079 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0303,
080 RestConstants.JOBTYPE_PARAM, jobType);
081 }
082 }
083 return json;
084 }
085
086 /**
087 * v1 service implementation to get a JSONObject representation of a job
088 * from its external ID
089 */
090 @Override
091 protected JSONObject getJobIdForExternalId(HttpServletRequest request, String externalId) throws XServletException,
092 IOException {
093 JSONObject json = null;
094 /*
095 * Configuration conf = new XConfiguration(); String wfPath =
096 * conf.get(OozieClient.APP_PATH); String coordPath =
097 * conf.get(OozieClient.COORDINATOR_APP_PATH);
098 *
099 * ServletUtilities.ValidateAppPath(wfPath, coordPath);
100 */
101 String jobtype = request.getParameter(RestConstants.JOBTYPE_PARAM);
102 jobtype = (jobtype != null) ? jobtype : "wf";
103 if (jobtype.contains("wf")) {
104 json = getWorkflowJobIdForExternalId(request, externalId);
105 }
106 else {
107 json = getCoordinatorJobIdForExternalId(request, externalId);
108 }
109 return json;
110 }
111
112 /**
113 * v1 service implementation to get a list of workflows, with filtering or interested windows embedded in the
114 * request object
115 */
116 @Override
117 protected JSONObject getJobs(HttpServletRequest request) throws XServletException, IOException {
118 JSONObject json = null;
119 /*
120 * json = getWorkflowJobs(request); if (json != null) { return json; }
121 * else { json = getCoordinatorJobs(request); } return json;
122 */
123 // Configuration conf = new XConfiguration();
124
125 String jobtype = request.getParameter(RestConstants.JOBTYPE_PARAM);
126 jobtype = (jobtype != null) ? jobtype : "wf";
127
128 if (jobtype.contains("wf")) {
129 json = getWorkflowJobs(request);
130 }
131 else {
132 json = getCoordinatorJobs(request);
133 }
134 return json;
135 }
136
137 /**
138 * v1 service implementation to submit a workflow job
139 */
140 private JSONObject submitWorkflowJob(HttpServletRequest request, Configuration conf) throws XServletException {
141
142 JSONObject json = new JSONObject();
143
144 try {
145 String action = request.getParameter(RestConstants.ACTION_PARAM);
146 if (action != null && !action.equals(RestConstants.JOB_ACTION_START)) {
147 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0303,
148 RestConstants.ACTION_PARAM, action);
149 }
150 boolean startJob = (action != null);
151 String user = conf.get(OozieClient.USER_NAME);
152 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(user, getAuthToken(request));
153 String id = dagEngine.submitJob(conf, startJob);
154 json.put(JsonTags.JOB_ID, id);
155 }
156 catch (DagEngineException ex) {
157 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
158 }
159
160 return json;
161 }
162
163 /**
164 * v1 service implementation to submit a coordinator job
165 */
166 private JSONObject submitCoordinatorJob(HttpServletRequest request, Configuration conf) throws XServletException {
167
168 JSONObject json = new JSONObject();
169 XLog.getLog(getClass()).warn("submitCoordinatorJob " + XmlUtils.prettyPrint(conf).toString());
170 try {
171 String action = request.getParameter(RestConstants.ACTION_PARAM);
172 if (action != null && !action.equals(RestConstants.JOB_ACTION_START)
173 && !action.equals(RestConstants.JOB_ACTION_DRYRUN)) {
174 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0303,
175 RestConstants.ACTION_PARAM, action);
176 }
177 boolean startJob = (action != null);
178 String user = conf.get(OozieClient.USER_NAME);
179 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
180 user, getAuthToken(request));
181 String id = null;
182 boolean dryrun = false;
183 if (action != null) {
184 dryrun = (action.equals(RestConstants.JOB_ACTION_DRYRUN));
185 }
186 if (dryrun) {
187 id = coordEngine.dryrunSubmit(conf, startJob);
188 }
189 else {
190 id = coordEngine.submitJob(conf, startJob);
191 }
192 json.put(JsonTags.JOB_ID, id);
193 }
194 catch (CoordinatorEngineException ex) {
195 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
196 }
197
198 return json;
199 }
200
201 /**
202 * v1 service implementation to get a JSONObject representation of a job from its external ID
203 */
204 private JSONObject getWorkflowJobIdForExternalId(HttpServletRequest request, String externalId)
205 throws XServletException {
206 JSONObject json = new JSONObject();
207 try {
208 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
209 getAuthToken(request));
210 String jobId = dagEngine.getJobIdForExternalId(externalId);
211 json.put(JsonTags.JOB_ID, jobId);
212 }
213 catch (DagEngineException ex) {
214 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
215 }
216 return json;
217 }
218
219 /**
220 * v1 service implementation to get a JSONObject representation of a job from its external ID
221 */
222 private JSONObject getCoordinatorJobIdForExternalId(HttpServletRequest request, String externalId)
223 throws XServletException {
224 JSONObject json = new JSONObject();
225 // TODO
226 return json;
227 }
228
229 /**
230 * v1 service implementation to get a list of workflows, with filtering or interested windows embedded in the
231 * request object
232 */
233 private JSONObject getWorkflowJobs(HttpServletRequest request) throws XServletException {
234 JSONObject json = new JSONObject();
235 try {
236 String filter = request.getParameter(RestConstants.JOBS_FILTER_PARAM);
237 String startStr = request.getParameter(RestConstants.OFFSET_PARAM);
238 String lenStr = request.getParameter(RestConstants.LEN_PARAM);
239 int start = (startStr != null) ? Integer.parseInt(startStr) : 1;
240 start = (start < 1) ? 1 : start;
241 int len = (lenStr != null) ? Integer.parseInt(lenStr) : 50;
242 len = (len < 1) ? 50 : len;
243 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request),
244 getAuthToken(request));
245 WorkflowsInfo jobs = dagEngine.getJobs(filter, start, len);
246 List<WorkflowJobBean> jsonWorkflows = jobs.getWorkflows();
247 json.put(JsonTags.WORKFLOWS_JOBS, WorkflowJobBean.toJSONArray(jsonWorkflows));
248 json.put(JsonTags.WORKFLOWS_TOTAL, jobs.getTotal());
249 json.put(JsonTags.WORKFLOWS_OFFSET, jobs.getStart());
250 json.put(JsonTags.WORKFLOWS_LEN, jobs.getLen());
251
252 }
253 catch (DagEngineException ex) {
254 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
255 }
256
257 return json;
258 }
259
260 /**
261 * v1 service implementation to get a list of workflows, with filtering or interested windows embedded in the
262 * request object
263 */
264 @SuppressWarnings("unchecked")
265 private JSONObject getCoordinatorJobs(HttpServletRequest request) throws XServletException {
266 JSONObject json = new JSONObject();
267 try {
268 String filter = request.getParameter(RestConstants.JOBS_FILTER_PARAM);
269 String startStr = request.getParameter(RestConstants.OFFSET_PARAM);
270 String lenStr = request.getParameter(RestConstants.LEN_PARAM);
271 int start = (startStr != null) ? Integer.parseInt(startStr) : 1;
272 start = (start < 1) ? 1 : start;
273 int len = (lenStr != null) ? Integer.parseInt(lenStr) : 50;
274 len = (len < 1) ? 50 : len;
275 CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
276 getUser(request), getAuthToken(request));
277 CoordinatorJobInfo jobs = coordEngine.getCoordJobs(filter, start, len);
278 List<CoordinatorJobBean> jsonJobs = jobs.getCoordJobs();
279 json.put(JsonTags.COORDINATOR_JOBS, CoordinatorJobBean.toJSONArray(jsonJobs));
280 json.put(JsonTags.COORD_JOB_TOTAL, jobs.getTotal());
281 json.put(JsonTags.COORD_JOB_OFFSET, jobs.getStart());
282 json.put(JsonTags.COORD_JOB_LEN, jobs.getLen());
283
284 }
285 catch (CoordinatorEngineException ex) {
286 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
287 }
288 return json;
289 }
290
291 /**
292 * service implementation to submit a http job
293 */
294 private JSONObject submitHttpJob(HttpServletRequest request, Configuration conf, String jobType) throws XServletException {
295 JSONObject json = new JSONObject();
296
297 try {
298 String user = conf.get(OozieClient.USER_NAME);
299 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(user, getAuthToken(request));
300 String id = dagEngine.submitHttpJob(conf, jobType);
301 json.put(JsonTags.JOB_ID, id);
302 }
303 catch (DagEngineException ex) {
304 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
305 }
306
307 return json;
308 }
309 }