Repository: gocd/gocd
Issue: pipeline config API: cannot create pipeline with dependency on an upstream with a template

Pipeline "upstream" uses some template that has a stage called "run". 

Using the pipeline config API, try to create a pipeline "downstream" with a material that points to the upstream pipeline. 

```
"materials": [ some_git_repo, {"attributes": {"auto_update": true, "name": "upstream", "pipeline": "upstream", "stage": "run"}, "type": "dependency"}], 
```

I get the following error:

```
Validations failed for pipeline 'downstream'.... errors: pipeline: "Stage with name 'run' does not exist on pipeline 'upstream'"
```


Changed files:
server/src/com/thoughtworks/go/server/service/PipelineConfigService.java
server/test/integration/com/thoughtworks/go/server/service/PipelineConfigServiceIntegrationTest.java

diff --git a/server/src/com/thoughtworks/go/server/service/PipelineConfigService.java b/server/src/com/thoughtworks/go/server/service/PipelineConfigService.java
index a9821da177..d3e1e95df0 100644
--- a/server/src/com/thoughtworks/go/server/service/PipelineConfigService.java
+++ b/server/src/com/thoughtworks/go/server/service/PipelineConfigService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 ThoughtWorks, Inc.
+ * Copyright 2016 ThoughtWorks, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -184,7 +184,7 @@ public class PipelineConfigService implements PipelineConfigChangedListener, Ini
 
     @Override
     public void onConfigChange(CruiseConfig newCruiseConfig) {
-        PipelineConfigurationCache.getInstance().onConfigChange(goConfigService.getConfigForEditing());
+        PipelineConfigurationCache.getInstance().onConfigChange(goConfigService.cruiseConfig());
         if (goCache.get(GO_PIPELINE_CONFIGS_ETAGS_CACHE) != null) {
             goCache.remove(GO_PIPELINE_CONFIGS_ETAGS_CACHE);
         }
diff --git a/server/test/integration/com/thoughtworks/go/server/service/PipelineConfigServiceIntegrationTest.java b/server/test/integration/com/thoughtworks/go/server/service/PipelineConfigServiceIntegrationTest.java
index ad9f249ddd..6d5423aa56 100644
--- a/server/test/integration/com/thoughtworks/go/server/service/PipelineConfigServiceIntegrationTest.java
+++ b/server/test/integration/com/thoughtworks/go/server/service/PipelineConfigServiceIntegrationTest.java
@@ -51,6 +51,7 @@ import java.util.Arrays;
 import java.util.UUID;
 
 import static com.thoughtworks.go.util.TestUtils.contains;
+import static junit.framework.Assert.assertTrue;
 import static junit.framework.TestCase.assertFalse;
 import static org.hamcrest.core.Is.is;
 import static org.hamcrest.core.IsNot.not;
@@ -148,6 +149,49 @@ public class PipelineConfigServiceIntegrationTest {
         assertThat(configRepository.getCurrentRevision().getUsername(), is(user.getDisplayName()));
     }
 
+    @Test
+    public void shouldUpdatePipelineConfigWhenDependencyMaterialHasTemplateDefined() throws Exception {
+        CaseInsensitiveString templateName = new CaseInsensitiveString("template_with_param");
+        saveTemplateWithParamToConfig(templateName);
+
+        pipelineConfig.clear();
+        pipelineConfig.setTemplateName(templateName);
+        pipelineConfig.addParam(new ParamConfig("SOME_PARAM", "SOME_VALUE"));
+
+        CruiseConfig cruiseConfig = goConfigDao.loadConfigHolder().configForEdit;
+        cruiseConfig.update(groupName, pipelineConfig.name().toString(), pipelineConfig);
+        saveConfig(cruiseConfig);
+
+        PipelineConfig downstream = GoConfigMother.createPipelineConfigWithMaterialConfig("downstream", new DependencyMaterialConfig(pipelineConfig.name(), new CaseInsensitiveString("stage")));
+        pipelineConfigService.createPipelineConfig(user, downstream, result, groupName);
+
+        assertThat(result.toString(), result.isSuccessful(), is(true));
+        assertTrue(downstream.materialConfigs().first().errors().isEmpty());
+    }
+
+    @Test
+    public void shouldUpdatePipelineConfigWhenFetchTaskFromUpstreamHasPipelineWithTemplateDefined() throws Exception {
+        CaseInsensitiveString templateName = new CaseInsensitiveString("template_with_param");
+        saveTemplateWithParamToConfig(templateName);
+
+        pipelineConfig.clear();
+        pipelineConfig.setTemplateName(templateName);
+        pipelineConfig.addParam(new ParamConfig("SOME_PARAM", "SOME_VALUE"));
+
+        CaseInsensitiveString stage = new CaseInsensitiveString("stage");
+        CaseInsensitiveString job = new CaseInsensitiveString("job");
+        CruiseConfig cruiseConfig = goConfigDao.loadConfigHolder().configForEdit;
+        cruiseConfig.update(groupName, pipelineConfig.name().toString(), pipelineConfig);
+        saveConfig(cruiseConfig);
+
+        PipelineConfig downstream = GoConfigMother.createPipelineConfigWithMaterialConfig("downstream", new DependencyMaterialConfig(pipelineConfig.name(), stage));
+        downstream.getStage(stage).getJobs().first().addTask(new FetchTask(pipelineConfig.name(), stage, job, "src", "dest"));
+        pipelineConfigService.createPipelineConfig(user, downstream, result, groupName);
+
+        assertThat(result.toString(), result.isSuccessful(), is(true));
+        assertTrue(downstream.materialConfigs().first().errors().isEmpty());
+    }
+
     @Test
     public void shouldNotCreatePipelineConfigWhenAPipelineBySameNameAlreadyExists() throws GitAPIException {
         GoConfigHolder goConfigHolderBeforeUpdate = goConfigDao.loadConfigHolder();