<commit_before>/*
 * Copyright 2015 Netflix, 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.netflix.spinnaker.orca.pipeline.util

import com.fasterxml.jackson.databind.ObjectMapper
import com.netflix.spinnaker.orca.ExecutionStatus
import com.netflix.spinnaker.orca.config.UserConfiguredUrlRestrictions
import com.netflix.spinnaker.orca.pipeline.model.Pipeline
import com.netflix.spinnaker.orca.pipeline.model.Stage
import groovy.transform.PackageScope
import org.springframework.expression.AccessException
import org.springframework.expression.EvaluationContext
import org.springframework.expression.EvaluationException
import org.springframework.expression.Expression
import org.springframework.expression.ExpressionParser
import org.springframework.expression.ParserContext
import org.springframework.expression.TypeLocator
import org.springframework.expression.TypedValue
import org.springframework.expression.common.TemplateParserContext
import org.springframework.expression.spel.SpelEvaluationException
import org.springframework.expression.spel.SpelMessage
import org.springframework.expression.spel.standard.SpelExpressionParser
import org.springframework.expression.spel.support.ReflectiveMethodResolver
import org.springframework.expression.spel.support.ReflectivePropertyAccessor
import org.springframework.expression.spel.support.StandardEvaluationContext
import org.springframework.expression.spel.support.StandardTypeLocator

import java.lang.reflect.Method
import java.text.SimpleDateFormat
import java.util.concurrent.atomic.AtomicReference

/**
 * Common methods for dealing with passing context parameters used by both Script and Jenkins stages
 */
class ContextParameterProcessor {

  // uses $ instead of  #
  private final ParserContext parserContext = new TemplateParserContext('${', '}')

  private final MapPropertyAccessor allowUnknownKeysAccessor = new MapPropertyAccessor(true)
  private final MapPropertyAccessor requireKeysAccessor = new MapPropertyAccessor(false)

  private final ExpressionParser parser = new SpelExpressionParser()

  private final ContextFunctionConfiguration contextFunctionConfiguration

  ContextParameterProcessor() {
    this(new ContextFunctionConfiguration(new UserConfiguredUrlRestrictions.Builder().build()))
  }

  ContextParameterProcessor(ContextFunctionConfiguration contextFunctionConfiguration) {
    this.contextFunctionConfiguration = contextFunctionConfiguration
    //this sucks so much:
    ContextUtilities.contextFunctionConfiguration.set(contextFunctionConfiguration)
  }

  Map process(Map parameters, Map context, boolean allowUnknownKeys) {
    if (!parameters) {
      return null
    }

    transform(parameters, precomputeValues(context), allowUnknownKeys)
  }

  Map<String, Object> buildExecutionContext(Stage stage, boolean includeStageContext) {
    def augmentedContext = [:] + (includeStageContext ? stage.context : [:])
    if (stage.execution instanceof Pipeline) {
      augmentedContext.put('trigger', ((Pipeline) stage.execution).trigger)
      augmentedContext.put('execution', stage.execution)
    }

    return augmentedContext
  }

  boolean containsExpression(String value) {
    return value?.contains(parserContext.getExpressionPrefix())
  }

