diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java
index 18fac7b7..7baeb44d 100644
--- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java
+++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java
@@ -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());
diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java
index 5994fc04..dcad0721 100644
--- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java
+++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientProperties.java
@@ -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 + "]";
}
}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerBootstrapApplicationListener.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerBootstrapApplicationListener.java
new file mode 100644
index 00000000..b1da3ebd
--- /dev/null
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerBootstrapApplicationListener.java
@@ -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 spring.cloud.config.enabled is
+ * explicitly "true". It has to be "true" at the time this listener is fired, which means
+ * before the bootstrap.yml 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
+ * spring.cloud.bootstrap.name to something other than "bootstrap".
+ *
+ * @author Dave Syer
+ *
+ */
+public class ConfigServerBootstrapApplicationListener implements
+ ApplicationListener, Ordered {
+
+ public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 4;
+
+ private int order = DEFAULT_ORDER;
+
+ private PropertySource> propertySource = new MapPropertySource(
+ "configServerClient", Collections. 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);
+ }
+ }
+ }
+
+}
diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerBootstrapConfiguration.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerBootstrapConfiguration.java
index a1ce1fbf..afc3621f 100644
--- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerBootstrapConfiguration.java
+++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/ConfigServerBootstrapConfiguration.java
@@ -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());
}
}
diff --git a/spring-cloud-config-server/src/main/resources/META-INF/spring.factories b/spring-cloud-config-server/src/main/resources/META-INF/spring.factories
index 5b4ba62c..5332de41 100644
--- a/spring-cloud-config-server/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-config-server/src/main/resources/META-INF/spring.factories
@@ -1,3 +1,7 @@
# Bootstrap components
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
-org.springframework.cloud.config.server.ConfigServerBootstrapConfiguration
\ No newline at end of file
+org.springframework.cloud.config.server.ConfigServerBootstrapConfiguration
+
+# Application listeners
+org.springframework.context.ApplicationListener=\
+org.springframework.cloud.config.server.ConfigServerBootstrapApplicationListener
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java
index 28a0168f..10471582 100644
--- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/BootstrapConfigServerIntegrationTests.java
@@ -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
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ConfigClientOffIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ConfigClientOffIntegrationTests.java
new file mode 100644
index 00000000..4761624d
--- /dev/null
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ConfigClientOffIntegrationTests.java
@@ -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);
+ }
+
+ }
+
+}
diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ConfigClientOnIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ConfigClientOnIntegrationTests.java
new file mode 100644
index 00000000..0a0f695f
--- /dev/null
+++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/ConfigClientOnIntegrationTests.java
@@ -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);
+ }
+
+ }
+
+}