/* * Copyright 2016 ThoughtWorks, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.thoughtworks.go.server.controller; import com.thoughtworks.go.config.StageNotFoundException; import com.thoughtworks.go.i18n.Localizer; import com.thoughtworks.go.server.GoUnauthorizedException; import com.thoughtworks.go.server.security.HeaderConstraint; import com.thoughtworks.go.server.service.ScheduleService; import com.thoughtworks.go.server.service.result.HttpLocalizedOperationResult; import com.thoughtworks.go.server.util.ErrorHandler; import com.thoughtworks.go.server.util.UserHelper; import com.thoughtworks.go.server.web.ResponseCodeView; import com.thoughtworks.go.util.SystemEnvironment; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.LinkedHashMap; import java.util.Map; import static com.thoughtworks.go.server.controller.actions.JsonAction.jsonNotAcceptable; import static com.thoughtworks.go.server.controller.actions.JsonAction.jsonOK; import static com.thoughtworks.go.util.json.JsonHelper.addFriendlyErrorMessage; import static java.lang.String.format; @Controller public class StageController { private static final Logger LOGGER = Logger.getLogger(StageController.class); private ScheduleService scheduleService; private Localizer localizer; private HeaderConstraint headerConstraint; protected StageController() { } @Autowired public StageController(ScheduleService scheduleService, Localizer localizer, SystemEnvironment systemEnvironment) { this.scheduleService = scheduleService; this.localizer = localizer; this.headerConstraint = new HeaderConstraint(systemEnvironment); } @RequestMapping(value = "/admin/rerun", method = RequestMethod.POST) public ModelAndView rerunStage(@RequestParam(value = "pipelineName") String pipelineName, @RequestParam(value = "pipelineLabel") String counterOrLabel, @RequestParam(value = "stageName") String stageName, HttpServletResponse response, HttpServletRequest request) { if(!headerConstraint.isSatisfied(request)) { return ResponseCodeView.create(HttpServletResponse.SC_BAD_REQUEST, "Missing required header 'Confirm'"); } try { scheduleService.rerunStage(pipelineName, counterOrLabel, stageName); return ResponseCodeView.create(HttpServletResponse.SC_OK, ""); } catch (GoUnauthorizedException e) { return ResponseCodeView.create(HttpServletResponse.SC_UNAUTHORIZED, ""); } catch (StageNotFoundException e) { LOGGER.error(String.format("Error while rerunning %s/%s/%s", pipelineName, counterOrLabel, stageName), e); return ResponseCodeView.create(HttpServletResponse.SC_NOT_FOUND, e.getMessage()); } catch (Exception e) { LOGGER.error(String.format("Error while rerunning %s/%s/%s", pipelineName, counterOrLabel, stageName), e); return ResponseCodeView.create(HttpServletResponse.SC_BAD_REQUEST, e.getMessage()); } } @RequestMapping(value = "/**/cancel.json", method = RequestMethod.POST) public ModelAndView cancelViaPost(@RequestParam(value = "id") Long stageId, HttpServletResponse response, HttpServletRequest request) { if(!headerConstraint.isSatisfied(request)) { return ResponseCodeView.create(HttpServletResponse.SC_BAD_REQUEST, "Missing required header 'Confirm'"); } try { HttpLocalizedOperationResult cancelResult = new HttpLocalizedOperationResult(); scheduleService.cancelAndTriggerRelevantStages(stageId, UserHelper.getUserName(), cancelResult); return handleResult(cancelResult, response); } catch (GoUnauthorizedException e) { return ResponseCodeView.create(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage()); } catch (Exception e) { return ResponseCodeView.create(HttpServletResponse.SC_NOT_ACCEPTABLE, e.getMessage()); } } private ModelAndView handleResult(HttpLocalizedOperationResult cancelResult, HttpServletResponse response) { if (cancelResult.httpCode() == HttpServletResponse.SC_UNAUTHORIZED) { return ResponseCodeView.create(HttpServletResponse.SC_UNAUTHORIZED, cancelResult.message(localizer)); } return jsonOK().respond(response); } @ErrorHandler public ModelAndView handleError(HttpServletRequest request, HttpServletResponse response, Exception e) { Map<String, Object> json = new LinkedHashMap<>(); String message = e.getMessage(); if (e instanceof StageNotFoundException) { StageNotFoundException stageNotFoundException = (StageNotFoundException) e; message = format( "Stage '%s' of pipeline '%s' does not exist in current configuration. You can not rerun it.", stageNotFoundException.getStageName(), stageNotFoundException.getPipelineName()); } addFriendlyErrorMessage(json, message); return jsonNotAcceptable(json).respond(response); } }