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.ArrayList;
022import java.util.List;
023
024import javax.servlet.http.HttpServletRequest;
025import javax.servlet.http.HttpServletResponse;
026
027import org.apache.commons.lang.StringUtils;
028import org.apache.hadoop.conf.Configuration;
029import org.apache.oozie.CoordinatorActionBean;
030import org.apache.oozie.CoordinatorActionInfo;
031import org.apache.oozie.CoordinatorEngine;
032import org.apache.oozie.CoordinatorEngineException;
033import org.apache.oozie.DagEngine;
034import org.apache.oozie.DagEngineException;
035import org.apache.oozie.ErrorCode;
036import org.apache.oozie.client.CoordinatorAction;
037import org.apache.oozie.client.rest.JsonBean;
038import org.apache.oozie.client.rest.JsonTags;
039import org.apache.oozie.client.rest.RestConstants;
040import org.apache.oozie.command.CommandException;
041import org.apache.oozie.service.CoordinatorEngineService;
042import org.apache.oozie.service.DagEngineService;
043import org.apache.oozie.service.Services;
044import org.json.simple.JSONObject;
045
046@SuppressWarnings("serial")
047public class V2JobServlet extends V1JobServlet {
048
049    private static final String INSTRUMENTATION_NAME = "v2job";
050
051    public V2JobServlet() {
052        super(INSTRUMENTATION_NAME);
053    }
054
055    @Override
056    protected JsonBean getWorkflowJob(HttpServletRequest request, HttpServletResponse response) throws XServletException {
057        JsonBean jobBean = super.getWorkflowJobBean(request, response);
058        return jobBean;
059    }
060
061    @Override
062    protected JsonBean getWorkflowAction(HttpServletRequest request, HttpServletResponse response) throws XServletException {
063        JsonBean actionBean = super.getWorkflowActionBean(request, response);
064        return actionBean;
065    }
066
067    @Override
068    protected int getCoordinatorJobLength(int defaultLen, int len) {
069        return (len < 0) ? defaultLen : len;
070    }
071
072    @Override
073    protected String getJMSTopicName(HttpServletRequest request, HttpServletResponse response) throws XServletException,
074            IOException {
075        String topicName;
076        String jobId = getResourceName(request);
077        DagEngine dagEngine = Services.get().get(DagEngineService.class).getDagEngine(getUser(request));
078        try {
079            topicName = dagEngine.getJMSTopicName(jobId);
080        }
081        catch (DagEngineException ex) {
082            throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
083        }
084        return topicName;
085    }
086
087    @Override
088    protected JSONObject getJobsByParentId(HttpServletRequest request, HttpServletResponse response)
089            throws XServletException, IOException {
090        return super.getJobsByParentId(request, response);
091    }
092
093    /**
094     * Update coord job.
095     *
096     * @param request the request
097     * @param response the response
098     * @return the JSON object
099     * @throws XServletException the x servlet exception
100     * @throws IOException Signals that an I/O exception has occurred.
101     */
102    @SuppressWarnings("unchecked")
103    @Override
104    protected JSONObject updateJob(HttpServletRequest request, HttpServletResponse response, Configuration conf)
105            throws XServletException, IOException {
106        CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class)
107                .getCoordinatorEngine(getUser(request));
108        JSONObject json = new JSONObject();
109        try {
110            String jobId = getResourceName(request);
111            boolean dryrun = StringUtils.isEmpty(request.getParameter(RestConstants.JOB_ACTION_DRYRUN)) ? false
112                    : Boolean.parseBoolean(request.getParameter(RestConstants.JOB_ACTION_DRYRUN));
113            boolean showDiff = StringUtils.isEmpty(request.getParameter(RestConstants.JOB_ACTION_SHOWDIFF)) ? true
114                    : Boolean.parseBoolean(request.getParameter(RestConstants.JOB_ACTION_SHOWDIFF));
115
116            String diff = coordEngine.updateJob(conf, jobId, dryrun, showDiff);
117            JSONObject diffJson = new JSONObject();
118            diffJson.put(JsonTags.COORD_UPDATE_DIFF, diff);
119            json.put(JsonTags.COORD_UPDATE, diffJson);
120        }
121        catch (CoordinatorEngineException e) {
122            throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, e);
123        }
124        return json;
125    }
126
127    /**
128     * Ignore a coordinator job
129     * @param request request object
130     * @param response response object
131     * @throws XServletException
132     * @throws IOException
133     */
134    @Override
135    protected JSONObject ignoreJob(HttpServletRequest request, HttpServletResponse response) throws XServletException, IOException {
136        String jobId = getResourceName(request);
137        if (jobId.endsWith("-W")) {
138            throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, "Workflow Ignore Not supported");
139        } else if (jobId.endsWith("-B")) {
140            throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ErrorCode.E0302, "Bundle Ignore Not supported");
141        } else {
142            return ignoreCoordinatorJob(request, response);
143        }
144
145    }
146
147    /**
148     * Ignore a coordinator job/action
149     *
150     * @param request servlet request
151     * @param response servlet response
152     * @throws XServletException
153     */
154    @SuppressWarnings("unchecked")
155    private JSONObject ignoreCoordinatorJob(HttpServletRequest request, HttpServletResponse response)
156            throws XServletException {
157        JSONObject json = null;
158        CoordinatorEngine coordEngine = Services.get().get(CoordinatorEngineService.class).getCoordinatorEngine(
159                getUser(request));
160        String jobId = getResourceName(request);
161        String type = request.getParameter(RestConstants.JOB_COORD_RANGE_TYPE_PARAM);
162        String scope = request.getParameter(RestConstants.JOB_COORD_SCOPE_PARAM);
163        String changeValue = "status=" + CoordinatorAction.Status.IGNORED;
164        List<CoordinatorActionBean> coordActions = new ArrayList<CoordinatorActionBean>();
165        try {
166            if (type != null && !type.equals(RestConstants.JOB_COORD_SCOPE_ACTION)) {
167                throw new CommandException(ErrorCode.E1024, "Currently ignore only support -action option");
168            }
169            CoordinatorActionInfo coordInfo = null;
170            if(scope == null || scope.isEmpty()) {
171                coordEngine.change(jobId, changeValue);
172            } else{
173                coordInfo = coordEngine.ignore(jobId, type, scope);
174            }
175            if(coordInfo != null) {
176                coordActions = coordInfo.getCoordActions();
177                json = new JSONObject();
178                json.put(JsonTags.COORDINATOR_ACTIONS, CoordinatorActionBean.toJSONArray(coordActions, "GMT"));
179            }
180            return json;
181        }
182        catch (CommandException ex) {
183            throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
184        }
185        catch (CoordinatorEngineException ex) {
186            throw new XServletException(HttpServletResponse.SC_BAD_REQUEST, ex);
187        }
188    }
189}