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.Arrays;
019
020 import javax.servlet.ServletException;
021 import javax.servlet.http.HttpServletRequest;
022 import javax.servlet.http.HttpServletResponse;
023
024 import org.apache.hadoop.conf.Configuration;
025 import org.apache.oozie.ErrorCode;
026 import org.apache.oozie.client.OozieClient;
027 import org.apache.oozie.client.rest.RestConstants;
028 import org.apache.oozie.service.Services;
029 import org.apache.oozie.service.WorkflowAppService;
030 import org.apache.oozie.util.XConfiguration;
031 import org.json.simple.JSONObject;
032
033 public abstract class BaseJobsServlet extends JsonRestServlet {
034
035 private static final JsonRestServlet.ResourceInfo RESOURCES_INFO[] = new JsonRestServlet.ResourceInfo[1];
036
037 static {
038 RESOURCES_INFO[0] = new JsonRestServlet.ResourceInfo("", Arrays.asList(
039 "POST", "GET"), Arrays.asList(
040 new JsonRestServlet.ParameterInfo(RestConstants.ACTION_PARAM,
041 String.class, false, Arrays.asList("POST")),
042 new JsonRestServlet.ParameterInfo(
043 RestConstants.JOBS_FILTER_PARAM, String.class, false,
044 Arrays.asList("GET")),
045 new JsonRestServlet.ParameterInfo(RestConstants.JOBTYPE_PARAM,
046 String.class, false, Arrays.asList("GET", "POST")),
047 new JsonRestServlet.ParameterInfo(RestConstants.OFFSET_PARAM,
048 String.class, false, Arrays.asList("GET")),
049 new JsonRestServlet.ParameterInfo(RestConstants.LEN_PARAM,
050 String.class, false, Arrays.asList("GET")),
051
052 new JsonRestServlet.ParameterInfo(
053 RestConstants.JOBS_EXTERNAL_ID_PARAM, String.class,
054 false, Arrays.asList("GET"))));
055 }
056
057 public BaseJobsServlet(String instrumentationName) {
058 super(instrumentationName, RESOURCES_INFO);
059 }
060
061 /**
062 * Create a job.
063 */
064 @Override
065 @SuppressWarnings("unchecked")
066 protected void doPost(HttpServletRequest request,
067 HttpServletResponse response) throws ServletException, IOException {
068 String authTok = getAuthToken(request);
069 /*
070 * Enumeration p = request.getAttributeNames();
071 * for(;p.hasMoreElements();){ String key = (String)p.nextElement();
072 * XLog.getLog(getClass()).warn(" key "+ key + " val "+ (String)
073 * request.getAttribute(key)); }
074 */
075 validateContentType(request, RestConstants.XML_CONTENT_TYPE);
076
077 request.setAttribute(AUDIT_OPERATION, request
078 .getParameter(RestConstants.ACTION_PARAM));
079
080 XConfiguration conf = new XConfiguration(request.getInputStream());
081
082 stopCron();
083
084 conf = conf.trim();
085 conf = conf.resolve();
086
087 validateJobConfiguration(conf);
088 BaseJobServlet.checkAuthorizationForApp(getUser(request), conf);
089
090 JSONObject json = submitJob(request, conf);
091 startCron();
092 sendJsonResponse(response, HttpServletResponse.SC_CREATED, json);
093 }
094
095 /**
096 * Return information about jobs.
097 */
098 @Override
099 @SuppressWarnings("unchecked")
100 public void doGet(HttpServletRequest request, HttpServletResponse response)
101 throws ServletException, IOException {
102 String externalId = request
103 .getParameter(RestConstants.JOBS_EXTERNAL_ID_PARAM);
104 if (externalId != null) {
105 stopCron();
106 JSONObject json = getJobIdForExternalId(request, externalId);
107 startCron();
108 sendJsonResponse(response, HttpServletResponse.SC_OK, json);
109 }
110 else {
111 stopCron();
112 // Configuration conf = new
113 // XConfiguration(request.getInputStream());
114 JSONObject json = getJobs(request);
115 startCron();
116 sendJsonResponse(response, HttpServletResponse.SC_OK, json);
117 }
118 }
119
120 /**
121 * abstract method to submit a job, either workflow or coordinator in the case of workflow job, there is an optional
122 * flag in request to indicate if want this job to be started immediately or not
123 *
124 * @param request
125 * @param conf
126 * @return JSONObject of job id
127 * @throws XServletException
128 * @throws IOException
129 */
130 abstract JSONObject submitJob(HttpServletRequest request, Configuration conf)
131 throws XServletException, IOException;
132
133 /**
134 * abstract method to get a job from external ID
135 *
136 * @param request
137 * @param externalId
138 * @return JSONObject for the requested job
139 * @throws XServletException
140 * @throws IOException
141 */
142 abstract JSONObject getJobIdForExternalId(HttpServletRequest request,
143 String externalId) throws XServletException, IOException;
144
145 /**
146 * abstract method to get a list of workflow jobs
147 *
148 * @param request
149 * @return JSONObject of the requested jobs
150 * @throws XServletException
151 * @throws IOException
152 */
153 abstract JSONObject getJobs(HttpServletRequest request)
154 throws XServletException, IOException;
155
156 static void validateJobConfiguration(Configuration conf) throws XServletException {
157 if (conf.get(OozieClient.USER_NAME) == null) {
158 throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0401,
159 OozieClient.USER_NAME);
160 }
161
162 String localRealm = Services.get().getConf().get("local.realm");
163
164 //if the job properties don't define JT/NN Kerberos principals, add default value
165 if (conf.get(WorkflowAppService.HADOOP_JT_KERBEROS_NAME) == null) {
166 conf.set(WorkflowAppService.HADOOP_JT_KERBEROS_NAME, "mapred/_HOST@" + localRealm);
167 }
168 if (conf.get(WorkflowAppService.HADOOP_NN_KERBEROS_NAME) == null) {
169 conf.set(WorkflowAppService.HADOOP_NN_KERBEROS_NAME, "hdfs/_HOST@" + localRealm);
170 }
171 }
172 }