Disable config server client by default in config server
This change adds a listener that inserts a PropertySource really early so that spring.cloud.config.enabled=false is the default in a config server. It can be overridden if the user primes the Environment with spring.cloud.config.enabled=true. See gh-104
This commit is contained in:
@@ -130,7 +130,6 @@ public class PropertySourceBootstrapConfiguration implements
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "spring.cloud.config.enabled", matchIfMissing = true)
|
||||
protected static class PropertySourceLocatorConfiguration {
|
||||
|
||||
@Autowired
|
||||
@@ -143,6 +142,7 @@ public class PropertySourceBootstrapConfiguration implements
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "spring.cloud.config.enabled", matchIfMissing = true)
|
||||
public ConfigServicePropertySourceLocator configServicePropertySource() {
|
||||
ConfigServicePropertySourceLocator locator = new ConfigServicePropertySourceLocator(
|
||||
configClientProperties());
|
||||
|
||||
@@ -34,14 +34,15 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
public class ConfigClientProperties {
|
||||
|
||||
public static final String PREFIX = "spring.cloud.config";
|
||||
|
||||
|
||||
/**
|
||||
* Flag to say that remote configuration is enabled. Default true;
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* The default profile to use when fetching remote configuration (comma-separated). Default is "default".
|
||||
* The default profile to use when fetching remote configuration (comma-separated).
|
||||
* Default is "default".
|
||||
*/
|
||||
private String profile = "default";
|
||||
|
||||
@@ -59,7 +60,7 @@ public class ConfigClientProperties {
|
||||
private Discovery discovery = new Discovery();
|
||||
|
||||
private boolean failFast = false;
|
||||
|
||||
|
||||
private ConfigClientProperties() {
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ public class ConfigClientProperties {
|
||||
public String getRawUri() {
|
||||
return extractCredentials()[2];
|
||||
}
|
||||
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
@@ -225,19 +226,22 @@ public class ConfigClientProperties {
|
||||
+ ConfigClientProperties.PREFIX
|
||||
+ ".name:${spring.application.name:application}}"));
|
||||
if (environment.containsProperty(ConfigClientProperties.PREFIX + ".profile")) {
|
||||
override.setProfile(environment.getProperty(ConfigClientProperties.PREFIX + ".profile"));
|
||||
override.setProfile(environment.getProperty(ConfigClientProperties.PREFIX
|
||||
+ ".profile"));
|
||||
}
|
||||
if (environment.containsProperty(ConfigClientProperties.PREFIX + ".label")) {
|
||||
override.setLabel(environment.getProperty(ConfigClientProperties.PREFIX + ".label"));
|
||||
override.setLabel(environment.getProperty(ConfigClientProperties.PREFIX
|
||||
+ ".label"));
|
||||
}
|
||||
return override;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConfigClientProperties [name=" + name + ", env=" + profile + ", label="
|
||||
+ label + ", uri=" + uri + ", discovery.enabled=" + discovery.enabled
|
||||
+ ", failFast="+ failFast + "]";
|
||||
return "ConfigClientProperties [enabled=" + enabled + ", profile=" + profile
|
||||
+ ", name=" + name + ", label=" + label + ", username=" + username
|
||||
+ ", password=" + password + ", uri=" + uri + ", discovery.enabled="
|
||||
+ discovery.enabled + ", failFast=" + failFast + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2014-2015 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.cloud.config.server;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
|
||||
/**
|
||||
* Normally you don't want the config server to be a config client itself, so this
|
||||
* listener disables the config client unless <code>spring.cloud.config.enabled</code> is
|
||||
* explicitly "true". It has to be "true" at the time this listener is fired, which means
|
||||
* <b>before</b> the <code>bootstrap.yml</code> is parsed, which in turn means to you need
|
||||
* to launch the application with an existing primed {@link Environment} (e.g. via System
|
||||
* properties or a {@link SpringApplicationBuilder}). This is the same rule of precedence
|
||||
* as for anything else affecting the bootstrap process itself, e.g. setting
|
||||
* <code>spring.cloud.bootstrap.name</code> to something other than "bootstrap".
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class ConfigServerBootstrapApplicationListener implements
|
||||
ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
|
||||
|
||||
public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 4;
|
||||
|
||||
private int order = DEFAULT_ORDER;
|
||||
|
||||
private PropertySource<?> propertySource = new MapPropertySource(
|
||||
"configServerClient", Collections.<String, Object> singletonMap(
|
||||
"spring.cloud.config.enabled", "false"));
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
|
||||
ConfigurableEnvironment environment = event.getEnvironment();
|
||||
if (!environment.resolvePlaceholders("${spring.cloud.config.enabled:false}")
|
||||
.equalsIgnoreCase("true")) {
|
||||
if (!environment.getPropertySources().contains(propertySource.getName())) {
|
||||
environment.getPropertySources().addLast(propertySource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,21 +32,25 @@ import org.springframework.context.annotation.Import;
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@ConditionalOnProperty("spring.cloud.config.server.bootstrap")
|
||||
@Configuration
|
||||
@Import(ConfigServerConfiguration.class)
|
||||
public class ConfigServerBootstrapConfiguration {
|
||||
|
||||
@Autowired
|
||||
private EnvironmentRepository repository;
|
||||
@ConditionalOnProperty("spring.cloud.config.server.bootstrap")
|
||||
@Import(ConfigServerConfiguration.class)
|
||||
protected static class LocalPropertySourceLocatorConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ConfigClientProperties client;
|
||||
@Autowired
|
||||
private EnvironmentRepository repository;
|
||||
|
||||
@Autowired
|
||||
private ConfigClientProperties client;
|
||||
|
||||
@Bean
|
||||
public EnvironmentRepositoryPropertySourceLocator environmentRepositoryPropertySourceLocator() {
|
||||
return new EnvironmentRepositoryPropertySourceLocator(repository,
|
||||
client.getName(), client.getProfile(), client.getLabel());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EnvironmentRepositoryPropertySourceLocator environmentRepositoryPropertySourceLocator() {
|
||||
return new EnvironmentRepositoryPropertySourceLocator(repository,
|
||||
client.getName(), client.getProfile(), client.getLabel());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Bootstrap components
|
||||
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
|
||||
org.springframework.cloud.config.server.ConfigServerBootstrapConfiguration
|
||||
org.springframework.cloud.config.server.ConfigServerBootstrapConfiguration
|
||||
|
||||
# Application listeners
|
||||
org.springframework.context.ApplicationListener=\
|
||||
org.springframework.cloud.config.server.ConfigServerBootstrapApplicationListener
|
||||
|
||||
@@ -21,8 +21,7 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = ConfigServerApplication.class)
|
||||
@IntegrationTest({ "debug", "server.port:0",
|
||||
"spring.cloud.bootstrap.name:enable-bootstrap" })
|
||||
@IntegrationTest({ "server.port:0", "spring.cloud.bootstrap.name:enable-bootstrap" })
|
||||
@WebAppConfiguration
|
||||
@ActiveProfiles("test")
|
||||
public class BootstrapConfigServerIntegrationTests {
|
||||
@@ -43,8 +42,8 @@ public class BootstrapConfigServerIntegrationTests {
|
||||
Environment environment = new TestRestTemplate().getForObject("http://localhost:"
|
||||
+ port + "/foo/development/", Environment.class);
|
||||
assertFalse(environment.getPropertySources().isEmpty());
|
||||
assertEquals("bar", environment.getPropertySources().get(0)
|
||||
.getSource().get("info.foo"));
|
||||
assertEquals("bar",
|
||||
environment.getPropertySources().get(0).getSource().get("info.foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.springframework.cloud.config.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.TestRestTemplate;
|
||||
import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator;
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.cloud.config.server.ConfigClientOffIntegrationTests.TestConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = TestConfiguration.class)
|
||||
@IntegrationTest("server.port:0")
|
||||
@WebAppConfiguration
|
||||
@ActiveProfiles("test")
|
||||
public class ConfigClientOffIntegrationTests {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws IOException {
|
||||
ConfigServerTestUtils.prepareLocalRepo();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
Environment environment = new TestRestTemplate().getForObject("http://localhost:"
|
||||
+ port + "/foo/development/", Environment.class);
|
||||
assertTrue(environment.getPropertySources().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configClientDisabled() throws Exception {
|
||||
assertEquals(0, BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,
|
||||
ConfigServicePropertySourceLocator.class).length);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(ConfigServerApplication.class)
|
||||
protected static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public EnvironmentRepository environmentRepository() {
|
||||
return Mockito.mock(EnvironmentRepository.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.springframework.cloud.config.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.boot.test.TestRestTemplate;
|
||||
import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator;
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.cloud.config.server.ConfigClientOnIntegrationTests.TestConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = TestConfiguration.class)
|
||||
@IntegrationTest({ "server.port:0", "spring.cloud.config.enabled:true" })
|
||||
@WebAppConfiguration
|
||||
@ActiveProfiles("test")
|
||||
public class ConfigClientOnIntegrationTests {
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() throws IOException {
|
||||
ConfigServerTestUtils.prepareLocalRepo();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
Environment environment = new TestRestTemplate().getForObject("http://localhost:"
|
||||
+ port + "/foo/development/", Environment.class);
|
||||
assertTrue(environment.getPropertySources().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configClientEnabled() throws Exception {
|
||||
assertEquals(1, BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,
|
||||
ConfigServicePropertySourceLocator.class).length);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(ConfigServerApplication.class)
|
||||
protected static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public EnvironmentRepository environmentRepository() {
|
||||
return Mockito.mock(EnvironmentRepository.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user