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 }