001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 * 
010 *      http://www.apache.org/licenses/LICENSE-2.0
011 * 
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.oozie.servlet;
019
020import java.io.IOException;
021import java.util.Arrays;
022
023import javax.servlet.ServletException;
024import javax.servlet.http.HttpServletRequest;
025import javax.servlet.http.HttpServletResponse;
026
027import org.apache.hadoop.conf.Configuration;
028import org.apache.oozie.ErrorCode;
029import org.apache.oozie.client.OozieClient;
030import org.apache.oozie.client.rest.RestConstants;
031import org.apache.oozie.service.Services;
032import org.apache.oozie.service.WorkflowAppService;
033import org.apache.oozie.util.JobUtils;
034import org.apache.oozie.util.XConfiguration;
035import org.json.simple.JSONObject;
036
037public abstract class BaseJobsServlet extends JsonRestServlet {
038
039    private static final JsonRestServlet.ResourceInfo RESOURCES_INFO[] = new JsonRestServlet.ResourceInfo[1];
040
041    static {
042        RESOURCES_INFO[0] = new JsonRestServlet.ResourceInfo("", Arrays.asList(
043                "POST", "GET"), Arrays.asList(
044                new JsonRestServlet.ParameterInfo(RestConstants.ACTION_PARAM,
045                                                  String.class, false, Arrays.asList("POST")),
046                new JsonRestServlet.ParameterInfo(
047                        RestConstants.JOBS_FILTER_PARAM, String.class, false,
048                        Arrays.asList("GET")),
049                new JsonRestServlet.ParameterInfo(RestConstants.JOBTYPE_PARAM,
050                                                  String.class, false, Arrays.asList("GET", "POST")),
051                new JsonRestServlet.ParameterInfo(RestConstants.OFFSET_PARAM,
052                                                  String.class, false, Arrays.asList("GET")),
053                new JsonRestServlet.ParameterInfo(RestConstants.LEN_PARAM,
054                                                  String.class, false, Arrays.asList("GET")),
055                new JsonRestServlet.ParameterInfo(RestConstants.JOBS_BULK_PARAM,
056                                                  String.class, false, Arrays.asList("GET")),
057                new JsonRestServlet.ParameterInfo(
058                        RestConstants.JOBS_EXTERNAL_ID_PARAM, String.class,
059                        false, Arrays.asList("GET"))));
060    }
061
062    public BaseJobsServlet(String instrumentationName) {
063        super(instrumentationName, RESOURCES_INFO);
064    }
065
066    /**
067     * Create a job.
068     */
069    @Override
070    @SuppressWarnings("unchecked")
071    protected void doPost(HttpServletRequest request,
072            HttpServletResponse response) throws ServletException, IOException {
073        /*
074         * Enumeration p = request.getAttributeNames();
075         * for(;p.hasMoreElements();){ String key = (String)p.nextElement();
076         * XLog.getLog(getClass()).warn(" key "+ key + " val "+ (String)
077         * request.getAttribute(key)); }
078         */
079        validateContentType(request, RestConstants.XML_CONTENT_TYPE);
080
081        request.setAttribute(AUDIT_OPERATION, request
082                .getParameter(RestConstants.ACTION_PARAM));
083
084        XConfiguration conf = new XConfiguration(request.getInputStream());
085
086        stopCron();
087
088        conf = conf.trim();
089        conf = conf.resolve();
090
091        validateJobConfiguration(conf);
092        String requestUser = getUser(request);
093        if (!requestUser.equals(UNDEF)) {
094            conf.set(OozieClient.USER_NAME, requestUser);
095        }
096        BaseJobServlet.checkAuthorizationForApp(conf);
097        JobUtils.normalizeAppPath(conf.get(OozieClient.USER_NAME), conf.get(OozieClient.GROUP_NAME), conf);
098
099        JSONObject json = submitJob(request, conf);
100        startCron();
101        sendJsonResponse(response, HttpServletResponse.SC_CREATED, json);
102    }
103
104    /**
105     * Return information about jobs.
106     */
107    @Override
108    public void doGet(HttpServletRequest request, HttpServletResponse response)
109    throws ServletException, IOException {
110        String externalId = request
111        .getParameter(RestConstants.JOBS_EXTERNAL_ID_PARAM);
112        if (externalId != null) {
113            stopCron();
114            JSONObject json = getJobIdForExternalId(request, externalId);
115            startCron();
116            sendJsonResponse(response, HttpServletResponse.SC_OK, json);
117        }
118        else {
119            stopCron();
120            JSONObject json = getJobs(request);
121            startCron();
122            sendJsonResponse(response, HttpServletResponse.SC_OK, json);
123        }
124    }
125
126    /**
127     * abstract method to submit a job, either workflow or coordinator in the case of workflow job, there is an optional
128     * flag in request to indicate if want this job to be started immediately or not
129     *
130     * @param request
131     * @param conf
132     * @return JSONObject of job id
133     * @throws XServletException
134     * @throws IOException
135     */
136    abstract JSONObject submitJob(HttpServletRequest request, Configuration conf)
137    throws XServletException, IOException;
138
139    /**
140     * abstract method to get a job from external ID
141     *
142     * @param request
143     * @param externalId
144     * @return JSONObject for the requested job
145     * @throws XServletException
146     * @throws IOException
147     */
148    abstract JSONObject getJobIdForExternalId(HttpServletRequest request,
149            String externalId) throws XServletException, IOException;
150
151    /**
152     * abstract method to get a list of workflow jobs
153     *
154     * @param request
155     * @return JSONObject of the requested jobs
156     * @throws XServletException
157     * @throws IOException
158     */
159    abstract JSONObject getJobs(HttpServletRequest request)
160    throws XServletException, IOException;
161
162    static void validateJobConfiguration(Configuration conf) throws XServletException {
163        if (conf.get(OozieClient.USER_NAME) == null) {
164            throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0401,
165                    OozieClient.USER_NAME);
166        }
167    }
168}