Merge branch '2.2.x'
This commit is contained in:
@@ -39,18 +39,22 @@ 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 +62,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.
|
||||
*/
|
||||
|
||||
@@ -429,16 +429,20 @@ 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,17 +33,23 @@ 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.
|
||||
* @param failOnError whether to throw an exception if there is an error.
|
||||
*/
|
||||
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
|
||||
@@ -61,6 +70,15 @@ public class CompositeEnvironmentRepository implements EnvironmentRepository {
|
||||
else {
|
||||
for (EnvironmentRepository repo : environmentRepositories) {
|
||||
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;
|
||||
|
||||
@@ -40,6 +40,11 @@ public class JdbcEnvironmentProperties implements EnvironmentRepositoryPropertie
|
||||
/** SQL used to query database for keys and values. */
|
||||
private String sql = DEFAULT_SQL;
|
||||
|
||||
/**
|
||||
* Flag to determine how to handle query exceptions.
|
||||
*/
|
||||
private boolean failOnError = true;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
@@ -65,4 +70,12 @@ public class JdbcEnvironmentProperties implements EnvironmentRepositoryPropertie
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public boolean isFailOnError() {
|
||||
return failOnError;
|
||||
}
|
||||
|
||||
public void setFailOnError(boolean failOnError) {
|
||||
this.failOnError = failOnError;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.cloud.config.environment.PropertySource;
|
||||
import org.springframework.core.Ordered;
|
||||
@@ -50,6 +53,8 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class JdbcEnvironmentRepository implements EnvironmentRepository, Ordered {
|
||||
|
||||
private static Log logger = LogFactory.getLog(JdbcEnvironmentRepository.class);
|
||||
|
||||
private final JdbcTemplate jdbc;
|
||||
|
||||
private final PropertiesResultSetExtractor extractor = new PropertiesResultSetExtractor();
|
||||
@@ -58,10 +63,13 @@ public class JdbcEnvironmentRepository implements EnvironmentRepository, Ordered
|
||||
|
||||
private String sql;
|
||||
|
||||
private boolean failOnError;
|
||||
|
||||
public JdbcEnvironmentRepository(JdbcTemplate jdbc, JdbcEnvironmentProperties properties) {
|
||||
this.jdbc = jdbc;
|
||||
this.order = properties.getOrder();
|
||||
this.sql = properties.getSql();
|
||||
this.failOnError = properties.isFailOnError();
|
||||
}
|
||||
|
||||
public String getSql() {
|
||||
@@ -96,10 +104,24 @@ public class JdbcEnvironmentRepository implements EnvironmentRepository, Ordered
|
||||
Collections.reverse(envs);
|
||||
for (String app : applications) {
|
||||
for (String env : envs) {
|
||||
Map<String, String> next = (Map<String, String>) this.jdbc.query(this.sql,
|
||||
new Object[] { app, env, label }, this.extractor);
|
||||
if (!next.isEmpty()) {
|
||||
environment.add(new PropertySource(app + "-" + env, next));
|
||||
try {
|
||||
Map<String, String> next = (Map<String, String>) this.jdbc.query(
|
||||
this.sql, new Object[] { app, env, label }, this.extractor);
|
||||
if (!next.isEmpty()) {
|
||||
environment.add(new PropertySource(app + "-" + env, next));
|
||||
}
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
if (!failOnError) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Failed to retrieve configuration from JDBC Repository",
|
||||
e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,6 +137,14 @@ public class JdbcEnvironmentRepository implements EnvironmentRepository, Ordered
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public boolean isFailOnError() {
|
||||
return failOnError;
|
||||
}
|
||||
|
||||
public void setFailOnError(boolean failOnError) {
|
||||
this.failOnError = failOnError;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PropertiesResultSetExtractor implements ResultSetExtractor<Map<String, String>> {
|
||||
|
||||
@@ -32,9 +32,10 @@ public class SearchPathCompositeEnvironmentRepository extends CompositeEnvironme
|
||||
* Creates a new {@link SearchPathCompositeEnvironmentRepository}.
|
||||
* @param environmentRepositories The {@link EnvironmentRepository}s to create this
|
||||
* composite from.
|
||||
* @param failOnError whether to throw an exception if there is an error.
|
||||
*/
|
||||
public SearchPathCompositeEnvironmentRepository(List<EnvironmentRepository> environmentRepositories) {
|
||||
super(environmentRepositories);
|
||||
public SearchPathCompositeEnvironmentRepository(List<EnvironmentRepository> environmentRepositories, boolean failOnError) {
|
||||
super(environmentRepositories, failOnError);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -76,7 +76,7 @@ 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);
|
||||
@@ -121,16 +121,15 @@ 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
|
||||
@@ -142,6 +141,38 @@ public class CompositeEnvironmentRepositoryTests {
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
@@ -178,6 +209,27 @@ 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 {
|
||||
|
||||
@@ -185,7 +237,7 @@ public class CompositeEnvironmentRepositoryTests {
|
||||
@Primary
|
||||
CompositeEnvironmentRepository customCompositeEnvironmentRepository() {
|
||||
return new CompositeEnvironmentRepository(Arrays.<EnvironmentRepository>asList(
|
||||
new TestOrderedEnvironmentRepository(1, new Environment("app", "dev"), null)));
|
||||
new TestOrderedEnvironmentRepository(1, new Environment("app", "dev"), null)), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user