From eb57c8df7b9a4b7a9f44ae57f5054303a0c9f74e Mon Sep 17 00:00:00 2001 From: Marcus Holl Date: Thu, 26 Sep 2019 12:23:36 +0200 Subject: [PATCH] Back commonPipelineEnvironment step by shared class (#821) * Back commonPipelineEnvironment step by shared class Each pipeline step comes with its own instance of a commonPipelineEnvironment. Properties stored on one instance was not shared with the other instances. Now we strip down the commonPipelineEnvironment step and forward basically everything to a shared singleton instance. With that approach all instances of commonPipelineEnvironment shares the same data and can now be really used for information exchange between the steps. Before that change only the commonPipelineEnvironment instance associated with the pipeline script itself could be used for that purpose. * Remove unneeded commented line --- .../piper/CommonPipelineEnvironment.groovy | 154 ++++++++++++++++++ .../util/JenkinsResetDefaultCacheRule.groovy | 2 + vars/commonPipelineEnvironment.groovy | 148 ++--------------- 3 files changed, 171 insertions(+), 133 deletions(-) create mode 100644 src/com/sap/piper/CommonPipelineEnvironment.groovy diff --git a/src/com/sap/piper/CommonPipelineEnvironment.groovy b/src/com/sap/piper/CommonPipelineEnvironment.groovy new file mode 100644 index 000000000..655c245c8 --- /dev/null +++ b/src/com/sap/piper/CommonPipelineEnvironment.groovy @@ -0,0 +1,154 @@ +package com.sap.piper; + +import com.sap.piper.analytics.InfluxData + +public class CommonPipelineEnvironment { + + private static CommonPipelineEnvironment INSTANCE = new CommonPipelineEnvironment() + + static CommonPipelineEnvironment getInstance() { + INSTANCE + } + + Map defaultConfiguration = [:] + + // The project config + Map configuration = [:] + + private Map valueMap = [:] + + //stores properties for a pipeline which build an artifact and then bundles it into a container + private Map appContainerProperties = [:] + + //stores version of the artifact which is build during pipeline run + def artifactVersion + + //Stores the current buildResult + String buildResult = 'SUCCESS' + + //stores the gitCommitId as well as additional git information for the build during pipeline run + String gitCommitId + String gitCommitMessage + String gitSshUrl + String gitHttpsUrl + String gitBranch + + //GiutHub specific information + String githubOrg + String githubRepo + + String mtarFilePath + + String changeDocumentId + + String xsDeploymentId + + void setValue(String property, value) { + valueMap[property] = value + } + + def getValue(String property) { + return valueMap.get(property) + } + + def setAppContainerProperty(property, value) { + appContainerProperties[property] = value + } + + def getAppContainerProperty(property) { + return appContainerProperties[property] + } + + // goes into measurement jenkins_custom_data + def setInfluxCustomDataEntry(key, value) { + InfluxData.addField('jenkins_custom_data', key, value) + } + // goes into measurement jenkins_custom_data + @Deprecated // not used in library + def getInfluxCustomData() { + return InfluxData.getInstance().getFields().jenkins_custom_data + } + + // goes into measurement jenkins_custom_data + def setInfluxCustomDataTagsEntry(key, value) { + InfluxData.addTag('jenkins_custom_data', key, value) + } + // goes into measurement jenkins_custom_data + @Deprecated // not used in library + def getInfluxCustomDataTags() { + return InfluxData.getInstance().getTags().jenkins_custom_data + } + + void setInfluxCustomDataMapEntry(measurement, field, value) { + InfluxData.addField(measurement, field, value) + } + @Deprecated // not used in library + def getInfluxCustomDataMap() { + return InfluxData.getInstance().getFields() + } + + def setInfluxCustomDataMapTagsEntry(measurement, tag, value) { + InfluxData.addTag(measurement, tag, value) + } + @Deprecated // not used in library + def getInfluxCustomDataMapTags() { + return InfluxData.getInstance().getTags() + } + + @Deprecated // not used in library + def setInfluxStepData(key, value) { + InfluxData.addField('step_data', key, value) + } + @Deprecated // not used in library + def getInfluxStepData(key) { + return InfluxData.getInstance().getFields()['step_data'][key] + } + + @Deprecated // not used in library + def setInfluxPipelineData(key, value) { + InfluxData.addField('pipeline_data', key, value) + } + @Deprecated // not used in library + def setPipelineMeasurement(key, value){ + setInfluxPipelineData(key, value) + } + @Deprecated // not used in library + def getPipelineMeasurement(key) { + return InfluxData.getInstance().getFields()['pipeline_data'][key] + } + + def reset() { + appContainerProperties = [:] + configuration = [:] + artifactVersion = null + + gitCommitId = null + gitCommitMessage = null + gitSshUrl = null + gitHttpsUrl = null + gitBranch = null + + githubOrg = null + githubRepo = null + + mtarFilePath = null + valueMap = [:] + + changeDocumentId = null + + InfluxData.reset() + } + + Map getStepConfiguration(stepName, stageName = env.STAGE_NAME, includeDefaults = true) { + Map defaults = [:] + if (includeDefaults) { + defaults = DefaultValueCache.getInstance()?.getDefaultValues()?.general ?: [:] + defaults = ConfigurationMerger.merge(ConfigurationLoader.defaultStepConfiguration([commonPipelineEnvironment: this], stepName), null, defaults) + defaults = ConfigurationMerger.merge(ConfigurationLoader.defaultStageConfiguration([commonPipelineEnvironment: this], stageName), null, defaults) + } + Map config = ConfigurationMerger.merge(configuration.get('general') ?: [:], null, defaults) + config = ConfigurationMerger.merge(configuration.get('steps')?.get(stepName) ?: [:], null, config) + config = ConfigurationMerger.merge(configuration.get('stages')?.get(stageName) ?: [:], null, config) + return config + } +} diff --git a/test/groovy/util/JenkinsResetDefaultCacheRule.groovy b/test/groovy/util/JenkinsResetDefaultCacheRule.groovy index 680e2fc93..301c29b13 100644 --- a/test/groovy/util/JenkinsResetDefaultCacheRule.groovy +++ b/test/groovy/util/JenkinsResetDefaultCacheRule.groovy @@ -6,6 +6,7 @@ import org.junit.runners.model.Statement import com.lesfurets.jenkins.unit.BasePipelineTest import com.sap.piper.DefaultValueCache +import com.sap.piper.CommonPipelineEnvironment class JenkinsResetDefaultCacheRule implements TestRule { @@ -27,6 +28,7 @@ class JenkinsResetDefaultCacheRule implements TestRule { @Override void evaluate() throws Throwable { DefaultValueCache.reset() + CommonPipelineEnvironment.getInstance().reset() base.evaluate() } } diff --git a/vars/commonPipelineEnvironment.groovy b/vars/commonPipelineEnvironment.groovy index a0ec24150..49b12f0b5 100644 --- a/vars/commonPipelineEnvironment.groovy +++ b/vars/commonPipelineEnvironment.groovy @@ -1,146 +1,28 @@ import com.sap.piper.ConfigurationLoader import com.sap.piper.ConfigurationMerger +import com.sap.piper.CommonPipelineEnvironment import com.sap.piper.analytics.InfluxData class commonPipelineEnvironment implements Serializable { - //stores version of the artifact which is build during pipeline run - def artifactVersion + // We forward everything to the singleton instance of + // commonPipelineEnvironment (CPE) on default value cache. + // + // Some background: each step has its own instance of CPE step. + // In case each instance has its own set of properties these instances + // are configured individually. Properties set on one instance cannot be + // retrieved with another instance. Now each instance forwards to one singleton. + // This means: all instances of the CPE shares the same properties/configuration. - //Stores the current buildResult - String buildResult = 'SUCCESS' - - //stores the gitCommitId as well as additional git information for the build during pipeline run - String gitCommitId - String gitCommitMessage - String gitSshUrl - String gitHttpsUrl - String gitBranch - - String xsDeploymentId - - //GiutHub specific information - String githubOrg - String githubRepo - - //stores properties for a pipeline which build an artifact and then bundles it into a container - private Map appContainerProperties = [:] - - Map configuration = [:] - Map defaultConfiguration = [:] - - String mtarFilePath - private Map valueMap = [:] - - void setValue(String property, value) { - valueMap[property] = value + def methodMissing(String name, def args) { + CommonPipelineEnvironment.getInstance().invokeMethod(name, args) } - def getValue(String property) { - return valueMap.get(property) + def propertyMissing(def name) { + CommonPipelineEnvironment.getInstance()[name] } - String changeDocumentId - - def reset() { - appContainerProperties = [:] - artifactVersion = null - - configuration = [:] - - gitCommitId = null - gitCommitMessage = null - gitSshUrl = null - gitHttpsUrl = null - gitBranch = null - - githubOrg = null - githubRepo = null - - mtarFilePath = null - valueMap = [:] - - changeDocumentId = null - - InfluxData.reset() - } - - def setAppContainerProperty(property, value) { - appContainerProperties[property] = value - } - - def getAppContainerProperty(property) { - return appContainerProperties[property] - } - - // goes into measurement jenkins_custom_data - def setInfluxCustomDataEntry(key, value) { - InfluxData.addField('jenkins_custom_data', key, value) - } - // goes into measurement jenkins_custom_data - @Deprecated // not used in library - def getInfluxCustomData() { - return InfluxData.getInstance().getFields().jenkins_custom_data - } - - // goes into measurement jenkins_custom_data - def setInfluxCustomDataTagsEntry(key, value) { - InfluxData.addTag('jenkins_custom_data', key, value) - } - // goes into measurement jenkins_custom_data - @Deprecated // not used in library - def getInfluxCustomDataTags() { - return InfluxData.getInstance().getTags().jenkins_custom_data - } - - void setInfluxCustomDataMapEntry(measurement, field, value) { - InfluxData.addField(measurement, field, value) - } - @Deprecated // not used in library - def getInfluxCustomDataMap() { - return InfluxData.getInstance().getFields() - } - - def setInfluxCustomDataMapTagsEntry(measurement, tag, value) { - InfluxData.addTag(measurement, tag, value) - } - @Deprecated // not used in library - def getInfluxCustomDataMapTags() { - return InfluxData.getInstance().getTags() - } - - @Deprecated // not used in library - def setInfluxStepData(key, value) { - InfluxData.addField('step_data', key, value) - } - @Deprecated // not used in library - def getInfluxStepData(key) { - return InfluxData.getInstance().getFields()['step_data'][key] - } - - @Deprecated // not used in library - def setInfluxPipelineData(key, value) { - InfluxData.addField('pipeline_data', key, value) - } - @Deprecated // not used in library - def setPipelineMeasurement(key, value){ - setInfluxPipelineData(key, value) - } - @Deprecated // not used in library - def getPipelineMeasurement(key) { - return InfluxData.getInstance().getFields()['pipeline_data'][key] - } - - Map getStepConfiguration(stepName, stageName = env.STAGE_NAME, includeDefaults = true) { - Map defaults = [:] - if (includeDefaults) { - defaults = ConfigurationLoader.defaultGeneralConfiguration() - defaults = ConfigurationMerger.merge(ConfigurationLoader.defaultStepConfiguration(null, stepName), null, defaults) - defaults = ConfigurationMerger.merge(ConfigurationLoader.defaultStageConfiguration(null, stageName), null, defaults) - } - Map config = ConfigurationMerger.merge(configuration.get('general') ?: [:], null, defaults) - config = ConfigurationMerger.merge(configuration.get('steps')?.get(stepName) ?: [:], null, config) - config = ConfigurationMerger.merge(configuration.get('stages')?.get(stageName) ?: [:], null, config) - return config + def propertyMissing(def name, def value) { + CommonPipelineEnvironment.getInstance()[name] = value } }