/*************************GO-LICENSE-START*********************************
* Copyright 2014 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.
*************************GO-LICENSE-END***********************************/
package com.thoughtworks.go.server.service.builders;
import com.thoughtworks.go.config.CaseInsensitiveString;
import com.thoughtworks.go.config.FetchTask;
import com.thoughtworks.go.config.PathFromAncestor;
import com.thoughtworks.go.domain.builder.Builder;
import com.thoughtworks.go.domain.ChecksumFileHandler;
import com.thoughtworks.go.domain.DirHandler;
import com.thoughtworks.go.domain.builder.FetchArtifactBuilder;
import com.thoughtworks.go.domain.FetchHandler;
import com.thoughtworks.go.domain.FileHandler;
import com.thoughtworks.go.domain.JobIdentifier;
import com.thoughtworks.go.domain.MaterialRevisions;
import com.thoughtworks.go.domain.Pipeline;
import com.thoughtworks.go.domain.StageIdentifier;
import com.thoughtworks.go.domain.buildcause.BuildCause;
import com.thoughtworks.go.domain.materials.dependency.DependencyMaterialRevision;
import com.thoughtworks.go.server.service.UpstreamPipelineResolver;
import com.thoughtworks.go.util.FileUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import static com.thoughtworks.go.util.ExceptionUtils.bomb;
@Component
public class FetchTaskBuilder implements TaskBuilder<FetchTask> {
@Override
public Builder createBuilder(BuilderFactory builderFactory, FetchTask task, Pipeline pipeline, UpstreamPipelineResolver resolver) {
JobIdentifier fetchFrom = resolveTargetJob(task, pipeline, resolver);
Builder cancelBuilder = builderFactory.builderFor(task.cancelTask(), pipeline, resolver);
return new FetchArtifactBuilder(task.getConditions(), cancelBuilder, task.describe(), fetchFrom, task.getSrc(),
task.getDest(), getHandler(task, pipeline.getName()), getChecksumHandler(task, pipeline.getName()));
}
private ChecksumFileHandler getChecksumHandler(FetchTask task, String pipelineName) {
return new ChecksumFileHandler(task.artifactDest(pipelineName, task.checksumPath()));
}
FetchHandler getHandler(FetchTask task, String pipelineName) {
return StringUtils.isNotEmpty(task.getRawSrcdir()) ? new DirHandler(task.getRawSrcdir(), task.destOnAgent(pipelineName)) : new FileHandler(
task.artifactDest(pipelineName, FileUtil.fileNameFromPath(task.getRawSrcfile())), task.getSrc());
}
private JobIdentifier resolveTargetJob(FetchTask task, Pipeline currentPipeline, UpstreamPipelineResolver resolver) {
PathFromAncestor pipelineNamePathFromAncestor = task.getPipelineNamePathFromAncestor();
if (pipelineNamePathFromAncestor == null
|| CaseInsensitiveString.isBlank(pipelineNamePathFromAncestor.getPath())
|| CaseInsensitiveString.areEqual(new CaseInsensitiveString(currentPipeline.getName()), pipelineNamePathFromAncestor.getPath())) {
task.setPipelineName(new CaseInsensitiveString(currentPipeline.getName()));
String stageCounter = JobIdentifier.LATEST;
if (currentPipeline.hasStageBeenRun(CaseInsensitiveString.str(task.getStage()))) {
stageCounter = String.valueOf(currentPipeline.findStage(CaseInsensitiveString.str(task.getStage())).getCounter());
}
return new JobIdentifier(new StageIdentifier(currentPipeline.getName(), currentPipeline.getCounter(), currentPipeline.getLabel(), CaseInsensitiveString.str(task.getStage()), stageCounter), CaseInsensitiveString.str(task.getJob()));
} else {
DependencyMaterialRevision revision = null;
if (pipelineNamePathFromAncestor.isAncestor()) {
BuildCause buildCause = currentPipeline.getBuildCause();
for (CaseInsensitiveString parentPipelineName : pipelineNamePathFromAncestor.pathToAncestor()) {
DependencyMaterialRevision dependencyMaterialRevision = dmrForPipeline(parentPipelineName, buildCause);
if (dependencyMaterialRevision == null) {
throw bomb(String.format("Pipeline [%s] could not fetch artifact [%s]. Unable to resolve revision for [%s] from build cause", currentPipeline.getName(), task, parentPipelineName));
}
buildCause = resolver.buildCauseFor(dependencyMaterialRevision.getPipelineName(), dependencyMaterialRevision.getPipelineCounter());
}
revision = dmrForPipeline(pipelineNamePathFromAncestor.getAncestorName(), buildCause);
if (revision == null) {
throw bomb(String.format("Pipeline [%s] could not fetch artifact [%s]. Unable to resolve revision for [%s] from build cause", currentPipeline.getName(), task, pipelineNamePathFromAncestor.getAncestorName()));
}
} else {
revision = dmrForPipeline(pipelineNamePathFromAncestor.getPath(), currentPipeline.getBuildCause());
if (revision == null) {
throw bomb(String.format("Pipeline [%s] tries to fetch artifact from job [%s/%s/%s] "
+ "which is not a dependency material", currentPipeline.getName(), pipelineNamePathFromAncestor, task.getStage(), task.getJob()));
}
}
String stageCounter = JobIdentifier.LATEST;
if (task.getStage().equals(new CaseInsensitiveString(revision.getStageName()))) {
stageCounter = String.valueOf(revision.getStageCounter());
}
return new JobIdentifier(new StageIdentifier(CaseInsensitiveString.str(pipelineNamePathFromAncestor.getAncestorName()), revision.getPipelineCounter(), revision.getPipelineLabel(),
CaseInsensitiveString.str(task.getStage()), stageCounter), CaseInsensitiveString.str(task.getJob()));
}
}
private DependencyMaterialRevision dmrForPipeline(CaseInsensitiveString pipelineName, BuildCause buildCause) {
MaterialRevisions materialRevisions = buildCause.getMaterialRevisions();
return materialRevisions.findDependencyMaterialRevision(CaseInsensitiveString.str(pipelineName));
}
}