Optionally throw exception when a repository can't be read.
By default, an exception will be thrown. Fixes gh-661 Fixes gh-1712
This commit is contained in:
@@ -39,18 +39,20 @@ public class CompositeConfiguration {
|
||||
|
||||
private List<EnvironmentRepository> environmentRepos = new ArrayList<>();
|
||||
|
||||
private ConfigServerProperties properties;
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnBean(SearchPathLocator.class)
|
||||
public SearchPathCompositeEnvironmentRepository searchPathCompositeEnvironmentRepository() {
|
||||
return new SearchPathCompositeEnvironmentRepository(this.environmentRepos);
|
||||
return new SearchPathCompositeEnvironmentRepository(this.environmentRepos, properties.isFailOnCompositeError());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@ConditionalOnMissingBean(SearchPathLocator.class)
|
||||
public CompositeEnvironmentRepository compositeEnvironmentRepository() {
|
||||
return new CompositeEnvironmentRepository(this.environmentRepos);
|
||||
return new CompositeEnvironmentRepository(this.environmentRepos, properties.isFailOnCompositeError());
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@@ -58,4 +60,9 @@ public class CompositeConfiguration {
|
||||
this.environmentRepos = repos;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setProperties(ConfigServerProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,6 +73,17 @@ public class ConfigServerProperties {
|
||||
*/
|
||||
private String defaultProfile = "default";
|
||||
|
||||
/**
|
||||
* Flag indicating that if there are any errors reading properties from a subordinate
|
||||
* environment repository in a composite environment repository, then the entire
|
||||
* composite read should fail. Useful when set to false when a Vault repository is in
|
||||
* the composite to allow clients to still read properties from other repositories
|
||||
* without providing a valid Vault token.
|
||||
*
|
||||
* Defaults to true, resulting in a failure on any error.
|
||||
*/
|
||||
private boolean failOnCompositeError = true;
|
||||
|
||||
/**
|
||||
* Decryption configuration for when server handles encrypted properties before
|
||||
* sending them to clients.
|
||||
@@ -147,6 +158,14 @@ public class ConfigServerProperties {
|
||||
this.defaultProfile = defaultProfile;
|
||||
}
|
||||
|
||||
public boolean isFailOnCompositeError() {
|
||||
return failOnCompositeError;
|
||||
}
|
||||
|
||||
public void setFailOnCompositeError(boolean failOnCompositeError) {
|
||||
this.failOnCompositeError = failOnCompositeError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encryption properties.
|
||||
*/
|
||||
|
||||
@@ -453,16 +453,17 @@ class CompositeRepositoryConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnSearchPathLocator
|
||||
public SearchPathCompositeEnvironmentRepository searchPathCompositeEnvironmentRepository(
|
||||
List<EnvironmentRepository> environmentRepositories) {
|
||||
return new SearchPathCompositeEnvironmentRepository(environmentRepositories);
|
||||
List<EnvironmentRepository> environmentRepositories, ConfigServerProperties properties) {
|
||||
return new SearchPathCompositeEnvironmentRepository(environmentRepositories,
|
||||
properties.isFailOnCompositeError());
|
||||
}
|
||||
|
||||
@Primary
|
||||
@Bean
|
||||
@ConditionalOnMissingSearchPathLocator
|
||||
public CompositeEnvironmentRepository compositeEnvironmentRepository(
|
||||
List<EnvironmentRepository> environmentRepositories) {
|
||||
return new CompositeEnvironmentRepository(environmentRepositories);
|
||||
List<EnvironmentRepository> environmentRepositories, ConfigServerProperties properties) {
|
||||
return new CompositeEnvironmentRepository(environmentRepositories, properties.isFailOnCompositeError());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ package org.springframework.cloud.config.server.environment;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.core.OrderComparator;
|
||||
|
||||
@@ -30,18 +33,22 @@ import org.springframework.core.OrderComparator;
|
||||
*/
|
||||
public class CompositeEnvironmentRepository implements EnvironmentRepository {
|
||||
|
||||
Log log = LogFactory.getLog(getClass());
|
||||
|
||||
protected List<EnvironmentRepository> environmentRepositories;
|
||||
|
||||
private boolean failOnError;
|
||||
|
||||
/**
|
||||
* Creates a new {@link CompositeEnvironmentRepository}.
|
||||
* @param environmentRepositories The list of {@link EnvironmentRepository}s to create
|
||||
* the composite from.
|
||||
*/
|
||||
public CompositeEnvironmentRepository(
|
||||
List<EnvironmentRepository> environmentRepositories) {
|
||||
public CompositeEnvironmentRepository(List<EnvironmentRepository> environmentRepositories, boolean failOnError) {
|
||||
// Sort the environment repositories by the priority
|
||||
Collections.sort(environmentRepositories, OrderComparator.INSTANCE);
|
||||
this.environmentRepositories = environmentRepositories;
|
||||
this.failOnError = failOnError;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -63,8 +70,17 @@ public class CompositeEnvironmentRepository implements EnvironmentRepository {
|
||||
}
|
||||
else {
|
||||
for (EnvironmentRepository repo : environmentRepositories) {
|
||||
env.addAll(repo.findOne(application, profile, label, includeOrigin)
|
||||
.getPropertySources());
|
||||
try {
|
||||
env.addAll(repo.findOne(application, profile, label, includeOrigin).getPropertySources());
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (failOnError) {
|
||||
throw e;
|
||||
}
|
||||
else {
|
||||
log.info("Error adding environment for " + repo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return env;
|
||||
|
||||
@@ -33,9 +33,9 @@ public class SearchPathCompositeEnvironmentRepository
|
||||
* @param environmentRepositories The {@link EnvironmentRepository}s to create this
|
||||
* composite from.
|
||||
*/
|
||||
public SearchPathCompositeEnvironmentRepository(
|
||||
List<EnvironmentRepository> environmentRepositories) {
|
||||
super(environmentRepositories);
|
||||
public SearchPathCompositeEnvironmentRepository(List<EnvironmentRepository> environmentRepositories,
|
||||
boolean failOnError) {
|
||||
super(environmentRepositories, failOnError);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -76,8 +76,8 @@ public class CompositeEnvironmentRepositoryTests {
|
||||
repos.add(new TestOrderedEnvironmentRepository(3, e1, loc1));
|
||||
repos.add(new TestOrderedEnvironmentRepository(2, e3, loc2));
|
||||
repos.add(new TestOrderedEnvironmentRepository(1, e2, loc3));
|
||||
SearchPathCompositeEnvironmentRepository compositeRepo = new SearchPathCompositeEnvironmentRepository(
|
||||
repos);
|
||||
SearchPathCompositeEnvironmentRepository compositeRepo = new SearchPathCompositeEnvironmentRepository(repos,
|
||||
true);
|
||||
Environment compositeEnv = compositeRepo.findOne("foo", "bar", "world", false);
|
||||
List<PropertySource> propertySources = compositeEnv.getPropertySources();
|
||||
assertThat(propertySources.size()).isEqualTo(5);
|
||||
@@ -123,17 +123,16 @@ public class CompositeEnvironmentRepositoryTests {
|
||||
List<EnvironmentRepository> repos2 = new ArrayList<EnvironmentRepository>();
|
||||
repos2.add(new TestOrderedEnvironmentRepository(3, e1, loc1));
|
||||
repos2.add(new TestOrderedEnvironmentRepository(3, e2, loc2));
|
||||
SearchPathCompositeEnvironmentRepository compositeRepo = new SearchPathCompositeEnvironmentRepository(
|
||||
repos);
|
||||
SearchPathCompositeEnvironmentRepository compositeRepo = new SearchPathCompositeEnvironmentRepository(repos,
|
||||
true);
|
||||
SearchPathCompositeEnvironmentRepository multiCompositeRepo = new SearchPathCompositeEnvironmentRepository(
|
||||
repos2);
|
||||
repos2, true);
|
||||
Environment env = compositeRepo.findOne("app", "dev", "label", false);
|
||||
assertThat(env.getVersion()).isEqualTo("1");
|
||||
assertThat(env.getState()).isEqualTo("state");
|
||||
Environment multiEnv = multiCompositeRepo.findOne("app", "dev", "label", false);
|
||||
assertThat(multiEnv.getVersion()).isEqualTo(null);
|
||||
assertThat(multiEnv.getState()).isEqualTo(null);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -145,8 +144,39 @@ public class CompositeEnvironmentRepositoryTests {
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestOrderedEnvironmentRepository
|
||||
implements EnvironmentRepository, SearchPathLocator, Ordered {
|
||||
@Test
|
||||
public void testFailingSubordinateRepositorySkipped() {
|
||||
PropertySource p1 = mock(PropertySource.class);
|
||||
doReturn("p1").when(p1).getName();
|
||||
PropertySource p2 = mock(PropertySource.class);
|
||||
doReturn("p2").when(p2).getName();
|
||||
String sLoc1 = "loc1";
|
||||
String sLoc2 = "loc2";
|
||||
Environment e1 = new Environment("app", "dev");
|
||||
e1.add(p1);
|
||||
e1.setVersion("1");
|
||||
e1.setState("state");
|
||||
Environment e2 = new Environment("app", "dev");
|
||||
e2.add(p2);
|
||||
e2.setVersion("2");
|
||||
e2.setState("state2");
|
||||
SearchPathLocator.Locations loc1 = new SearchPathLocator.Locations("app", "dev", "label", "version",
|
||||
new String[] { sLoc1 });
|
||||
SearchPathLocator.Locations loc2 = new SearchPathLocator.Locations("app", "dev", "label", "version",
|
||||
new String[] { sLoc1, sLoc2 });
|
||||
List<EnvironmentRepository> repos = new ArrayList<EnvironmentRepository>();
|
||||
repos.add(new TestOrderedEnvironmentRepository(2, e1, loc1));
|
||||
repos.add(new TestFailingEnvironmentRepository(1, e2, loc2));
|
||||
|
||||
SearchPathCompositeEnvironmentRepository compositeRepo = new SearchPathCompositeEnvironmentRepository(repos,
|
||||
false);
|
||||
Environment env = compositeRepo.findOne("app", "dev", "label", false);
|
||||
List<PropertySource> propertySources = env.getPropertySources();
|
||||
assertThat(propertySources.size()).isEqualTo(1);
|
||||
assertThat(propertySources.get(0).getName()).isEqualTo("p1");
|
||||
}
|
||||
|
||||
private static class TestOrderedEnvironmentRepository implements EnvironmentRepository, SearchPathLocator, Ordered {
|
||||
|
||||
private Environment env;
|
||||
|
||||
@@ -184,15 +214,32 @@ public class CompositeEnvironmentRepositoryTests {
|
||||
|
||||
}
|
||||
|
||||
private static class TestFailingEnvironmentRepository extends TestOrderedEnvironmentRepository {
|
||||
|
||||
TestFailingEnvironmentRepository(int order, Environment env, Locations locations) {
|
||||
super(order, env, locations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Environment findOne(String application, String profile, String label, boolean includeOrigin) {
|
||||
throw new IllegalArgumentException("Failing for some reason");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Environment findOne(String application, String profile, String label) {
|
||||
throw new IllegalArgumentException("Failing for some reason");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class OverrideCompositeConfig {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
CompositeEnvironmentRepository customCompositeEnvironmentRepository() {
|
||||
return new CompositeEnvironmentRepository(Arrays
|
||||
.<EnvironmentRepository>asList(new TestOrderedEnvironmentRepository(1,
|
||||
new Environment("app", "dev"), null)));
|
||||
return new CompositeEnvironmentRepository(Arrays.<EnvironmentRepository>asList(
|
||||
new TestOrderedEnvironmentRepository(1, new Environment("app", "dev"), null)), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user