From b29b492817d9f39136a189611089ee3ebff98453 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 18 Dec 2014 16:49:52 +0000 Subject: [PATCH] Add label/ prefix to properties files in the "native" profile This allows user s to separate their native resources by label, e.g. /config/master/*.properties, /config/dev/*.properties etc. --- .../main/asciidoc/spring-cloud-config.adoc | 9 +++-- .../server/JGitEnvironmentRepository.java | 2 +- ...pringApplicationEnvironmentRepository.java | 40 ++++++++++++++----- ...ApplicationEnvironmentRepositoryTests.java | 9 +++++ .../test/resources/test/dev/foo.properties | 1 + 5 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 spring-cloud-config-server/src/test/resources/test/dev/foo.properties diff --git a/docs/src/main/asciidoc/spring-cloud-config.adoc b/docs/src/main/asciidoc/spring-cloud-config.adoc index 22166cc0..744b94b0 100644 --- a/docs/src/main/asciidoc/spring-cloud-config.adoc +++ b/docs/src/main/asciidoc/spring-cloud-config.adoc @@ -39,10 +39,11 @@ Git, but just loads the config files from the local classpath (or anywhere else you want to point to with "spring.cloud.config.server.locations"). To use the native profile just launch the Config Server with "spring.profiles.active=native". In -the native profile the repository only has the "current" set of -configuration files, so the "label" specification in the HTTP -resources is ignored (i.e. it's like always pulling from "master" in -the Git implementation). +the native profile the repository the "label" specification in the +HTTP resources is added to the search path, so properties files are +loaded from each search location *and* a subdirectory with the same +name as the label (the labelled properties take precedence in the +Spring Environment). === Security diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/JGitEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/JGitEnvironmentRepository.java index ff55cf89..eb34958f 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/JGitEnvironmentRepository.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/JGitEnvironmentRepository.java @@ -177,7 +177,7 @@ public class JGitEnvironmentRepository implements EnvironmentRepository { pull(git, label, ref); } environment.setSearchLocations(getSearchLocations(basedir)); - return clean(environment.findOne(application, profile, label)); + return clean(environment.findOne(application, profile, "")); } private String[] getSearchLocations(File dir) { diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/SpringApplicationEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/SpringApplicationEnvironmentRepository.java index 83e24d03..b74f4a03 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/SpringApplicationEnvironmentRepository.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/SpringApplicationEnvironmentRepository.java @@ -23,11 +23,11 @@ import java.util.List; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.config.Environment; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.StandardEnvironment; -import org.springframework.cloud.config.Environment; import org.springframework.util.StringUtils; /** @@ -46,6 +46,9 @@ public class SpringApplicationEnvironmentRepository implements EnvironmentReposi private boolean failOnError = false; + private static final String[] DEFAULT_LOCATIONS = new String[] { "classpath:/", + "classpath:/config/", "file:./", "file:./config/" }; + /** * Strategy to determine how to handle exceptions during decryption. * @@ -62,12 +65,12 @@ public class SpringApplicationEnvironmentRepository implements EnvironmentReposi ConfigurableEnvironment environment = getEnvironment(profile); builder.environment(environment); builder.web(false).showBanner(false); - String[] args = getArgs(config); + String[] args = getArgs(config, label); ConfigurableApplicationContext context = builder.run(args); environment.getPropertySources().remove("profiles"); try { - return new NativeEnvironmentRepository(environment).findOne( - config, profile, label); + return new NativeEnvironmentRepository(environment).findOne(config, profile, + label); } finally { context.close(); @@ -84,7 +87,7 @@ public class SpringApplicationEnvironmentRepository implements EnvironmentReposi return environment; } - private String[] getArgs(String config) { + private String[] getArgs(String config, String label) { List list = new ArrayList(); if (!config.startsWith("application")) { config = "application," + config; @@ -93,22 +96,41 @@ public class SpringApplicationEnvironmentRepository implements EnvironmentReposi list.add("--spring.cloud.bootstrap.enabled=false"); list.add("--encrypt.failOnError=" + failOnError); if (locations != null) { - list.add("--spring.config.location=" - + StringUtils.arrayToCommaDelimitedString(locations)); + list.add("--spring.config.location=" + getLocations(this.locations, label)); + } + else { + list.add("--spring.config.location=" + getLocations(DEFAULT_LOCATIONS, label)); } return list.toArray(new String[0]); } + private String getLocations(String[] locations, String label) { + List output = new ArrayList(); + for (String location : locations) { + output.add(location); + } + for (String location : locations) { + if (isDirectory(location) && StringUtils.hasText(label)) { + output.add(location + label.trim() + "/"); + } + } + return StringUtils.collectionToCommaDelimitedString(output); + } + public void setSearchLocations(String... locations) { this.locations = locations; for (int i = 0; i < locations.length; i++) { String location = locations[i]; - if (!location.endsWith(".properties") && !location.endsWith(".yml") - && !location.endsWith(".yaml") && !location.endsWith("/")) { + if (isDirectory(location)&& !location.endsWith("/")) { location = location + "/"; } locations[i] = location; } } + private boolean isDirectory(String location) { + return !location.endsWith(".properties") && !location.endsWith(".yml") + && !location.endsWith(".yaml"); + } + } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/SpringApplicationEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/SpringApplicationEnvironmentRepositoryTests.java index 25043488..f46a5a31 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/SpringApplicationEnvironmentRepositoryTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/SpringApplicationEnvironmentRepositoryTests.java @@ -56,4 +56,13 @@ public class SpringApplicationEnvironmentRepositoryTests { assertEquals(3, environment.getPropertySources().size()); } + @Test + public void labelled() { + repository.setSearchLocations("classpath:/test"); + Environment environment = repository.findOne("foo", "development", "dev"); + assertEquals(4, environment.getPropertySources().size()); + // position 1 because it has higher precendence than anything except the foo-development.properties + assertEquals("dev_bar", environment.getPropertySources().get(1).getSource().get("foo")); + } + } diff --git a/spring-cloud-config-server/src/test/resources/test/dev/foo.properties b/spring-cloud-config-server/src/test/resources/test/dev/foo.properties new file mode 100644 index 00000000..469386bf --- /dev/null +++ b/spring-cloud-config-server/src/test/resources/test/dev/foo.properties @@ -0,0 +1 @@ +foo: dev_bar \ No newline at end of file