Allow system property override to be switched off

The default behaviour is the same as before, so a config client
adds the remote property sources "first" (i.e. ahead of system
properties). If the user sets up a  remote config repo with
spring.cloud.config.overrideSystemProperties=false they can
change this behaviour and insert the new property source after
systemEnvironment (i.e. before local config files but after the
other local sources). Of course using an `application.yml` on
the server you can change the default  for all applications.

There is also a new feature in the config server where the operator
can add a map of override properties in
spring.cloud.config.server.overrides.* and have them added with
highest priority in the Environment returned from the server.
Using that the operator can prevent config repositories from
changing the override behaviour by setting
spring.cloud.config.allowOverride=false.

Fixes gh-57
This commit is contained in:
Dave Syer
2015-01-16 16:24:41 +00:00
parent 1a2c21a081
commit a0c9ae3ff0
17 changed files with 256 additions and 58 deletions

View File

@@ -46,7 +46,7 @@ public class ConfigServerBootstrapConfiguration {
@Bean
public EnvironmentRepositoryPropertySourceLocator environmentRepositoryPropertySourceLocator() {
return new EnvironmentRepositoryPropertySourceLocator(repository,
client.getName(), client.getEnv(), client.getLabel());
client.getName(), client.getProfile(), client.getLabel());
}
}

View File

