Use config map name for configtree property sources
When Kubernetes mounts config maps onto volumes in a pod, it creates hidden files on the pod filesystem with symbolic links to the hidden files. The symlinks are named for the user-provided config map that was mounted, while the hidden files have system-generated names. Prior to this commit, the property sources created by the configtree property source were added to the environment using the system-generated hidden file name instead of the user-provided symlink name. This commit corrects that behavior so the property sources are named as a user would expect. Fixes gh-23232
This commit is contained in:
@@ -25,6 +25,7 @@ import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
@@ -192,7 +193,7 @@ public class ConfigTreePropertySource extends EnumerablePropertySource<Path> imp
|
||||
static Map<String, PropertyFile> findAll(Path sourceDirectory, Set<Option> options) {
|
||||
try {
|
||||
Map<String, PropertyFile> propertyFiles = new TreeMap<>();
|
||||
Files.find(sourceDirectory, MAX_DEPTH, PropertyFile::isRegularFile).forEach((path) -> {
|
||||
Files.find(sourceDirectory, MAX_DEPTH, PropertyFile::isPropertyFile).forEach((path) -> {
|
||||
String name = getName(sourceDirectory.relativize(path));
|
||||
if (StringUtils.hasText(name)) {
|
||||
if (options.contains(Option.USE_LOWERCASE_NAMES)) {
|
||||
@@ -208,8 +209,18 @@ public class ConfigTreePropertySource extends EnumerablePropertySource<Path> imp
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isRegularFile(Path path, BasicFileAttributes attributes) {
|
||||
return attributes.isRegularFile();
|
||||
private static boolean isPropertyFile(Path path, BasicFileAttributes attributes) {
|
||||
return !hasHiddenPathElement(path) && (attributes.isRegularFile() || attributes.isSymbolicLink());
|
||||
}
|
||||
|
||||
private static boolean hasHiddenPathElement(Path path) {
|
||||
Iterator<Path> iterator = path.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (iterator.next().toString().startsWith(".")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getName(Path relativePath) {
|
||||
|
||||
@@ -88,6 +88,18 @@ class ConfigTreePropertySourceTests {
|
||||
assertThat(propertySource.getPropertyNames()).containsExactly("c", "fa.a", "fa.b", "fb.a", "fb.fa.a");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyNamesFromFlatWithSymlinksIgnoresHiddenFiles() throws Exception {
|
||||
ConfigTreePropertySource propertySource = getSymlinkedFlatPropertySource();
|
||||
assertThat(propertySource.getPropertyNames()).containsExactly("a", "b", "c");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyNamesFromNestedWithSymlinksIgnoresHiddenFiles() throws Exception {
|
||||
ConfigTreePropertySource propertySource = getSymlinkedNestedPropertySource();
|
||||
assertThat(propertySource.getPropertyNames()).containsExactly("aa", "ab", "baa", "c");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyNamesWhenLowercaseReturnsPropertyNames() throws Exception {
|
||||
addProperty("SpRiNg", "boot");
|
||||
@@ -194,6 +206,16 @@ class ConfigTreePropertySourceTests {
|
||||
return new ConfigTreePropertySource("test", this.directory);
|
||||
}
|
||||
|
||||
private ConfigTreePropertySource getSymlinkedFlatPropertySource() throws IOException {
|
||||
addProperty("..hidden-a", "A");
|
||||
addProperty("..hidden-b", "B");
|
||||
addProperty("..hidden-c", "C");
|
||||
createSymbolicLink("a", "..hidden-a");
|
||||
createSymbolicLink("b", "..hidden-b");
|
||||
createSymbolicLink("c", "..hidden-c");
|
||||
return new ConfigTreePropertySource("test", this.directory);
|
||||
}
|
||||
|
||||
private ConfigTreePropertySource getNestedPropertySource() throws IOException {
|
||||
addNested();
|
||||
return new ConfigTreePropertySource("test", this.directory);
|
||||
@@ -207,10 +229,26 @@ class ConfigTreePropertySourceTests {
|
||||
addProperty("c", "C");
|
||||
}
|
||||
|
||||
private ConfigTreePropertySource getSymlinkedNestedPropertySource() throws IOException {
|
||||
addProperty("..hidden-a/a", "AA");
|
||||
addProperty("..hidden-a/b", "AB");
|
||||
addProperty("..hidden-b/fa/a", "BAA");
|
||||
addProperty("c", "C");
|
||||
createSymbolicLink("aa", "..hidden-a/a");
|
||||
createSymbolicLink("ab", "..hidden-a/b");
|
||||
createSymbolicLink("baa", "..hidden-b/fa/a");
|
||||
return new ConfigTreePropertySource("test", this.directory);
|
||||
}
|
||||
|
||||
private void addProperty(String path, String value) throws IOException {
|
||||
File file = this.directory.resolve(path).toFile();
|
||||
file.getParentFile().mkdirs();
|
||||
FileCopyUtils.copy(value.getBytes(StandardCharsets.UTF_8), file);
|
||||
}
|
||||
|
||||
private void createSymbolicLink(String link, String target) throws IOException {
|
||||
Files.createSymbolicLink(this.directory.resolve(link).toAbsolutePath(),
|
||||
this.directory.resolve(target).toAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user