Skip to content

Commit

Permalink
fix(pipeline_template): Respect UI-configured concurrency options (#1599
Browse files Browse the repository at this point in the history
)
  • Loading branch information
robzienert authored Sep 6, 2017
1 parent 98fc206 commit c2a4d72
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private Map<String, Object> processInternal(Map<String, Object> pipeline) {
graphMutator.mutate(template);

ExecutionGenerator executionGenerator = new V1SchemaExecutionGenerator();
Map<String, Object> generatedPipeline = executionGenerator.generate(template, templateConfiguration, (String) pipeline.get("id"));
Map<String, Object> generatedPipeline = executionGenerator.generate(template, templateConfiguration, request);

return generatedPipeline;
}
Expand Down Expand Up @@ -163,56 +163,4 @@ private void setTemplateSourceWithJinja(TemplatedPipelineRequest request) {
RenderContext context = new DefaultRenderContext(request.getConfig().getPipeline().getApplication(), null, request.getTrigger());
request.getConfig().getPipeline().getTemplate().setSource(renderer.render(request.getConfig().getPipeline().getTemplate().getSource(), context ));
}

private static class TemplatedPipelineRequest {
String type;
Map<String, Object> trigger;
TemplateConfiguration config;
PipelineTemplate template;
Boolean plan = false;

public boolean isTemplatedPipelineRequest() {
return "templatedPipeline".equals(type);
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public TemplateConfiguration getConfig() {
return config;
}

public void setConfig(TemplateConfiguration config) {
this.config = config;
}

public Map<String, Object> getTrigger() {
return trigger;
}

public void setTrigger(Map<String, Object> trigger) {
this.trigger = trigger;
}

public PipelineTemplate getTemplate() {
return template;
}

public void setTemplate(PipelineTemplate template) {
this.template = template;
}

public Boolean getPlan() {
return plan;
}

public void setPlan(Boolean plan) {
this.plan = plan;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2017 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.pipelinetemplate;

import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.PipelineTemplate;
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.TemplateConfiguration;

import java.util.Map;

public class TemplatedPipelineRequest {
String id;
String type;
Map<String, Object> trigger;
TemplateConfiguration config;
PipelineTemplate template;
Boolean plan = false;
boolean limitConcurrent = true;
boolean keepWaitingPipelines = false;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public boolean isTemplatedPipelineRequest() {
return "templatedPipeline".equals(type);
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public TemplateConfiguration getConfig() {
return config;
}

public void setConfig(TemplateConfiguration config) {
this.config = config;
}

public Map<String, Object> getTrigger() {
return trigger;
}

public void setTrigger(Map<String, Object> trigger) {
this.trigger = trigger;
}

public PipelineTemplate getTemplate() {
return template;
}

public void setTemplate(PipelineTemplate template) {
this.template = template;
}

public Boolean getPlan() {
return plan;
}

public void setPlan(Boolean plan) {
this.plan = plan;
}

public boolean isLimitConcurrent() {
return limitConcurrent;
}

public boolean isKeepWaitingPipelines() {
return keepWaitingPipelines;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
*/
package com.netflix.spinnaker.orca.pipelinetemplate.generator;

import com.netflix.spinnaker.orca.pipelinetemplate.TemplatedPipelineRequest;
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.PipelineTemplate;
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.TemplateConfiguration;

import java.util.Map;

public interface ExecutionGenerator {

Map<String, Object> generate(PipelineTemplate template, TemplateConfiguration configuration, String id);
Map<String, Object> generate(PipelineTemplate template, TemplateConfiguration configuration, TemplatedPipelineRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,39 @@
*/
package com.netflix.spinnaker.orca.pipelinetemplate.v1schema;

import java.util.*;
import java.util.stream.Collectors;
import com.netflix.spinnaker.orca.pipelinetemplate.TemplatedPipelineRequest;
import com.netflix.spinnaker.orca.pipelinetemplate.generator.ExecutionGenerator;
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.PipelineTemplate;
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.PipelineTemplate.Configuration;
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.TemplateConfiguration;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

public class V1SchemaExecutionGenerator implements ExecutionGenerator {

@Override
public Map<String, Object> generate(PipelineTemplate template, TemplateConfiguration configuration, String id) {
public Map<String, Object> generate(PipelineTemplate template, TemplateConfiguration configuration, TemplatedPipelineRequest request) {
Map<String, Object> pipeline = new HashMap<>();
pipeline.put("id", Optional.ofNullable(id).orElse(Optional.ofNullable(configuration.getPipeline().getPipelineConfigId()).orElse("unknown")));
pipeline.put("id", Optional.ofNullable(request.getId()).orElse(Optional.ofNullable(configuration.getPipeline().getPipelineConfigId()).orElse("unknown")));
pipeline.put("application", configuration.getPipeline().getApplication());
pipeline.put("name", Optional.ofNullable(configuration.getPipeline().getName()).orElse("Unnamed Execution"));

if (configuration.getPipeline().getExecutionEngine() != null) {
pipeline.put("executionEngine", configuration.getPipeline().getExecutionEngine());
}

// TODO rz - Ehhhh
Configuration c = template.getConfiguration();
if (template.getConfiguration() == null) {
pipeline.put("limitConcurrent", true);
pipeline.put("keepWaitingPipelines", false);
if (c.getConcurrentExecutions().isEmpty()) {
pipeline.put("limitConcurrent", request.isLimitConcurrent());
pipeline.put("keepWaitingPipelines", request.isKeepWaitingPipelines());
} else {
pipeline.put("limitConcurrent", c.getConcurrentExecutions().getOrDefault("limitConcurrent", true));
pipeline.put("keepWaitingPipelines", c.getConcurrentExecutions().getOrDefault("keepWaitingPipelines", false));
pipeline.put("limitConcurrent", c.getConcurrentExecutions().getOrDefault("limitConcurrent", request.isLimitConcurrent()));
pipeline.put("keepWaitingPipelines", c.getConcurrentExecutions().getOrDefault("keepWaitingPipelines", request.isKeepWaitingPipelines()));
}

addNotifications(pipeline, template, configuration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import com.netflix.spinnaker.orca.pipelinetemplate.loader.TemplateLoader
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.PipelineTemplate
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.StageDefinition
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.TemplateConfiguration
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.render.DefaultRenderContext
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.render.JinjaRenderer
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.render.RenderUtil
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.render.Renderer
Expand All @@ -35,6 +34,7 @@ import org.yaml.snakeyaml.Yaml
import spock.lang.Specification
import spock.lang.Subject
import spock.lang.Unroll

import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals

class PipelineTemplatePipelinePreprocessorSpec extends Specification {
Expand Down Expand Up @@ -319,6 +319,33 @@ class PipelineTemplatePipelinePreprocessorSpec extends Specification {
result.stages*.group == ['my group of stages: wowow waiting', 'my group of stages: wowow waiting']
}

def "should respect request-defined concurrency options if configuration does not define them"() {
given:
def pipeline = [
type: 'templatedPipeline',
config: [
schema: '1',
pipeline: [
application: 'myapp'
]
],
template: [
schema: '1',
id: 'myTemplate',
configuration: [:],
stages: []
],
plan: true,
limitConcurrent: false
]

when:
def result = subject.process(pipeline)

then:
result.limitConcurrent == false
}

Map<String, Object> createTemplateRequest(String templatePath, Map<String, Object> variables = [:], List<Map<String, Object>> stages = [], boolean plan = false) {
return [
type: 'templatedPipeline',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.netflix.spinnaker.orca.pipelinetemplate.v1schema

import com.netflix.spinnaker.orca.pipelinetemplate.TemplatedPipelineRequest
import com.netflix.spinnaker.orca.pipelinetemplate.generator.ExecutionGenerator
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.NamedHashMap
import com.netflix.spinnaker.orca.pipelinetemplate.v1schema.model.PipelineTemplate
Expand Down Expand Up @@ -44,7 +45,7 @@ class V1SchemaExecutionGeneratorSpec extends Specification {
)

when:
def result = subject.generate(template, configuration, "124")
def result = subject.generate(template, configuration, new TemplatedPipelineRequest(id: "124"))

then:
noExceptionThrown()
Expand All @@ -69,7 +70,7 @@ class V1SchemaExecutionGeneratorSpec extends Specification {
)

when:
def result = subject.generate(template, configuration, pipelineId)
def result = subject.generate(template, configuration, new TemplatedPipelineRequest(id: pipelineId))

then:
result.id == expectedId
Expand Down Expand Up @@ -102,7 +103,7 @@ class V1SchemaExecutionGeneratorSpec extends Specification {
)

when:
def result = subject.generate(template, configuration, "pipelineConfigId")
def result = subject.generate(template, configuration, new TemplatedPipelineRequest(id: "pipelineConfigId"))

then:
result.notifications*.address == addresses
Expand Down

0 comments on commit c2a4d72

Please sign in to comment.