Skip to content

Support new delimiters in spring.config.location #1904

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.springframework.cloud.config.server.environment;

import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
Expand Down Expand Up @@ -224,7 +225,7 @@ private ConfigurableEnvironment getEnvironment(String application, String profil
map.put("spring.config.name", config);
// map.put("encrypt.failOnError=" + this.failOnError);
map.put("spring.config.location",
StringUtils.arrayToCommaDelimitedString(getLocations(application, profile, label).getLocations()));
StringUtils.arrayToDelimitedString(getLocations(application, profile, label).getLocations(), ";"));
// globally ignore config files that are not found
map.put("spring.config.on-not-found", "IGNORE");
environment.getPropertySources().addFirst(new MapPropertySource("config-data-setup", map));
Expand All @@ -245,64 +246,32 @@ protected Environment clean(Environment env,
if (this.environment.getPropertySources().contains(name)) {
continue;
}
String location = null;
String[] locations = null;

PropertySourceConfigData configData = propertySourceToConfigData.get(source.getOriginalPropertySource());
// try and get information directly from ConfigData
if (configData != null && configData.resource instanceof StandardConfigDataResource) {
StandardConfigDataResource configDataResource = (StandardConfigDataResource) configData.resource;
// use StandardConfigDataResource as that format is expected still
name = configDataResource.toString();
location = configData.location.toString();
locations = configDataLocations(configData.location.split());
}
else {
// if not, try and parse
Matcher matcher = RESOURCE_PATTERN.matcher(name);
if (matcher.find()) {
name = matcher.group(1);
location = matcher.group(2);
locations = new String[] { matcher.group(2) };
}
}
// TODO: needed anymore?
name = name.replace("applicationConfig: [", "");
name = name.replace("file [", "file:");
if (name.indexOf('[') < 0) {
// only remove if there isn't a matching left bracket
name = name.replace("]", "");
}
if (this.searchLocations != null) {
boolean matches = false;
String normal = name;
if (normal.startsWith("file:")) {
normal = StringUtils.cleanPath(new File(normal.substring("file:".length())).getAbsolutePath());
}
String profile = result.getProfiles() == null ? null
: StringUtils.arrayToCommaDelimitedString(result.getProfiles());
for (String pattern : getLocations(result.getName(), profile, result.getLabel()).getLocations()) {
if (!pattern.contains(":")) {
pattern = "file:" + pattern;
}
if (pattern.startsWith("file:")) {
pattern = StringUtils.cleanPath(new File(pattern.substring("file:".length())).getAbsolutePath())
+ "/";
}
if (logger.isTraceEnabled()) {
logger.trace("Testing pattern: " + pattern + " with property source: " + name);
}
if (normal.startsWith(pattern) && !normal.substring(pattern.length()).contains("/")) {
matches = true;
break;
}
if (location != null && location.startsWith("file:")) {
location = StringUtils
.cleanPath(new File(location.substring("file:".length())).getAbsolutePath()) + "/";
}
if (location != null && location.startsWith(pattern)
&& !location.substring(pattern.length()).contains("/")) {
matches = true;
break;
}
}
boolean matches = matchesLocation(locations, name, result);
if (!matches) {
// Don't include this one: it wasn't matched by our search locations
if (logger.isDebugEnabled()) {
Expand All @@ -324,6 +293,53 @@ protected Environment clean(Environment env,
return result;
}

private String[] configDataLocations(ConfigDataLocation[] locations) {
String[] stringLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
stringLocations[i] = locations[i].toString();
}
return stringLocations;
}

private boolean matchesLocation(String[] locations, String name, Environment result) {
boolean matches = false;
String normal = name;
if (normal.startsWith("file:")) {
normal = StringUtils.cleanPath(new File(normal.substring("file:".length())).getAbsolutePath());
}
String profile = result.getProfiles() == null ? null
: StringUtils.arrayToCommaDelimitedString(result.getProfiles());
for (String pattern : getLocations(result.getName(), profile, result.getLabel()).getLocations()) {
if (!pattern.contains(":")) {
pattern = "file:" + pattern;
}
if (pattern.startsWith("file:")) {
pattern = StringUtils.cleanPath(new File(pattern.substring("file:".length())).getAbsolutePath()) + "/";
}
final String finalPattern = pattern;
if (logger.isTraceEnabled()) {
logger.trace("Testing pattern: " + finalPattern + " with property source: " + name);
}
if (normal.startsWith(finalPattern) && !normal.substring(finalPattern.length()).contains("/")) {
matches = true;
break;
}
if (locations != null) {
return !Arrays.stream(locations).map(this::cleanFileLocation)
.noneMatch(location -> location.startsWith(finalPattern)
&& !location.substring(finalPattern.length()).contains("/"));
}
}
return matches;
}

private String cleanFileLocation(String location) {
if (location.startsWith("file:")) {
return StringUtils.cleanPath(new File(location.substring("file:".length())).getAbsolutePath()) + "/";
}
return location;
}

public String[] getSearchLocations() {
return this.searchLocations;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,20 @@ public void nestedWithApplicationPlaceholders() throws IOException {
assertThat(environment.getPropertySources().size()).isEqualTo(3);
}

@Test
public void verifyPropertySourceOrdering() throws IOException {
String uri = ConfigServerTestUtils.prepareLocalRepo("ordering-repo");
this.context = new SpringApplicationBuilder(TestConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.cloud.config.server.git.uri=" + uri, "--spring.cloud.config.server.git.searchPaths=**");
EnvironmentRepository repository = this.context.getBean(EnvironmentRepository.class);
Environment environment = repository.findOne("application", "test", "master");
assertThat(environment.getPropertySources().size()).isEqualTo(2);
assertThat(environment.getPropertySources().get(0).getName())
.isEqualTo("file:././target/repos/ordering-repo//project/sub/application-test.yml");
assertThat(environment.getPropertySources().get(1).getName())
.isEqualTo("file:././target/repos/ordering-repo//project/application.yml");
}

@Test
public void nestedWithProfilePlaceholders() throws IOException {
String uri = ConfigServerTestUtils.prepareLocalRepo("nested-repo");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
initial commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ref: refs/heads/master
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0000000000000000000000000000000000000000 8265220d6be7d73011cbc98382b499e5d7169fe7 Ryan Baxter <[email protected]> 1623269485 -0400 commit (initial): initial commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0000000000000000000000000000000000000000 8265220d6be7d73011cbc98382b499e5d7169fe7 Ryan Baxter <[email protected]> 1623269485 -0400 commit (initial): initial commit
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x��A
�0E]�se��iD�#x�I��@�HEo/�������uY�B7�N�8Z$ ��J�'�28�('r1F�!��~�6��y� �tlpli�{yV��P� �`��c{�&o�_�ה�h�~��C:�
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
8265220d6be7d73011cbc98382b499e5d7169fe7
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
info:
foo: bar
raw: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
info:
foo: profile