Consider aliases when checking descendants
Update `AliasedConfigurationPropertySource` to consider aliases in `containsDescendantOf`. Prior to this commit, given a source containing `example.name` with a defined alias of `other.name -> example.name` calling `containsDescendantOf("other")` would incorrectly return `ConfigurationPropertyState.ABSENT`. Closes gh-14967
This commit is contained in:
parent
7bb6df4206
commit
256ca681fd
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.boot.context.properties.source;
|
package org.springframework.boot.context.properties.source;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,11 +60,17 @@ class AliasedConfigurationPropertySource implements ConfigurationPropertySource
|
||||||
if (result != ConfigurationPropertyState.ABSENT) {
|
if (result != ConfigurationPropertyState.ABSENT) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
for (ConfigurationPropertyName alias : getAliases().getAliases(name)) {
|
Set<ConfigurationPropertyName> aliasNames = this.aliases.getAllNames();
|
||||||
ConfigurationPropertyState aliasResult = this.source
|
for (ConfigurationPropertyName configurationPropertyName : aliasNames) {
|
||||||
.containsDescendantOf(alias);
|
boolean descendantPresentInAlias = this.aliases
|
||||||
if (aliasResult != ConfigurationPropertyState.ABSENT) {
|
.getAliases(configurationPropertyName).stream()
|
||||||
return aliasResult;
|
.filter(name::isAncestorOf).findFirst().isPresent();
|
||||||
|
if (descendantPresentInAlias) {
|
||||||
|
ConfigurationProperty configurationProperty = this.getSource()
|
||||||
|
.getConfigurationProperty(configurationPropertyName);
|
||||||
|
if (configurationProperty != null) {
|
||||||
|
return ConfigurationPropertyState.PRESENT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ConfigurationPropertyState.ABSENT;
|
return ConfigurationPropertyState.ABSENT;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
@ -74,4 +75,8 @@ public final class ConfigurationPropertyNameAliases {
|
||||||
.findFirst().orElse(null);
|
.findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<ConfigurationPropertyName> getAllNames() {
|
||||||
|
return this.aliases.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ package org.springframework.boot.context.properties.source;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.Answers;
|
import org.mockito.Answers;
|
||||||
|
|
||||||
|
import org.springframework.boot.origin.Origin;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
@ -105,8 +107,30 @@ public class AliasedConfigurationPropertySourceTests {
|
||||||
.willReturn(ConfigurationPropertyState.ABSENT);
|
.willReturn(ConfigurationPropertyState.ABSENT);
|
||||||
given(source.containsDescendantOf(ConfigurationPropertyName.of("bar")))
|
given(source.containsDescendantOf(ConfigurationPropertyName.of("bar")))
|
||||||
.willReturn(ConfigurationPropertyState.PRESENT);
|
.willReturn(ConfigurationPropertyState.PRESENT);
|
||||||
|
ConfigurationPropertyName barBar = ConfigurationPropertyName.of("bar.bar");
|
||||||
|
given(source.getConfigurationProperty(barBar)).willReturn(
|
||||||
|
new ConfigurationProperty(barBar, "barBarValue", mock(Origin.class)));
|
||||||
ConfigurationPropertySource aliased = source
|
ConfigurationPropertySource aliased = source
|
||||||
.withAliases(new ConfigurationPropertyNameAliases("foo", "bar"));
|
.withAliases(new ConfigurationPropertyNameAliases("bar.bar", "foo.foo"));
|
||||||
|
assertThat(aliased.containsDescendantOf(name))
|
||||||
|
.isEqualTo(ConfigurationPropertyState.PRESENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void containsDescendantOfWhenPresentInAliasShouldReturnPresent() {
|
||||||
|
ConfigurationPropertyName name = ConfigurationPropertyName.of("baz");
|
||||||
|
ConfigurationPropertySource source = mock(ConfigurationPropertySource.class,
|
||||||
|
withSettings().defaultAnswer(Answers.CALLS_REAL_METHODS));
|
||||||
|
given(source.containsDescendantOf(name))
|
||||||
|
.willReturn(ConfigurationPropertyState.ABSENT);
|
||||||
|
|
||||||
|
ConfigurationPropertyName barFoo = ConfigurationPropertyName.of("bar.foo");
|
||||||
|
|
||||||
|
given(source.getConfigurationProperty(barFoo)).willReturn(
|
||||||
|
new ConfigurationProperty(barFoo, "barFooValue", mock(Origin.class)));
|
||||||
|
|
||||||
|
ConfigurationPropertySource aliased = source
|
||||||
|
.withAliases(new ConfigurationPropertyNameAliases("bar.foo", "baz.foo"));
|
||||||
assertThat(aliased.containsDescendantOf(name))
|
assertThat(aliased.containsDescendantOf(name))
|
||||||
.isEqualTo(ConfigurationPropertyState.PRESENT);
|
.isEqualTo(ConfigurationPropertyState.PRESENT);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue