/* * 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.AgentConfig; import com.thoughtworks.go.config.CaseInsensitiveString; import com.thoughtworks.go.config.Tabs; import com.thoughtworks.go.config.TrackingTool; import com.thoughtworks.go.domain.*; import com.thoughtworks.go.domain.Properties; import com.thoughtworks.go.i18n.Localizer; import com.thoughtworks.go.server.presentation.models.JobDetailPresentationModel; import com.thoughtworks.go.server.presentation.models.JobStatusJsonPresentationModel; import com.thoughtworks.go.server.service.*; import com.thoughtworks.go.server.util.ErrorHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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.*; import static com.thoughtworks.go.server.controller.actions.JsonAction.jsonFound; import static com.thoughtworks.go.util.ExceptionUtils.bomb; import static com.thoughtworks.go.util.GoConstants.ERROR_FOR_PAGE; import static com.thoughtworks.go.util.json.JsonHelper.addDeveloperErrorMessage; /* * Handles requests for Build Details: See urlrewrite.xml. */ @Controller public class JobController { private static final Log LOGGER = LogFactory.getLog(JobController.class); @Autowired private JobInstanceService jobInstanceService; @Autowired private JobDetailService jobDetailService; @Autowired private GoConfigService goConfigService; @Autowired private PipelineService pipelineService; @Autowired private RestfulService restfulService; @Autowired private ArtifactsService artifactService; @Autowired private PropertiesService propertiesService; @Autowired private StageService stageService; @Autowired private Localizer localizer; public JobController() { } JobController( JobInstanceService jobInstanceService, JobDetailService jobDetailService, GoConfigService goConfigService, PipelineService pipelineService, RestfulService restfulService, ArtifactsService artifactService, PropertiesService propertiesService, StageService stageService, Localizer localizer) { this.jobInstanceService = jobInstanceService; this.jobDetailService = jobDetailService; this.goConfigService = goConfigService; this.pipelineService = pipelineService; this.restfulService = restfulService; this.artifactService = artifactService; this.propertiesService = propertiesService; this.stageService = stageService; this.localizer = localizer; } @RequestMapping(value = "/tab/build/recent", method = RequestMethod.GET) public ModelAndView jobDetail(@RequestParam("pipelineName") String pipelineName, @RequestParam("label") String counterOrLabel, @RequestParam("stageName") String stageName, @RequestParam("stageCounter") String stageCounter, @RequestParam("jobName") String jobName) throws Exception { Pipeline pipeline = pipelineService.findPipelineByCounterOrLabel(pipelineName, counterOrLabel); if (pipeline == null) { throw bomb(String.format("Job %s/%s/%s/%s/%s not found", pipelineName, counterOrLabel, stageName, stageCounter, jobName)); } StageIdentifier stageIdentifier = restfulService.translateStageCounter(pipeline.getIdentifier(), stageName, stageCounter); JobInstance instance = jobDetailService.findMostRecentBuild(new JobIdentifier(stageIdentifier, jobName)); return getModelAndView(instance); } private ModelAndView getModelAndView(JobInstance jobDetail) throws Exception { final JobDetailPresentationModel presenter = presenter(jobDetail); Map data = new HashMap(); data.put("presenter", presenter); data.put("l", localizer); data.put("isEditableViaUI", goConfigService.isPipelineEditableViaUI(jobDetail.getPipelineName())); return new ModelAndView("build_detail/build_detail_page", data); } @ErrorHandler public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Exception e) throws Exception { LOGGER.error("Job detail page error: ", e); Map model = new HashMap(); model.put(ERROR_FOR_PAGE, e.getMessage()); return new ModelAndView("exceptions_page", model); } private JobDetailPresentationModel presenter(JobInstance current) { String pipelineName = current.getIdentifier().getPipelineName(); String stageName = current.getIdentifier().getStageName(); JobInstances recent25 = jobInstanceService.latestCompletedJobs(pipelineName, stageName, current.getName()); AgentConfig agentConfig = goConfigService.agentByUuid(current.getAgentUuid()); Pipeline pipelineWithOneBuild = pipelineService.wrapBuildDetails(current); Tabs customizedTabs = goConfigService.getCustomizedTabs(pipelineWithOneBuild.getName(), pipelineWithOneBuild.getFirstStage().getName(), current.getName()); TrackingTool trackingTool = goConfigService.pipelineConfigNamed( new CaseInsensitiveString(pipelineWithOneBuild.getName())).trackingTool(); Properties properties = propertiesService.getPropertiesForJob(current.getId()); Stage stage = stageService.getStageByBuild(current); return new JobDetailPresentationModel(current, recent25, agentConfig, pipelineWithOneBuild, customizedTabs, trackingTool, artifactService, properties, stage); } @RequestMapping(value = "/**/jobStatus.json", method = RequestMethod.GET) public ModelAndView handleRequest(@RequestParam(value = "pipelineName") String pipelineName, @RequestParam(value = "stageName") String stageName, @RequestParam(value = "jobId") long jobId, HttpServletResponse response) { Object json; try { JobInstance requestedInstance = jobInstanceService.buildByIdWithTransitions(jobId); JobInstance mostRecentJobInstance = jobDetailService.findMostRecentBuild(requestedInstance.getIdentifier()); JobStatusJsonPresentationModel presenter = new JobStatusJsonPresentationModel(mostRecentJobInstance, goConfigService.agentByUuid(mostRecentJobInstance.getAgentUuid()), stageService.getBuildDuration(pipelineName, stageName, mostRecentJobInstance)); json = createBuildInfo(presenter); } catch (Exception e) { LOGGER.warn(e); json = errorJsonMap(e); } return jsonFound(json).respond(response); } private Map errorJsonMap(Exception e) { Map<String, Object> jsonMap = new LinkedHashMap<>(); addDeveloperErrorMessage(jsonMap, e); return jsonMap; } private List createBuildInfo(JobStatusJsonPresentationModel presenter) { // TODO: Hucking Fack alert. We shouldn't need "building_info" Map<String, Object> info = new LinkedHashMap<>(); info.put("building_info", presenter.toJsonHash()); List jsonList = new ArrayList(); jsonList.add(info); return jsonList; } }