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.
This commit is contained in:
Dave Syer
2014-12-18 16:49:52 +00:00
parent fade46210e
commit b29b492817
5 changed files with 47 additions and 14 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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<String> list = new ArrayList<String>();
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<String> output = new ArrayList<String>();
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");
}
}

View File

@@ -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"));
}
}

View File

@@ -0,0 +1 @@
foo: dev_bar