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 }