Rename volumemount -> configtree
Closes gh-22941
This commit is contained in:
@@ -675,7 +675,7 @@ Locations will be processed in the order that they are defined, with later impor
|
||||
[TIP]
|
||||
====
|
||||
Spring Boot includes pluggable API that allows various different location addresses to be supported.
|
||||
By default you can import Java Properties, YAML and volume mounts.
|
||||
By default you can import Java Properties, YAML and "`<<boot-features-external-config-files-configtree, configuration trees>>`".
|
||||
|
||||
Third-party jars can offer support for additional technologies (there's no requirement for files to be local).
|
||||
For example, you can imagine config data being from external stores such as Consul, Apache ZooKeeper or Netflix Archaius.
|
||||
@@ -685,8 +685,8 @@ If you want to support your own locations, see the `ConfigDataLocationResolver`
|
||||
|
||||
|
||||
|
||||
[[boot-features-external-config-files-voumemounts]]
|
||||
==== Using Volume Mount Properties
|
||||
[[boot-features-external-config-files-configtree]]
|
||||
==== Using Configuration Trees
|
||||
When running applications on a cloud platform (such as Kubernetes) you often need to read config values that the platform supplies.
|
||||
It's not uncommon to use environment variables for such purposes, but this can have drawbacks, especially if the value is supposed to be kept secret.
|
||||
|
||||
@@ -696,10 +696,10 @@ For example, Kubernetes can volume mount both https://kubernetes.io/docs/tasks/c
|
||||
There are two common volume mount patterns that can be use:
|
||||
|
||||
. A single file contains a complete set of properties (usually written as YAML).
|
||||
. Multiple files are written to a directory with the filename becoming the '`key`' and the contents becoming the '`value`'.
|
||||
. Multiple files are written to a directory tree, with the filename becoming the '`key`' and the contents becoming the '`value`'.
|
||||
|
||||
For the first case, you can import the YAML or Properties file directly using `spring.config.import` as described <<boot-features-external-config-files-importing,above>>.
|
||||
For the second case, you need to use the `volumemount:` prefix so that Spring Boot knows it needs to expose all the files as properties.
|
||||
For the second case, you need to use the `configtree:` prefix so that Spring Boot knows it needs to expose all the files as properties.
|
||||
|
||||
As an example, let's imagine that Kubernetes has mounted the following volume:
|
||||
|
||||
@@ -718,12 +718,12 @@ To import these properties, you can add the following to your `application.prope
|
||||
|
||||
[source,properties,indent=0]
|
||||
----
|
||||
spring.config.import=volumemount:/etc/config
|
||||
spring.config.import=configtree:/etc/config
|
||||
----
|
||||
|
||||
You can then access or inject `myapp.username` and `myapp.password` properties from the `Environment` in the usual way.
|
||||
|
||||
TIP: Volume mounted values can be bound to both string `String` and `byte[]` types depending on the contents expected.
|
||||
TIP: Configuration tree values can be bound to both string `String` and `byte[]` types depending on the contents expected.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,21 +20,21 @@ import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.boot.env.VolumeMountDirectoryPropertySource;
|
||||
import org.springframework.boot.env.ConfigTreePropertySource;
|
||||
|
||||
/**
|
||||
* {@link ConfigDataLoader} for directory locations mounted as volumes.
|
||||
* {@link ConfigDataLoader} for config tree locations.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class VolumeMountConfigDataLoader implements ConfigDataLoader<VolumeMountConfigDataLocation> {
|
||||
class ConfigTreeConfigDataLoader implements ConfigDataLoader<ConfigTreeConfigDataLocation> {
|
||||
|
||||
@Override
|
||||
public ConfigData load(VolumeMountConfigDataLocation location) throws IOException {
|
||||
public ConfigData load(ConfigTreeConfigDataLocation location) throws IOException {
|
||||
Path path = location.getPath();
|
||||
String name = "Volume mount config '" + path + "'";
|
||||
VolumeMountDirectoryPropertySource source = new VolumeMountDirectoryPropertySource(name, path);
|
||||
String name = "Config tree '" + path + "'";
|
||||
ConfigTreePropertySource source = new ConfigTreePropertySource(name, path);
|
||||
return new ConfigData(Collections.singletonList(source));
|
||||
}
|
||||
|
||||
@@ -20,19 +20,21 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.boot.env.ConfigTreePropertySource;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link ConfigDataLocation} backed by a directory mounted as a volume.
|
||||
* {@link ConfigDataLocation} backed by a config tree directory.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Phillip Webb
|
||||
* @see ConfigTreePropertySource
|
||||
*/
|
||||
class VolumeMountConfigDataLocation extends ConfigDataLocation {
|
||||
class ConfigTreeConfigDataLocation extends ConfigDataLocation {
|
||||
|
||||
private final Path path;
|
||||
|
||||
VolumeMountConfigDataLocation(String path) {
|
||||
ConfigTreeConfigDataLocation(String path) {
|
||||
Assert.notNull(path, "Path must not be null");
|
||||
this.path = Paths.get(path).toAbsolutePath();
|
||||
}
|
||||
@@ -49,7 +51,7 @@ class VolumeMountConfigDataLocation extends ConfigDataLocation {
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
VolumeMountConfigDataLocation other = (VolumeMountConfigDataLocation) obj;
|
||||
ConfigTreeConfigDataLocation other = (ConfigTreeConfigDataLocation) obj;
|
||||
return Objects.equals(this.path, other.path);
|
||||
}
|
||||
|
||||
@@ -60,7 +62,7 @@ class VolumeMountConfigDataLocation extends ConfigDataLocation {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "volume mount [" + this.path + "]";
|
||||
return "config tree [" + this.path + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,15 +20,14 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link ConfigDataLocationResolver} for volume mounted locations such as Kubernetes
|
||||
* ConfigMaps and Secrets.
|
||||
* {@link ConfigDataLocationResolver} for config tree locations.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class VolumeMountConfigDataLocationResolver implements ConfigDataLocationResolver<VolumeMountConfigDataLocation> {
|
||||
class ConfigTreeConfigDataLocationResolver implements ConfigDataLocationResolver<ConfigTreeConfigDataLocation> {
|
||||
|
||||
private static final String PREFIX = "volumemount:";
|
||||
private static final String PREFIX = "configtree:";
|
||||
|
||||
@Override
|
||||
public boolean isResolvable(ConfigDataLocationResolverContext context, String location) {
|
||||
@@ -36,8 +35,8 @@ class VolumeMountConfigDataLocationResolver implements ConfigDataLocationResolve
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VolumeMountConfigDataLocation> resolve(ConfigDataLocationResolverContext context, String location) {
|
||||
VolumeMountConfigDataLocation resolved = new VolumeMountConfigDataLocation(location.substring(PREFIX.length()));
|
||||
public List<ConfigTreeConfigDataLocation> resolve(ConfigDataLocationResolverContext context, String location) {
|
||||
ConfigTreeConfigDataLocation resolved = new ConfigTreeConfigDataLocation(location.substring(PREFIX.length()));
|
||||
return Collections.singletonList(resolved);
|
||||
}
|
||||
|
||||
@@ -46,16 +46,16 @@ import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link PropertySource} backed by a directory that contains files for each value. The
|
||||
* {@link PropertySource} will recursively scan a given source directory and expose a
|
||||
* {@link PropertySource} backed by a directory tree that contains files for each value.
|
||||
* The {@link PropertySource} will recursively scan a given source directory and expose a
|
||||
* property for each file found. The property name will be the filename, and the property
|
||||
* value will be the contents of the file.
|
||||
* <p>
|
||||
* Directories are only scanned when the source is first created. The directory is not
|
||||
* monitored for updates, so files should not be added or removed. However, the contents
|
||||
* of a file can be updated as long as the property source was created with a
|
||||
* {@link Option#ALWAYS_READ} option. Nested folders are included in the source, but with
|
||||
* a {@code '.'} rather than {@code '/'} used as the path separator.
|
||||
* {@link Option#ALWAYS_READ} option. Nested directories are included in the source, but
|
||||
* with a {@code '.'} rather than {@code '/'} used as the path separator.
|
||||
* <p>
|
||||
* Property values are returned as {@link Value} instances which allows them to be treated
|
||||
* either as an {@link InputStreamSource} or as a {@link CharSequence}. In addition, if
|
||||
@@ -69,7 +69,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Phillip Webb
|
||||
* @since 2.4.0
|
||||
*/
|
||||
public class VolumeMountDirectoryPropertySource extends EnumerablePropertySource<Path> implements OriginLookup<String> {
|
||||
public class ConfigTreePropertySource extends EnumerablePropertySource<Path> implements OriginLookup<String> {
|
||||
|
||||
private static final int MAX_DEPTH = 100;
|
||||
|
||||
@@ -80,25 +80,25 @@ public class VolumeMountDirectoryPropertySource extends EnumerablePropertySource
|
||||
private final Set<Option> options;
|
||||
|
||||
/**
|
||||
* Create a new {@link VolumeMountDirectoryPropertySource} instance.
|
||||
* Create a new {@link ConfigTreePropertySource} instance.
|
||||
* @param name the name of the property source
|
||||
* @param sourceDirectory the underlying source directory
|
||||
*/
|
||||
public VolumeMountDirectoryPropertySource(String name, Path sourceDirectory) {
|
||||
public ConfigTreePropertySource(String name, Path sourceDirectory) {
|
||||
this(name, sourceDirectory, EnumSet.noneOf(Option.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link VolumeMountDirectoryPropertySource} instance.
|
||||
* Create a new {@link ConfigTreePropertySource} instance.
|
||||
* @param name the name of the property source
|
||||
* @param sourceDirectory the underlying source directory
|
||||
* @param options the property source options
|
||||
*/
|
||||
public VolumeMountDirectoryPropertySource(String name, Path sourceDirectory, Option... options) {
|
||||
public ConfigTreePropertySource(String name, Path sourceDirectory, Option... options) {
|
||||
this(name, sourceDirectory, EnumSet.copyOf(Arrays.asList(options)));
|
||||
}
|
||||
|
||||
private VolumeMountDirectoryPropertySource(String name, Path sourceDirectory, Set<Option> options) {
|
||||
private ConfigTreePropertySource(String name, Path sourceDirectory, Set<Option> options) {
|
||||
super(name, sourceDirectory);
|
||||
Assert.isTrue(Files.exists(sourceDirectory), () -> "Directory '" + sourceDirectory + "' does not exist");
|
||||
Assert.isTrue(Files.isDirectory(sourceDirectory), () -> "File '" + sourceDirectory + "' is not a directory");
|
||||
@@ -894,7 +894,7 @@
|
||||
"value": "classpath:"
|
||||
},
|
||||
{
|
||||
"value": "volumemount:"
|
||||
"value": "configtree:"
|
||||
}
|
||||
],
|
||||
"providers": [
|
||||
|
||||
@@ -5,13 +5,13 @@ org.springframework.boot.env.YamlPropertySourceLoader
|
||||
|
||||
# ConfigData Location Resolvers
|
||||
org.springframework.boot.context.config.ConfigDataLocationResolver=\
|
||||
org.springframework.boot.context.config.ResourceConfigDataLocationResolver,\
|
||||
org.springframework.boot.context.config.VolumeMountConfigDataLocationResolver
|
||||
org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,\
|
||||
org.springframework.boot.context.config.ResourceConfigDataLocationResolver
|
||||
|
||||
# ConfigData Loaders
|
||||
org.springframework.boot.context.config.ConfigDataLoader=\
|
||||
org.springframework.boot.context.config.ResourceConfigDataLoader,\
|
||||
org.springframework.boot.context.config.VolumeMountConfigDataLoader
|
||||
org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\
|
||||
org.springframework.boot.context.config.ResourceConfigDataLoader
|
||||
|
||||
# Run Listeners
|
||||
org.springframework.boot.SpringApplicationRunListener=\
|
||||
|
||||
@@ -30,14 +30,14 @@ import org.springframework.util.FileCopyUtils;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link VolumeMountConfigDataLoader}.
|
||||
* Tests for {@link ConfigTreeConfigDataLoader}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class VolumeMountConfigDataLoaderTests {
|
||||
public class ConfigTreeConfigDataLoaderTests {
|
||||
|
||||
private VolumeMountConfigDataLoader loader = new VolumeMountConfigDataLoader();
|
||||
private ConfigTreeConfigDataLoader loader = new ConfigTreeConfigDataLoader();
|
||||
|
||||
@TempDir
|
||||
Path directory;
|
||||
@@ -47,11 +47,11 @@ public class VolumeMountConfigDataLoaderTests {
|
||||
File file = this.directory.resolve("hello").toFile();
|
||||
file.getParentFile().mkdirs();
|
||||
FileCopyUtils.copy("world".getBytes(StandardCharsets.UTF_8), file);
|
||||
VolumeMountConfigDataLocation location = new VolumeMountConfigDataLocation(this.directory.toString());
|
||||
ConfigTreeConfigDataLocation location = new ConfigTreeConfigDataLocation(this.directory.toString());
|
||||
ConfigData configData = this.loader.load(location);
|
||||
assertThat(configData.getPropertySources().size()).isEqualTo(1);
|
||||
PropertySource<?> source = configData.getPropertySources().get(0);
|
||||
assertThat(source.getName()).isEqualTo("Volume mount config '" + this.directory.toString() + "'");
|
||||
assertThat(source.getName()).isEqualTo("Config tree '" + this.directory.toString() + "'");
|
||||
assertThat(source.getProperty("hello").toString()).isEqualTo("world");
|
||||
}
|
||||
|
||||
@@ -25,20 +25,20 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link VolumeMountConfigDataLocationResolver}.
|
||||
* Tests for {@link ConfigTreeConfigDataLocationResolver}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class VolumeMountConfigDataLocationResolverTests {
|
||||
class ConfigTreeConfigDataLocationResolverTests {
|
||||
|
||||
private VolumeMountConfigDataLocationResolver resolver = new VolumeMountConfigDataLocationResolver();
|
||||
private ConfigTreeConfigDataLocationResolver resolver = new ConfigTreeConfigDataLocationResolver();
|
||||
|
||||
private ConfigDataLocationResolverContext context = mock(ConfigDataLocationResolverContext.class);
|
||||
|
||||
@Test
|
||||
void isResolvableWhenPrefixMatchesReturnsTrue() {
|
||||
assertThat(this.resolver.isResolvable(this.context, "volumemount:/etc/config")).isTrue();
|
||||
assertThat(this.resolver.isResolvable(this.context, "configtree:/etc/config")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -49,10 +49,10 @@ class VolumeMountConfigDataLocationResolverTests {
|
||||
|
||||
@Test
|
||||
void resolveReturnsConfigVolumeMountLocation() {
|
||||
List<VolumeMountConfigDataLocation> locations = this.resolver.resolve(this.context, "volumemount:/etc/config");
|
||||
List<ConfigTreeConfigDataLocation> locations = this.resolver.resolve(this.context, "configtree:/etc/config");
|
||||
assertThat(locations.size()).isEqualTo(1);
|
||||
assertThat(locations).extracting(Object::toString)
|
||||
.containsExactly("volume mount [" + new File("/etc/config").getAbsolutePath() + "]");
|
||||
.containsExactly("config tree [" + new File("/etc/config").getAbsolutePath() + "]");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,37 +24,37 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link VolumeMountConfigDataLocation}.
|
||||
* Tests for {@link ConfigTreeConfigDataLocation}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class VolumeMountConfigDataLocationTests {
|
||||
public class ConfigTreeConfigDataLocationTests {
|
||||
|
||||
@Test
|
||||
void constructorWhenPathIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new VolumeMountConfigDataLocation(null))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigTreeConfigDataLocation(null))
|
||||
.withMessage("Path must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsWhenPathIsTheSameReturnsTrue() {
|
||||
VolumeMountConfigDataLocation location = new VolumeMountConfigDataLocation("/etc/config");
|
||||
VolumeMountConfigDataLocation other = new VolumeMountConfigDataLocation("/etc/config");
|
||||
ConfigTreeConfigDataLocation location = new ConfigTreeConfigDataLocation("/etc/config");
|
||||
ConfigTreeConfigDataLocation other = new ConfigTreeConfigDataLocation("/etc/config");
|
||||
assertThat(location).isEqualTo(other);
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsWhenPathIsDifferentReturnsFalse() {
|
||||
VolumeMountConfigDataLocation location = new VolumeMountConfigDataLocation("/etc/config");
|
||||
VolumeMountConfigDataLocation other = new VolumeMountConfigDataLocation("other-location");
|
||||
ConfigTreeConfigDataLocation location = new ConfigTreeConfigDataLocation("/etc/config");
|
||||
ConfigTreeConfigDataLocation other = new ConfigTreeConfigDataLocation("other-location");
|
||||
assertThat(location).isNotEqualTo(other);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringReturnsDescriptiveString() {
|
||||
VolumeMountConfigDataLocation location = new VolumeMountConfigDataLocation("/etc/config");
|
||||
assertThat(location.toString()).isEqualTo("volume mount [" + new File("/etc/config").getAbsolutePath() + "]");
|
||||
ConfigTreeConfigDataLocation location = new ConfigTreeConfigDataLocation("/etc/config");
|
||||
assertThat(location.toString()).isEqualTo("config tree [" + new File("/etc/config").getAbsolutePath() + "]");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,8 +26,8 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.convert.ApplicationConversionService;
|
||||
import org.springframework.boot.env.VolumeMountDirectoryPropertySource.Option;
|
||||
import org.springframework.boot.env.VolumeMountDirectoryPropertySource.Value;
|
||||
import org.springframework.boot.env.ConfigTreePropertySource.Option;
|
||||
import org.springframework.boot.env.ConfigTreePropertySource.Value;
|
||||
import org.springframework.boot.origin.TextResourceOrigin;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.ConfigurableConversionService;
|
||||
@@ -40,32 +40,31 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link VolumeMountDirectoryPropertySource}.
|
||||
* Tests for {@link ConfigTreePropertySource}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class VolumeMountDirectoryPropertySourceTests {
|
||||
class ConfigTreePropertySourceTests {
|
||||
|
||||
@TempDir
|
||||
Path directory;
|
||||
|
||||
@Test
|
||||
void createWhenNameIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new VolumeMountDirectoryPropertySource(null, this.directory))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigTreePropertySource(null, this.directory))
|
||||
.withMessageContaining("name must contain");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenSourceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new VolumeMountDirectoryPropertySource("test", null))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigTreePropertySource("test", null))
|
||||
.withMessage("Property source must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenSourceDoesNotExistThrowsException() {
|
||||
Path missing = this.directory.resolve("missing");
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new VolumeMountDirectoryPropertySource("test", missing))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigTreePropertySource("test", missing))
|
||||
.withMessage("Directory '" + missing + "' does not exist");
|
||||
}
|
||||
|
||||
@@ -73,45 +72,45 @@ class VolumeMountDirectoryPropertySourceTests {
|
||||
void createWhenSourceIsFileThrowsException() throws Exception {
|
||||
Path file = this.directory.resolve("file");
|
||||
FileCopyUtils.copy("test".getBytes(StandardCharsets.UTF_8), file.toFile());
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new VolumeMountDirectoryPropertySource("test", file))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ConfigTreePropertySource("test", file))
|
||||
.withMessage("File '" + file + "' is not a directory");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyNamesFromFlatReturnsPropertyNames() throws Exception {
|
||||
VolumeMountDirectoryPropertySource propertySource = getFlatPropertySource();
|
||||
ConfigTreePropertySource propertySource = getFlatPropertySource();
|
||||
assertThat(propertySource.getPropertyNames()).containsExactly("a", "b", "c");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyNamesFromNestedReturnsPropertyNames() throws Exception {
|
||||
VolumeMountDirectoryPropertySource propertySource = getNestedPropertySource();
|
||||
ConfigTreePropertySource propertySource = getNestedPropertySource();
|
||||
assertThat(propertySource.getPropertyNames()).containsExactly("c", "fa.a", "fa.b", "fb.a", "fb.fa.a");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyNamesWhenLowercaseReturnsPropertyNames() throws Exception {
|
||||
addProperty("SpRiNg", "boot");
|
||||
VolumeMountDirectoryPropertySource propertySource = new VolumeMountDirectoryPropertySource("test",
|
||||
this.directory, Option.USE_LOWERCASE_NAMES);
|
||||
ConfigTreePropertySource propertySource = new ConfigTreePropertySource("test", this.directory,
|
||||
Option.USE_LOWERCASE_NAMES);
|
||||
assertThat(propertySource.getPropertyNames()).containsExactly("spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyFromFlatReturnsFileContent() throws Exception {
|
||||
VolumeMountDirectoryPropertySource propertySource = getFlatPropertySource();
|
||||
ConfigTreePropertySource propertySource = getFlatPropertySource();
|
||||
assertThat(propertySource.getProperty("b")).hasToString("B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyFromFlatWhenMissingReturnsNull() throws Exception {
|
||||
VolumeMountDirectoryPropertySource propertySource = getFlatPropertySource();
|
||||
ConfigTreePropertySource propertySource = getFlatPropertySource();
|
||||
assertThat(propertySource.getProperty("missing")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyFromFlatWhenFileDeletedThrowsException() throws Exception {
|
||||
VolumeMountDirectoryPropertySource propertySource = getFlatPropertySource();
|
||||
ConfigTreePropertySource propertySource = getFlatPropertySource();
|
||||
Path b = this.directory.resolve("b");
|
||||
Files.delete(b);
|
||||
assertThatIllegalStateException().isThrownBy(() -> propertySource.getProperty("b").toString())
|
||||
@@ -120,7 +119,7 @@ class VolumeMountDirectoryPropertySourceTests {
|
||||
|
||||
@Test
|
||||
void getOriginFromFlatReturnsOrigin() throws Exception {
|
||||
VolumeMountDirectoryPropertySource propertySource = getFlatPropertySource();
|
||||
ConfigTreePropertySource propertySource = getFlatPropertySource();
|
||||
TextResourceOrigin origin = (TextResourceOrigin) propertySource.getOrigin("b");
|
||||
assertThat(origin.getResource().getFile()).isEqualTo(this.directory.resolve("b").toFile());
|
||||
assertThat(origin.getLocation().getLine()).isEqualTo(0);
|
||||
@@ -129,7 +128,7 @@ class VolumeMountDirectoryPropertySourceTests {
|
||||
|
||||
@Test
|
||||
void getOriginFromFlatWhenMissingReturnsNull() throws Exception {
|
||||
VolumeMountDirectoryPropertySource propertySource = getFlatPropertySource();
|
||||
ConfigTreePropertySource propertySource = getFlatPropertySource();
|
||||
assertThat(propertySource.getOrigin("missing")).isNull();
|
||||
}
|
||||
|
||||
@@ -147,13 +146,13 @@ class VolumeMountDirectoryPropertySourceTests {
|
||||
|
||||
@Test
|
||||
void getPropertyFromNestedReturnsFileContent() throws Exception {
|
||||
VolumeMountDirectoryPropertySource propertySource = getNestedPropertySource();
|
||||
ConfigTreePropertySource propertySource = getNestedPropertySource();
|
||||
assertThat(propertySource.getProperty("fb.fa.a")).hasToString("BAA");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyWhenNotAlwaysReadIgnoresUpdates() throws Exception {
|
||||
VolumeMountDirectoryPropertySource propertySource = getNestedPropertySource();
|
||||
ConfigTreePropertySource propertySource = getNestedPropertySource();
|
||||
Value v1 = propertySource.getProperty("fa.b");
|
||||
Value v2 = propertySource.getProperty("fa.b");
|
||||
assertThat(v1).isSameAs(v2);
|
||||
@@ -167,8 +166,8 @@ class VolumeMountDirectoryPropertySourceTests {
|
||||
@Test
|
||||
void getPropertyWhenAlwaysReadReflectsUpdates() throws Exception {
|
||||
addNested();
|
||||
VolumeMountDirectoryPropertySource propertySource = new VolumeMountDirectoryPropertySource("test",
|
||||
this.directory, Option.ALWAYS_READ);
|
||||
ConfigTreePropertySource propertySource = new ConfigTreePropertySource("test", this.directory,
|
||||
Option.ALWAYS_READ);
|
||||
Value v1 = propertySource.getProperty("fa.b");
|
||||
Value v2 = propertySource.getProperty("fa.b");
|
||||
assertThat(v1).isNotSameAs(v2);
|
||||
@@ -183,21 +182,21 @@ class VolumeMountDirectoryPropertySourceTests {
|
||||
@Test
|
||||
void getPropertyWhenLowercaseReturnsValue() throws Exception {
|
||||
addProperty("SpRiNg", "boot");
|
||||
VolumeMountDirectoryPropertySource propertySource = new VolumeMountDirectoryPropertySource("test",
|
||||
this.directory, Option.USE_LOWERCASE_NAMES);
|
||||
ConfigTreePropertySource propertySource = new ConfigTreePropertySource("test", this.directory,
|
||||
Option.USE_LOWERCASE_NAMES);
|
||||
assertThat(propertySource.getProperty("spring")).hasToString("boot");
|
||||
}
|
||||
|
||||
private VolumeMountDirectoryPropertySource getFlatPropertySource() throws IOException {
|
||||
private ConfigTreePropertySource getFlatPropertySource() throws IOException {
|
||||
addProperty("a", "A");
|
||||
addProperty("b", "B");
|
||||
addProperty("c", "C");
|
||||
return new VolumeMountDirectoryPropertySource("test", this.directory);
|
||||
return new ConfigTreePropertySource("test", this.directory);
|
||||
}
|
||||
|
||||
private VolumeMountDirectoryPropertySource getNestedPropertySource() throws IOException {
|
||||
private ConfigTreePropertySource getNestedPropertySource() throws IOException {
|
||||
addNested();
|
||||
return new VolumeMountDirectoryPropertySource("test", this.directory);
|
||||
return new ConfigTreePropertySource("test", this.directory);
|
||||
}
|
||||
|
||||
private void addNested() throws IOException {
|
||||
Reference in New Issue
Block a user