@@ -42,6 +42,7 @@ public class ConfigServerMvcConfiguration {
public EnvironmentController environmentController() {
EnvironmentController controller = new EnvironmentController(repository, encryptionController());
controller.setDefaultLabel(server.getDefaultLabel());
controller.setOverrides(server.getOverrides());
return controller;
}

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.cloud.config.server;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
@@ -28,7 +31,15 @@ public class ConfigServerProperties {
private boolean bootstrap;
private String prefix;
/**
* Default repository label (defaults to "master") when incoming requests do not have
* a specific label.
*/
private String defaultLabel = ConfigServerProperties.MASTER;
/**
* Extra map for a property source to be sent to all clients.
*/
private Map<String, String> overrides = new LinkedHashMap<String, String>();
public String getDefaultLabel() {
return defaultLabel;
}
@@ -47,5 +58,11 @@ public class ConfigServerProperties {
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public Map<String, String> getOverrides() {
return overrides;
}
public void setOverrides(Map<String, String> overrides) {
this.overrides = overrides;
}
}

View File

@@ -36,6 +36,8 @@ public class EnvironmentController {
private String defaultLabel = ConfigServerProperties.MASTER;
private Map<String, String> overrides = new LinkedHashMap<String, String>();
@Autowired
public EnvironmentController(EnvironmentRepository repository,
EncryptionController encryption) {
@@ -52,7 +54,12 @@ public class EnvironmentController {
@RequestMapping("/{name}/{profiles}/{label}")
public Environment labelled(@PathVariable String name, @PathVariable String profiles,
@PathVariable String label) {
return encryption.decrypt(repository.findOne(name, profiles, label));
Environment environment = encryption.decrypt(repository.findOne(name, profiles,
label));
if (!overrides.isEmpty()) {
environment.addFirst(new PropertySource("overrides", overrides));
}
return environment;
}
@RequestMapping("/{name}-{profiles}.properties")
@@ -65,7 +72,8 @@ public class EnvironmentController {
public ResponseEntity<String> labelledProperties(@PathVariable String name,
@PathVariable String profiles, @PathVariable String label) throws IOException {
if (name.contains("-") || profiles.contains("-")) {
throw new IllegalArgumentException("Properties output not supported for name or profiles containing hyphens");
throw new IllegalArgumentException(
"Properties output not supported for name or profiles containing hyphens");
}
Properties properties = convertToProperties(labelled(name, profiles, label));
return getSuccess(sortLines(properties));
@@ -92,8 +100,8 @@ public class EnvironmentController {
}
@RequestMapping({ "/{name}-{profiles}.yml", "/{name}-{profiles}.yaml" })
public ResponseEntity<String> yaml(@PathVariable String name, @PathVariable String profiles)
throws Exception {
public ResponseEntity<String> yaml(@PathVariable String name,
@PathVariable String profiles) throws Exception {
return labelledYaml(name, profiles, defaultLabel);
}
@@ -101,7 +109,8 @@ public class EnvironmentController {
public ResponseEntity<String> labelledYaml(@PathVariable String name,
@PathVariable String profiles, @PathVariable String label) throws Exception {
if (name.contains("-") || profiles.contains("-")) {
throw new IllegalArgumentException("YAML output not supported for name or profiles containing hyphens");
throw new IllegalArgumentException(
"YAML output not supported for name or profiles containing hyphens");
}
LinkedHashMap<String, Object> target = new LinkedHashMap<String, Object>();
PropertiesConfigurationFactory<Map<String, Object>> factory = new PropertiesConfigurationFactory<Map<String, Object>>(
@@ -113,7 +122,7 @@ public class EnvironmentController {
Map<String, Object> input = factory.getObject();
return getSuccess(new Yaml().dumpAsMap(input));
}
@ExceptionHandler(IllegalArgumentException.class)
public void illegalArgument(HttpServletResponse response) throws IOException {
response.sendError(HttpStatus.BAD_REQUEST.value());
@@ -186,7 +195,14 @@ public class EnvironmentController {
* @param defaultLabel
*/
public void setDefaultLabel(String defaultLabel) {
this.defaultLabel = defaultLabel;
this.defaultLabel = defaultLabel;
}
/**
* @param overrides the overrides to set
*/
public void setOverrides(Map<String, String> overrides) {
this.overrides = overrides;
}
}

View File

@@ -24,6 +24,6 @@ import org.springframework.cloud.config.Environment;
*/
public interface EnvironmentRepository {
Environment findOne(String application, String name, String label);
Environment findOne(String application, String profile, String label);
}

View File

@@ -1,5 +1,6 @@
package org.springframework.cloud.config.server;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import java.io.IOException;
@@ -35,6 +36,8 @@ public class ApplicationTests {
public void contextLoads() {
Environment environment = new TestRestTemplate().getForObject("http://localhost:" + port + "/foo/development/", Environment.class);
assertFalse(environment.getPropertySources().isEmpty());
assertEquals("overrides", environment.getPropertySources().get(0).getName());
assertEquals("{spring.cloud.config.enabled=true}", environment.getPropertySources().get(0).getSource().toString());
}
}

View File

@@ -17,6 +17,7 @@ package org.springframework.cloud.config.server;
import static org.junit.Assert.assertEquals;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -38,7 +39,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
*
*/
public class EnvironmentControllerTests {
@Rule
public ExpectedException expected = ExpectedException.none();
@@ -120,9 +121,22 @@ public class EnvironmentControllerTests {
@Test
public void mappingForLabelledYamlWithHyphen() throws Exception {
Mockito.when(repository.findOne("foo", "bar-spam", "other")).thenReturn(environment);
Mockito.when(repository.findOne("foo", "bar-spam", "other")).thenReturn(
environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(controller).build();
mvc.perform(MockMvcRequestBuilders.get("/other/foo-bar-spam.yml")).andExpect(
MockMvcResultMatchers.status().isBadRequest());
}
@Test
public void allowOverrideFalse() throws Exception {
controller.setOverrides(Collections.singletonMap("foo", "bar"));
Map<String, Object> map = new HashMap<String, Object>();
map.put("a.b.c", "d");
environment.add(new PropertySource("one", map));
Mockito.when(repository.findOne("foo", "bar", "master")).thenReturn(environment);
assertEquals("{foo=bar}", controller.master("foo", "bar").getPropertySources()
.get(0).getSource().toString());
}
}

View File

@@ -4,3 +4,8 @@ spring:
server:
git:
basedir: target/config
overrides:
spring:
cloud:
config:
enabled: true