  Map precomputeValues(Map context) {

    if (context.trigger?.parameters) {
      context.parameters = context.trigger.parameters
    }

    context.scmInfo = context.buildInfo?.scm ?: context.trigger?.buildInfo?.scm ?: null
    if (context.scmInfo && context.scmInfo.size() >= 2) {
      def scmInfo = context.scmInfo.find { it.branch != 'master' && it.branch != 'develop' }
      context.scmInfo = scmInfo ?: context.scmInfo?.first()
    } else {
      context.scmInfo = context.scmInfo?.first()
    }

    if (context.execution) {
      def deployedServerGroups = []
      context.execution.stages.findAll {
        it.type in ['deploy', 'cloneServerGroup', 'rollingPush'] && it.status == ExecutionStatus.SUCCEEDED
      }.each { deployStage ->
        if (deployStage.context.'deploy.server.groups') {
          Map deployDetails = [
            account    : deployStage.context.account,<commit_msg>fix(expressions): recognize deployedServerGroups from createServerGroup stages<commit_after>/*
 * Copyright 2015 Netflix, 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.netflix.spinnaker.orca.pipeline.util

import java.lang.reflect.Method
import java.text.SimpleDateFormat
import java.util.concurrent.atomic.AtomicReference
import com.fasterxml.jackson.databind.ObjectMapper
import com.netflix.spinnaker.orca.ExecutionStatus
import com.netflix.spinnaker.orca.config.UserConfiguredUrlRestrictions
import com.netflix.spinnaker.orca.pipeline.model.Pipeline
import com.netflix.spinnaker.orca.pipeline.model.Stage
import groovy.transform.PackageScope
import org.springframework.expression.*
import org.springframework.expression.common.TemplateParserContext
import org.springframework.expression.spel.SpelEvaluationException
import org.springframework.expression.spel.SpelMessage
import org.springframework.expression.spel.standard.SpelExpressionParser
import org.springframework.expression.spel.support.ReflectiveMethodResolver
import org.springframework.expression.spel.support.ReflectivePropertyAccessor
import org.springframework.expression.spel.support.StandardEvaluationContext
import org.springframework.expression.spel.support.StandardTypeLocator

/**
 * Common methods for dealing with passing context parameters used by both Script and Jenkins stages
 */
class ContextParameterProcessor {

  // uses $ instead of  #
  private final ParserContext parserContext = new TemplateParserContext('${', '}')

  private final MapPropertyAccessor allowUnknownKeysAccessor = new MapPropertyAccessor(true)
  private final MapPropertyAccessor requireKeysAccessor = new MapPropertyAccessor(false)

  private final ExpressionParser parser = new SpelExpressionParser()

  private final ContextFunctionConfiguration contextFunctionConfiguration

  ContextParameterProcessor() {
    this(new ContextFunctionConfiguration(new UserConfiguredUrlRestrictions.Builder().build()))
  }

  ContextParameterProcessor(ContextFunctionConfiguration contextFunctionConfiguration) {
    this.contextFunctionConfiguration = contextFunctionConfiguration
    //this sucks so much:
    ContextUtilities.contextFunctionConfiguration.set(contextFunctionConfiguration)
  }

  Map process(Map parameters, Map context, boolean allowUnknownKeys) {
    if (!parameters) {
      return null
    }

    transform(parameters, precomputeValues(context), allowUnknownKeys)
  }

  Map<String, Object> buildExecutionContext(Stage stage, boolean includeStageContext) {
    def augmentedContext = [:] + (includeStageContext ? stage.context : [:])
    if (stage.execution instanceof Pipeline) {
      augmentedContext.put('trigger', ((Pipeline) stage.execution).trigger)
      augmentedContext.put('execution', stage.execution)
    }

    return augmentedContext
  }

  boolean containsExpression(String value) {
    return value?.contains(parserContext.getExpressionPrefix())
  }

  Map precomputeValues(Map context) {

    if (context.trigger?.parameters) {
      context.parameters = context.trigger.parameters
    }

    context.scmInfo = context.buildInfo?.scm ?: context.trigger?.buildInfo?.scm ?: null
    if (context.scmInfo && context.scmInfo.size() >= 2) {
      def scmInfo = context.scmInfo.find { it.branch != 'master' && it.branch != 'develop' }
      context.scmInfo = scmInfo ?: context.scmInfo?.first()
    } else {
      context.scmInfo = context.scmInfo?.first()
    }

    if (context.execution) {
      def deployedServerGroups = []
      context.execution.stages.findAll {
        it.type in ['deploy', 'createServerGroup', 'cloneServerGroup', 'rollingPush'] && it.status == ExecutionStatus.SUCCEEDED
      }.each { deployStage ->
        if (deployStage.context.'deploy.server.groups') {
          Map deployDetails = [
            account    : deployStage.context.account,
{'fraction_non_alphanumeric': 0.08725425226419262, 'fraction_numerical': 0.0019880715705765406, 'mean_word_length': 4.8381689232753065, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3878363', 'n_tokens_mistral': 2332, 'n_tokens_neox': 2254, 'n_words': 559}