Skip to content

Commit 43cfeba

Browse files
Ignore properties files in hidden directories
This commit modifies the logic for finding properties files using wildcard paths to ignore files if any part of the file path contains a hidden directory. Hidden directories are common when Kubernetes mounts config maps onto volumes in a pod, which was causing the same properties files to be loaded multiple times. Fixes gh-23160
1 parent 37cbf1b commit 43cfeba

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.io.File;
2020
import java.io.IOException;
21+
import java.nio.file.Path;
22+
import java.nio.file.Paths;
2123
import java.util.ArrayList;
2224
import java.util.Arrays;
2325
import java.util.Collections;
@@ -108,6 +110,7 @@
108110
* @author Andy Wilkinson
109111
* @author Eddú Meléndez
110112
* @author Madhura Bhave
113+
* @author Scott Frederick
111114
* @since 1.0.0
112115
*/
113116
public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
@@ -519,6 +522,14 @@ private void load(PropertySourceLoader loader, String location, Profile profile,
519522
}
520523
continue;
521524
}
525+
if (resource.isFile() && hasHiddenPathElement(resource)) {
526+
if (this.logger.isTraceEnabled()) {
527+
StringBuilder description = getDescription("Skipped location with hidden path element ",
528+
location, resource, profile);
529+
this.logger.trace(description);
530+
}
531+
continue;
532+
}
522533
String name = "applicationConfig: [" + getLocationName(location, resource) + "]";
523534
List<Document> documents = loadDocuments(loader, name, resource);
524535
if (CollectionUtils.isEmpty(documents)) {
@@ -555,6 +566,16 @@ private void load(PropertySourceLoader loader, String location, Profile profile,
555566
}
556567
}
557568

569+
private boolean hasHiddenPathElement(Resource resource) throws IOException {
570+
String cleanPath = StringUtils.cleanPath(resource.getFile().getAbsolutePath());
571+
for (Path value : Paths.get(cleanPath)) {
572+
if (value.toString().startsWith(".")) {
573+
return true;
574+
}
575+
}
576+
return false;
577+
}
578+
558579
private String getLocationName(String location, Resource resource) {
559580
if (!location.contains("*")) {
560581
return location;

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/config/ConfigFileApplicationListenerTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
* @author Dave Syer
7676
* @author Eddú Meléndez
7777
* @author Madhura Bhave
78+
* @author Scott Frederick
7879
*/
7980
@ExtendWith(OutputCaptureExtension.class)
8081
class ConfigFileApplicationListenerTests {
@@ -1080,6 +1081,16 @@ void locationsWithWildcardDirectoriesShouldRestrictToOneLevelDeep() {
10801081
assertThat(this.environment.getProperty("third.property")).isNull();
10811082
}
10821083

1084+
@Test
1085+
void locationsWithWildcardDirectoriesShouldIgnoreHiddenDirectories() {
1086+
String location = "file:src/test/resources/config/*/";
1087+
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
1088+
"spring.config.location=" + location);
1089+
this.initializer.setSearchNames("testproperties");
1090+
this.initializer.postProcessEnvironment(this.environment, this.application);
1091+
assertThat(this.environment.getProperty("fourth.property")).isNull();
1092+
}
1093+
10831094
@Test
10841095
void locationsWithWildcardDirectoriesShouldLoadAllFilesThatMatch() {
10851096
String location = "file:src/test/resources/config/*/";
@@ -1124,6 +1135,16 @@ void locationsWithWildcardFilesShouldLoadAllFilesThatMatch() {
11241135
assertThat(second).isEqualTo("ball");
11251136
}
11261137

1138+
@Test
1139+
void locationsWithWildcardFilesShouldIgnoreHiddenDirectories() {
1140+
String location = "file:src/test/resources/config/*/testproperties.properties";
1141+
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment,
1142+
"spring.config.location=" + location);
1143+
this.initializer.setSearchNames("testproperties");
1144+
this.initializer.postProcessEnvironment(this.environment, this.application);
1145+
assertThat(this.environment.getProperty("fourth.property")).isNull();
1146+
}
1147+
11271148
private Condition<ConfigurableEnvironment> matchingPropertySource(final String sourceName) {
11281149
return new Condition<ConfigurableEnvironment>("environment containing property source " + sourceName) {
11291150

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fourth.property=shouldbehidden

0 commit comments

Comments
 (0)