Commit 4fc0dec6 authored by Phillip Webb's avatar Phillip Webb

Support wrapped random property sources

Update `SpringConfigurationPropertySource` so that wrapped random
property sources can be used. It's assumed that wrapped random
sources will use the name of the source as the prefix.

Closes gh-21595
parent 09a47c9a
...@@ -20,6 +20,7 @@ import java.util.Map; ...@@ -20,6 +20,7 @@ import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.function.Function; import java.util.function.Function;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName.Form;
import org.springframework.boot.origin.Origin; import org.springframework.boot.origin.Origin;
import org.springframework.boot.origin.PropertySourceOrigin; import org.springframework.boot.origin.PropertySourceOrigin;
import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.EnumerablePropertySource;
...@@ -53,8 +54,6 @@ import org.springframework.util.ObjectUtils; ...@@ -53,8 +54,6 @@ import org.springframework.util.ObjectUtils;
*/ */
class SpringConfigurationPropertySource implements ConfigurationPropertySource { class SpringConfigurationPropertySource implements ConfigurationPropertySource {
private static final ConfigurationPropertyName RANDOM = ConfigurationPropertyName.of("random");
private final PropertySource<?> propertySource; private final PropertySource<?> propertySource;
private final PropertyMapper mapper; private final PropertyMapper mapper;
...@@ -184,13 +183,19 @@ class SpringConfigurationPropertySource implements ConfigurationPropertySource { ...@@ -184,13 +183,19 @@ class SpringConfigurationPropertySource implements ConfigurationPropertySource {
private static Function<ConfigurationPropertyName, ConfigurationPropertyState> getContainsDescendantOfForSource( private static Function<ConfigurationPropertyName, ConfigurationPropertyState> getContainsDescendantOfForSource(
PropertySource<?> source) { PropertySource<?> source) {
if (source.getSource() instanceof Random) { if (source.getSource() instanceof Random) {
return SpringConfigurationPropertySource::containsDescendantOfForRandom; return (name) -> containsDescendantOfForRandom("random", name);
}
if (source.getSource() instanceof PropertySource<?>
&& ((PropertySource<?>) source.getSource()).getSource() instanceof Random) {
// Assume wrapped random sources use the source name as the prefix
return (name) -> containsDescendantOfForRandom(source.getName(), name);
} }
return null; return null;
} }
private static ConfigurationPropertyState containsDescendantOfForRandom(ConfigurationPropertyName name) { private static ConfigurationPropertyState containsDescendantOfForRandom(String prefix,
if (RANDOM.isAncestorOf(name) || name.equals(RANDOM)) { ConfigurationPropertyName name) {
if (name.getNumberOfElements() > 1 && name.getElement(0, Form.DASHED).equals(prefix)) {
return ConfigurationPropertyState.PRESENT; return ConfigurationPropertyState.PRESENT;
} }
return ConfigurationPropertyState.ABSENT; return ConfigurationPropertyState.ABSENT;
......
...@@ -62,14 +62,14 @@ public class RandomValuePropertySource extends PropertySource<Random> { ...@@ -62,14 +62,14 @@ public class RandomValuePropertySource extends PropertySource<Random> {
private static final Log logger = LogFactory.getLog(RandomValuePropertySource.class); private static final Log logger = LogFactory.getLog(RandomValuePropertySource.class);
public RandomValuePropertySource(String name) {
super(name, new Random());
}
public RandomValuePropertySource() { public RandomValuePropertySource() {
this(RANDOM_PROPERTY_SOURCE_NAME); this(RANDOM_PROPERTY_SOURCE_NAME);
} }
public RandomValuePropertySource(String name) {
super(name, new Random());
}
@Override @Override
public Object getProperty(String name) { public Object getProperty(String name) {
if (!name.startsWith(PREFIX)) { if (!name.startsWith(PREFIX)) {
......
...@@ -153,24 +153,105 @@ class SpringConfigurationPropertySourceTests { ...@@ -153,24 +153,105 @@ class SpringConfigurationPropertySourceTests {
void containsDescendantOfWhenRandomSourceAndRandomPropertyReturnsPresent() { void containsDescendantOfWhenRandomSourceAndRandomPropertyReturnsPresent() {
SpringConfigurationPropertySource source = SpringConfigurationPropertySource SpringConfigurationPropertySource source = SpringConfigurationPropertySource
.from(new RandomValuePropertySource()); .from(new RandomValuePropertySource());
assertThat(source.containsDescendantOf(ConfigurationPropertyName.of("random"))) ConfigurationPropertyName name = ConfigurationPropertyName.of("random");
.isEqualTo(ConfigurationPropertyState.PRESENT); assertThat(source.containsDescendantOf(name)).isEqualTo(ConfigurationPropertyState.ABSENT);
assertThat(source.getConfigurationProperty(name)).isNull();
} }
@Test @Test
void containsDescendantOfWhenRandomSourceAndRandomPrefixedPropertyReturnsPresent() { void containsDescendantOfWhenRandomSourceAndRandomPrefixedPropertyReturnsPresent() {
SpringConfigurationPropertySource source = SpringConfigurationPropertySource SpringConfigurationPropertySource source = SpringConfigurationPropertySource
.from(new RandomValuePropertySource()); .from(new RandomValuePropertySource());
assertThat(source.containsDescendantOf(ConfigurationPropertyName.of("random.something"))) ConfigurationPropertyName name = ConfigurationPropertyName.of("random.int");
.isEqualTo(ConfigurationPropertyState.PRESENT); assertThat(source.containsDescendantOf(name)).isEqualTo(ConfigurationPropertyState.PRESENT);
assertThat(source.getConfigurationProperty(name)).isNotNull();
}
@Test
void containsDescendantOfWhenRandomSourceWithDifferentNameAndRandomPrefixedPropertyReturnsPresent() {
SpringConfigurationPropertySource source = SpringConfigurationPropertySource
.from(new RandomValuePropertySource("different"));
ConfigurationPropertyName name = ConfigurationPropertyName.of("random.int");
assertThat(source.containsDescendantOf(name)).isEqualTo(ConfigurationPropertyState.PRESENT);
assertThat(source.getConfigurationProperty(name)).isNotNull();
} }
@Test @Test
void containsDescendantOfWhenRandomSourceAndNonRandomPropertyReturnsAbsent() { void containsDescendantOfWhenRandomSourceAndNonRandomPropertyReturnsAbsent() {
SpringConfigurationPropertySource source = SpringConfigurationPropertySource SpringConfigurationPropertySource source = SpringConfigurationPropertySource
.from(new RandomValuePropertySource()); .from(new RandomValuePropertySource());
assertThat(source.containsDescendantOf(ConfigurationPropertyName.of("abandon.something"))) ConfigurationPropertyName name = ConfigurationPropertyName.of("abandon.int");
.isEqualTo(ConfigurationPropertyState.ABSENT); assertThat(source.containsDescendantOf(name)).isEqualTo(ConfigurationPropertyState.ABSENT);
assertThat(source.getConfigurationProperty(name)).isNull();
}
@Test
void containsDescendantOfWhenWrappedRandomSourceAndRandomPropertyReturnsPresent() {
SpringConfigurationPropertySource source = SpringConfigurationPropertySource
.from(new RandomWrapperPropertySource());
ConfigurationPropertyName name = ConfigurationPropertyName.of("cachedrandom");
assertThat(source.containsDescendantOf(name)).isEqualTo(ConfigurationPropertyState.ABSENT);
assertThat(source.getConfigurationProperty(name)).isNull();
}
@Test
void containsDescendantOfWhenWrappedRandomSourceAndRandomPrefixedPropertyReturnsPresent() {
SpringConfigurationPropertySource source = SpringConfigurationPropertySource
.from(new RandomWrapperPropertySource());
ConfigurationPropertyName name = ConfigurationPropertyName.of("cachedrandom.something.int");
assertThat(source.containsDescendantOf(name)).isEqualTo(ConfigurationPropertyState.ABSENT);
assertThat(source.getConfigurationProperty(name)).isNull();
}
@Test
void containsDescendantOfWhenWrappedRandomSourceWithMatchingNameAndRandomPrefixedPropertyReturnsPresent() {
SpringConfigurationPropertySource source = SpringConfigurationPropertySource
.from(new RandomWrapperPropertySource("cachedrandom"));
ConfigurationPropertyName name = ConfigurationPropertyName.of("cachedrandom.something.int");
assertThat(source.containsDescendantOf(name)).isEqualTo(ConfigurationPropertyState.PRESENT);
assertThat(source.getConfigurationProperty(name)).isNotNull();
}
@Test
void containsDescendantOfWhenWrappedRandomSourceAndRandomDashPrefixedPropertyReturnsPresent() {
SpringConfigurationPropertySource source = SpringConfigurationPropertySource
.from(new RandomWrapperPropertySource());
ConfigurationPropertyName name = ConfigurationPropertyName.of("cached-random.something.int");
assertThat(source.containsDescendantOf(name)).isEqualTo(ConfigurationPropertyState.ABSENT);
assertThat(source.getConfigurationProperty(name)).isNull();
}
@Test
void containsDescendantOfWhenWrappedRandomSourceAndNonRandomPropertyReturnsAbsent() {
SpringConfigurationPropertySource source = SpringConfigurationPropertySource
.from(new RandomWrapperPropertySource());
ConfigurationPropertyName name = ConfigurationPropertyName.of("abandon.something.int");
assertThat(source.containsDescendantOf(name)).isEqualTo(ConfigurationPropertyState.ABSENT);
assertThat(source.getConfigurationProperty(name)).isNull();
}
static class RandomWrapperPropertySource extends PropertySource<RandomValuePropertySource> {
private final String prefix;
RandomWrapperPropertySource() {
this("cachedRandom");
}
RandomWrapperPropertySource(String name) {
super(name, new RandomValuePropertySource());
this.prefix = name + ".";
}
@Override
public Object getProperty(String name) {
name = name.toLowerCase();
if (!name.startsWith(this.prefix)) {
return null;
}
return getSource().getProperty("random." + name.substring(this.prefix.length()));
}
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment