/* * 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.service; import com.thoughtworks.go.config.*; import com.thoughtworks.go.config.elastic.ElasticProfile; import com.thoughtworks.go.domain.*; import com.thoughtworks.go.domain.buildcause.BuildCause; import com.thoughtworks.go.util.Clock; import org.springframework.stereotype.Component; import java.util.List; @Component public class InstanceFactory { public Pipeline createPipelineInstance(PipelineConfig pipelineConfig, BuildCause buildCause, SchedulingContext context, String md5, Clock clock) { buildCause.assertMaterialsMatch(pipelineConfig.materialConfigs()); buildCause.assertPipelineConfigAndMaterialRevisionMatch(pipelineConfig); return new Pipeline(CaseInsensitiveString.str(pipelineConfig.name()), pipelineConfig.getLabelTemplate(), buildCause, createStageInstance(pipelineConfig.first(), context, md5, clock)); } public Stage createStageInstance(PipelineConfig pipelineConfig, CaseInsensitiveString stageName, SchedulingContext context, String md5, Clock clock) { StageConfig stageConfig = pipelineConfig.findBy(stageName); if (stageConfig == null) { throw new StageNotFoundException(pipelineConfig.name(), stageName); } return createStageInstance(stageConfig, context, md5, clock); } public Stage createStageInstance(StageConfig stageConfig, SchedulingContext context, String md5, Clock clock) { return new Stage(CaseInsensitiveString.str(stageConfig.name()), createJobInstances(stageConfig, context, clock), context.getApprovedBy(), stageConfig.approvalType(), stageConfig.isFetchMaterials(), stageConfig.isCleanWorkingDir(), md5, clock); } public Stage createStageForRerunOfJobs(Stage stage, List<String> jobNames, SchedulingContext context, StageConfig stageConfig, Clock clock, String latestMd5) { Stage newStage = stage.createClone(); newStage.prepareForRerunOf(context, latestMd5); createRerunJobs(newStage, jobNames, context, stageConfig, clock); return newStage; } public JobInstances createJobInstance(CaseInsensitiveString stageName, JobConfig jobConfig, SchedulingContext context, Clock clock, JobType.JobNameGenerator jobNameGenerator) { JobInstances instances = new JobInstances(); createJobType(jobConfig.isRunOnAllAgents(), jobConfig.isRunMultipleInstanceType()).createJobInstances(instances, context, jobConfig, CaseInsensitiveString.str(stageName), jobNameGenerator, clock, this); return instances; } private JobInstances createJobInstances(StageConfig stageConfig, SchedulingContext context, Clock clock) { JobInstances instances = new JobInstances(); for (JobConfig jobConfig : stageConfig.getJobs()) { JobType.JobNameGenerator nameGenerator = null; if (jobConfig.isRunOnAllAgents()) { nameGenerator = new RunOnAllAgents.CounterBasedJobNameGenerator(CaseInsensitiveString.str(jobConfig.name())); } else if (jobConfig.isRunMultipleInstanceType()) { nameGenerator = new RunMultipleInstance.CounterBasedJobNameGenerator(CaseInsensitiveString.str(jobConfig.name())); } JobInstances configInstances = createJobInstance(stageConfig.name(), jobConfig, context, clock, nameGenerator); instances.addAll(configInstances); } return instances; } private void createRerunJobs(Stage newStage, List<String> jobNames, SchedulingContext context, StageConfig stageConfig, Clock clock) { for (String jobName : jobNames) { JobInstances jobInstances = newStage.getJobInstances(); JobInstance oldJob = jobInstances.getByName(jobName); jobInstances.remove(oldJob); createJobType(oldJob.isRunOnAllAgents(), oldJob.isRunMultipleInstance()).createRerunInstances(oldJob, jobInstances, context, stageConfig, clock, this); } } private JobType createJobType(boolean runOnAllAgents, boolean runMultipleInstances) { if (runOnAllAgents) { return new RunOnAllAgents(); } if (runMultipleInstances) { return new RunMultipleInstance(); } return new SingleJobInstance(); } public void reallyCreateJobInstance(JobConfig config, JobInstances jobs, String uuid, String jobName, boolean runOnAllAgents, boolean runMultipleInstance, SchedulingContext context, final Clock clock) { JobInstance instance = new JobInstance(jobName, clock); instance.setPlan(createJobPlan(config, context)); instance.setAgentUuid(uuid); instance.setRunOnAllAgents(runOnAllAgents); instance.setRunMultipleInstance(runMultipleInstance); jobs.add(instance); } public JobPlan createJobPlan(JobConfig config, SchedulingContext context) { JobIdentifier identifier = new JobIdentifier(); String elasticProfileId = config.getElasticProfileId(); ElasticProfile elasticProfile = null; if (elasticProfileId != null) { elasticProfile = context.getElasticProfile(elasticProfileId); } return new DefaultJobPlan(config.resources(), config.artifactPlans(), config.getProperties(), -1, identifier, null, context.overrideEnvironmentVariables(config.getVariables()).getEnvironmentVariablesConfig(), new EnvironmentVariablesConfig(), elasticProfile); } }