/* * Copyright 2017 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.config; import com.thoughtworks.go.config.materials.MaterialConfigs; import com.thoughtworks.go.config.remote.ConfigReposConfig; import com.thoughtworks.go.domain.PipelineGroups; import com.thoughtworks.go.domain.materials.MaterialConfig; import com.thoughtworks.go.domain.packagerepository.PackageRepository; import com.thoughtworks.go.domain.scm.SCM; import com.thoughtworks.go.util.Node; import org.apache.commons.lang.NotImplementedException; import java.util.ArrayList; import java.util.Hashtable; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; public class PipelineConfigSaveValidationContext implements ValidationContext { private final Boolean isPipelineBeingCreated; private final String groupName; private final Validatable immediateParent; private BasicCruiseConfig cruiseConfig; private PipelineConfig pipelineBeingValidated; private boolean isPipeline = true;//Does not support template editing yet private final PipelineConfigSaveValidationContext parentContext; private PipelineConfig pipeline; private StageConfig stage; private JobConfig job; private MaterialConfigFingerprintMap materialConfigsFingerprintMap; private PipelineConfigSaveValidationContext(Boolean isPipelineBeingCreated, String groupName, Validatable immediateParent) { this.isPipelineBeingCreated = isPipelineBeingCreated; this.groupName = groupName; this.immediateParent = immediateParent; this.parentContext = null; } private PipelineConfigSaveValidationContext(Validatable immediateParent, PipelineConfigSaveValidationContext parentContext) { this.isPipelineBeingCreated = parentContext.isPipelineBeingCreated(); this.groupName = parentContext.groupName; this.immediateParent = immediateParent; this.parentContext = parentContext; if (immediateParent instanceof BasicCruiseConfig) { this.cruiseConfig = (BasicCruiseConfig) immediateParent; } else if (parentContext.cruiseConfig != null) { this.cruiseConfig = parentContext.cruiseConfig; } if (immediateParent instanceof PipelineConfig) { this.pipeline = (PipelineConfig) immediateParent; } else if (parentContext.pipeline != null) { this.pipeline = parentContext.pipeline; } if (immediateParent instanceof JobConfig) { this.job = (JobConfig) immediateParent; } else if (parentContext.getJob() != null) { this.job = parentContext.job; } if (immediateParent instanceof StageConfig) { this.stage = (StageConfig) immediateParent; } else if (parentContext.stage != null) { this.stage = parentContext.stage; } this.pipelineBeingValidated = parentContext.pipelineBeingValidated; if (parentContext.pipelineBeingValidated == null) { this.pipelineBeingValidated = this.pipeline; } } public static PipelineConfigSaveValidationContext forChain(Boolean isPipelineBeingCreated, String groupName, Validatable... validatables) { PipelineConfigSaveValidationContext tail = new PipelineConfigSaveValidationContext(isPipelineBeingCreated, groupName, null); for (Validatable validatable : validatables) { tail = tail.withParent(validatable); } return tail; } @Override public PipelineConfigSaveValidationContext withParent(Validatable current) { return new PipelineConfigSaveValidationContext(current, this); } @Override public ConfigReposConfig getConfigRepos() { throw new NotImplementedException(); } public JobConfig getJob() { return this.job; } public StageConfig getStage() { return this.stage; } public PipelineConfig getPipeline() { return this.pipeline; } public PipelineTemplateConfig getTemplate() { throw new NotImplementedException(); } public String getParentDisplayName() { return getParent().getClass().getAnnotation(ConfigTag.class).value(); } public Validatable getParent() { return immediateParent; } public boolean isWithinTemplates() { return !isPipeline; } public boolean isWithinPipelines() { return isPipeline; } public PipelineConfigs getPipelineGroup() { if (cruiseConfig.hasPipelineGroup(groupName)) return cruiseConfig.findGroup(groupName); else return null; } public Node getDependencyMaterialsFor(CaseInsensitiveString pipelineName) { if (getDependencies().containsKey(pipelineName)) { return getDependencies().get(pipelineName); } return new Node(new ArrayList<>()); } @Override public String toString() { return "ValidationContext{" + "immediateParent=" + immediateParent + ", parentContext=" + parentContext + '}'; } public MaterialConfigs getAllMaterialsByFingerPrint(String fingerprint) { initMaterialConfigMap(); return materialConfigsFingerprintMap.get(fingerprint); } public PipelineConfig getPipelineConfigByName(CaseInsensitiveString pipelineName) { try { return cruiseConfig.pipelineConfigByName(pipelineName); } catch (PipelineNotFoundException e) { return null; } } @Override public boolean shouldCheckConfigRepo() { return false; } @Override public SecurityConfig getServerSecurityConfig() { return cruiseConfig.server().security(); } public boolean doesTemplateExist(CaseInsensitiveString template) { return cruiseConfig.getTemplates().hasTemplateNamed(template); } @Override public SCM findScmById(String scmID) { return cruiseConfig.getSCMs().find(scmID); } @Override public PackageRepository findPackageById(String packageId) { return cruiseConfig.getPackageRepositories().findPackageRepositoryHaving(packageId); } public Set<CaseInsensitiveString> getPipelinesWithDependencyMaterials() { return getDependencies().keySet(); } private Hashtable<CaseInsensitiveString, Node> getDependencies() { if (dependencies == null) { dependencies = new Hashtable<>(); for (PipelineConfig pipeline : cruiseConfig.getAllPipelineConfigs()) { dependencies.put(pipeline.name(), pipeline.getDependenciesAsNode()); } } return dependencies; } private Hashtable<CaseInsensitiveString, Node> dependencies; public PipelineGroups getGroups() { return cruiseConfig.getGroups(); } public boolean isPipelineBeingCreated() { return isPipelineBeingCreated; } private void initMaterialConfigMap() { if (materialConfigsFingerprintMap == null) { materialConfigsFingerprintMap = new MaterialConfigFingerprintMap(cruiseConfig); } } private class MaterialConfigFingerprintMap { private Map<String, MaterialConfigs> map = new ConcurrentHashMap<>(); private Map<String, MaterialConfigs> pipelineMaterialMap = new ConcurrentHashMap<>(); public MaterialConfigFingerprintMap(CruiseConfig cruiseConfig) { for (PipelineConfigs group : cruiseConfig.getGroups()) { for (PipelineConfig pipelineConfig : group) { for (MaterialConfig material : pipelineConfig.materialConfigs()) { String fingerprint = material.getFingerprint(); if (fingerprint != null) { if (!map.containsKey(fingerprint)) { map.put(fingerprint, new MaterialConfigs()); } map.get(fingerprint).add(material); } if (!pipelineMaterialMap.containsKey(pipelineConfig.name().toString())) { pipelineMaterialMap.put(pipelineConfig.name().toString(), new MaterialConfigs()); } pipelineMaterialMap.get(pipelineConfig.name().toString()).add(material); } } } } public MaterialConfigs get(String fingerprint) { return map.get(fingerprint); } } @Override public boolean isValidProfileId(String profileId) { return this.cruiseConfig.server().getElasticConfig().getProfiles().find(profileId) != null; } @Override public boolean shouldNotCheckRole() { return isWithinTemplates(); } }