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 org.apache.hadoop.conf.Configuration;
018 import org.apache.oozie.client.rest.RestConstants;
019 import org.apache.oozie.client.rest.JsonTags;
020 import org.apache.oozie.client.OozieClient;
021 import org.apache.oozie.util.XConfiguration;
022 import org.apache.oozie.service.Services;
023 import org.apache.oozie.service.DagEngineService;
024 import org.apache.oozie.service.WorkflowAppService;
025 import org.apache.oozie.DagEngine;
026 import org.apache.oozie.DagEngineException;
027 import org.apache.oozie.WorkflowsInfo;
028 import org.apache.oozie.WorkflowJobBean;
029 import org.apache.oozie.ErrorCode;
030 import org.json.simple.JSONObject;
031
032 import javax.servlet.ServletException;
033 import javax.servlet.http.HttpServletRequest;
034 import javax.servlet.http.HttpServletResponse;
035 import java.io.IOException;
036 import java.util.Arrays;
037 import java.util.List;
038
039 public class JobsServlet extends JsonRestServlet {
040 private static final String INSTRUMENTATION_NAME = "jobs";
041
042 private static final JsonRestServlet.ResourceInfo RESOURCES_INFO[] = new JsonRestServlet.ResourceInfo[1];
043
044 static {
045 RESOURCES_INFO[0] =
046 new JsonRestServlet.ResourceInfo("", Arrays.asList("POST", "GET"), Arrays.asList(
047 new JsonRestServlet.ParameterInfo(RestConstants.ACTION_PARAM, String.class, false, Arrays.asList("POST")),
048 new JsonRestServlet.ParameterInfo(RestConstants.JOBS_FILTER_PARAM, String.class, false, Arrays.asList("GET")),
049 new JsonRestServlet.ParameterInfo(RestConstants.JOBTYPE_PARAM, String.class, false, Arrays.asList("GET")),
050 new JsonRestServlet.ParameterInfo(RestConstants.OFFSET_PARAM, String.class, false, Arrays.asList("GET")),
051 new JsonRestServlet.ParameterInfo(RestConstants.LEN_PARAM, String.class, false, Arrays.asList("GET")),
052 new JsonRestServlet.ParameterInfo(RestConstants.JOBS_EXTERNAL_ID_PARAM, String.class, false, Arrays.asList("GET"))));
053 }
054
055 public JobsServlet() {
056 super(INSTRUMENTATION_NAME, RESOURCES_INFO);
057 }
058
059 /**
060 * Create a job.
061 */
062 @SuppressWarnings("unchecked")
063 protected void doPost(HttpServletRequest request, HttpServletResponse response)
064 throws ServletException, IOException {
065
066 validateContentType(request, RestConstants.XML_CONTENT_TYPE);
067
068 request.setAttribute(AUDIT_OPERATION, request.getParameter(RestConstants.ACTION_PARAM));
069
070 XConfiguration conf = new XConfiguration(request.getInputStream());
071
072 stopCron();
073
074 conf = conf.trim();
075 conf = conf.resolve();
076
077 validateJobConfiguration(conf);
078
079 JobServlet.checkAuthorizationForApp(getUser(request), conf);
080
081 String action = request.getParameter(RestConstants.ACTION_PARAM);
082 if (action != null && !action.equals(RestConstants.JOB_ACTION_START)) {
083 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0303, RestConstants.ACTION_PARAM,
084 action);
085 }
086 try {
087 boolean startJob = (action != null);
088 String user = conf.get(OozieClient.USER_NAME);
089 DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(user, getAuthToken(request));
090 String id = dagEngine.submitJob(conf, startJob);
091 JSONObject json = new JSONObject();
092 json.put(JsonTags.JOB_ID, id);
093 startCron();
094 sendJsonResponse(response, HttpServletResponse.SC_CREATED, json);
095 }
096 catch (DagEngineException ex) {
097 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
098 }
099 }
100
101 static void validateJobConfiguration(Configuration conf) throws XServletException {
102 if (conf.get(OozieClient.USER_NAME) == null) {
103 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0401,
104 OozieClient.USER_NAME);
105 }
106
107 String localRealm = Services.get().getConf().get("local.realm");
108
109 //if the job properties don't define JT/NN Kerberos principals, add default value
110 if (conf.get(WorkflowAppService.HADOOP_JT_KERBEROS_NAME) == null) {
111 conf.set(WorkflowAppService.HADOOP_JT_KERBEROS_NAME, "mapred/_HOST@" + localRealm);
112 }
113 if (conf.get(WorkflowAppService.HADOOP_NN_KERBEROS_NAME) == null) {
114 conf.set(WorkflowAppService.HADOOP_NN_KERBEROS_NAME, "hdfs/_HOST@" + localRealm);
115 }
116 }
117
118 /**
119 * Return information about jobs.
120 */
121 @SuppressWarnings("unchecked")
122 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
123 try {
124 String externalId = request.getParameter(RestConstants.JOBS_EXTERNAL_ID_PARAM);
125 if (externalId != null) {
126 stopCron();
127 DagEngine dagEngine = Services.get().get(DagEngineService.class)
128 .getDagEngine(getUser(request), getAuthToken(request));
129 String jobId = dagEngine.getJobIdForExternalId(externalId);
130 JSONObject json = new JSONObject();
131 json.put(JsonTags.JOB_ID, jobId);
132 startCron();
133 sendJsonResponse(response, HttpServletResponse.SC_OK, json);
134 }
135 else {
136 String filter = request.getParameter(RestConstants.JOBS_FILTER_PARAM);
137 String startStr = request.getParameter(RestConstants.OFFSET_PARAM);
138 String lenStr = request.getParameter(RestConstants.LEN_PARAM);
139 int start = (startStr != null) ? Integer.parseInt(startStr) : 1;
140 start = (start < 1) ? 1 : start;
141 int len = (lenStr != null) ? Integer.parseInt(lenStr) : 50;
142 len = (len < 1) ? 50 : len;
143 stopCron();
144 DagEngine dagEngine = Services.get().get(DagEngineService.class)
145 .getDagEngine(getUser(request), getAuthToken(request));
146 WorkflowsInfo jobs = dagEngine.getJobs(filter, start, len);
147 List<WorkflowJobBean> jsonWorkflows = jobs.getWorkflows();
148 startCron();
149 JSONObject json = new JSONObject();
150 json.put(JsonTags.WORKFLOWS_JOBS, WorkflowJobBean.toJSONArray(jsonWorkflows));
151 json.put(JsonTags.WORKFLOWS_TOTAL, jobs.getTotal());
152 json.put(JsonTags.WORKFLOWS_OFFSET, jobs.getStart());
153 json.put(JsonTags.WORKFLOWS_LEN, jobs.getLen());
154 sendJsonResponse(response, HttpServletResponse.SC_OK, json);
155 }
156 }
157 catch (DagEngineException ex) {
158 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
159 }
160 }
161
162 }