Browse Source
We configure the `SystemEnvironmentPropertySource` as a `Prefixed` property source. When adapting this to a `ConfigurationPropertySource, a `PrefixedConfigurationPropertySource` will be created for it. A `PrefixedConfigurationPropertySource` will resolve property such as `foo.bar` to `my.foo.bar` for a prefix of `my`. Closes gh-3450pull/25445/head
14 changed files with 416 additions and 17 deletions
@ -0,0 +1,72 @@
@@ -0,0 +1,72 @@
|
||||
/* |
||||
* Copyright 2012-2021 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.context.properties.source; |
||||
|
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* A {@link ConfigurationPropertySource} supporting a prefix. |
||||
* |
||||
* @author Madhura Bhave |
||||
*/ |
||||
class PrefixedConfigurationPropertySource implements ConfigurationPropertySource { |
||||
|
||||
private final ConfigurationPropertySource source; |
||||
|
||||
private final String prefix; |
||||
|
||||
PrefixedConfigurationPropertySource(ConfigurationPropertySource source, String prefix) { |
||||
Assert.notNull(source, "Source must not be null"); |
||||
Assert.notNull(prefix, "Prefix must not be null"); |
||||
this.source = source; |
||||
this.prefix = prefix; |
||||
} |
||||
|
||||
@Override |
||||
public ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name) { |
||||
ConfigurationProperty configurationProperty = this.source.getConfigurationProperty(getPrefixedName(name)); |
||||
if (configurationProperty == null) { |
||||
return null; |
||||
} |
||||
return ConfigurationProperty.of(name, configurationProperty.getValue(), configurationProperty.getOrigin()); |
||||
} |
||||
|
||||
private ConfigurationPropertyName getPrefixedName(ConfigurationPropertyName name) { |
||||
String prefix = (StringUtils.hasText(this.prefix)) ? this.prefix + "." : ""; |
||||
return ConfigurationPropertyName.of(prefix + name); |
||||
} |
||||
|
||||
@Override |
||||
public ConfigurationPropertyState containsDescendantOf(ConfigurationPropertyName name) { |
||||
return this.source.containsDescendantOf(getPrefixedName(name)); |
||||
} |
||||
|
||||
@Override |
||||
public Object getUnderlyingSource() { |
||||
return this.source.getUnderlyingSource(); |
||||
} |
||||
|
||||
protected ConfigurationPropertySource getSource() { |
||||
return this.source; |
||||
} |
||||
|
||||
protected String getPrefix() { |
||||
return this.prefix; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
/* |
||||
* Copyright 2012-2021 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.context.properties.source; |
||||
|
||||
import java.util.stream.Stream; |
||||
|
||||
/** |
||||
* An iterable {@link PrefixedConfigurationPropertySource}. |
||||
* |
||||
* @author Madhura Bhave |
||||
*/ |
||||
class PrefixedIterableConfigurationPropertySource extends PrefixedConfigurationPropertySource |
||||
implements IterableConfigurationPropertySource { |
||||
|
||||
PrefixedIterableConfigurationPropertySource(IterableConfigurationPropertySource source, String prefix) { |
||||
super(source, prefix); |
||||
} |
||||
|
||||
@Override |
||||
public Stream<ConfigurationPropertyName> stream() { |
||||
ConfigurationPropertyName prefix = ConfigurationPropertyName.of(getPrefix()); |
||||
return getSource().stream().map((propertyName) -> { |
||||
if (prefix.isAncestorOf(propertyName)) { |
||||
String name = propertyName.toString(); |
||||
return ConfigurationPropertyName.of(name.substring(getPrefix().length() + 1)); |
||||
} |
||||
return propertyName; |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
protected IterableConfigurationPropertySource getSource() { |
||||
return (IterableConfigurationPropertySource) super.getSource(); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
/* |
||||
* Copyright 2012-2021 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.env; |
||||
|
||||
/** |
||||
* Interface that can be implemented by a |
||||
* {@link org.springframework.core.env.PropertySource} that can be used with a prefix. |
||||
* |
||||
* @author Madhura Bhave |
||||
* @since 2.5.0 |
||||
*/ |
||||
@FunctionalInterface |
||||
public interface Prefixed { |
||||
|
||||
String getPrefix(); |
||||
|
||||
} |
||||
@ -0,0 +1,89 @@
@@ -0,0 +1,89 @@
|
||||
/* |
||||
* Copyright 2012-2021 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.context.properties.source; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
import org.mockito.Answers; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.BDDMockito.given; |
||||
import static org.mockito.Mockito.mock; |
||||
|
||||
/** |
||||
* Tests for {@link PrefixedConfigurationPropertySource}. |
||||
* |
||||
* @author Madhura Bhave |
||||
*/ |
||||
class PrefixedConfigurationPropertySourceTests { |
||||
|
||||
@Test |
||||
void getConfigurationPropertyShouldConsiderPrefix() { |
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource(); |
||||
source.put("my.foo.bar", "bing"); |
||||
source.put("my.foo.baz", "biff"); |
||||
ConfigurationPropertySource prefixed = source.nonIterable().withPrefix("my"); |
||||
assertThat(getName(prefixed, "foo.bar").toString()).isEqualTo("foo.bar"); |
||||
assertThat(getValue(prefixed, "foo.bar")).isEqualTo("bing"); |
||||
assertThat(getName(prefixed, "foo.baz").toString()).isEqualTo("foo.baz"); |
||||
assertThat(getValue(prefixed, "foo.baz")).isEqualTo("biff"); |
||||
} |
||||
|
||||
@Test |
||||
void containsDescendantOfWhenSourceReturnsUnknownShouldReturnUnknown() { |
||||
ConfigurationPropertyName name = ConfigurationPropertyName.of("my.foo"); |
||||
ConfigurationPropertySource source = mock(ConfigurationPropertySource.class, Answers.CALLS_REAL_METHODS); |
||||
given(source.containsDescendantOf(name)).willReturn(ConfigurationPropertyState.UNKNOWN); |
||||
ConfigurationPropertySource prefixed = source.withPrefix("my"); |
||||
assertThat(prefixed.containsDescendantOf(ConfigurationPropertyName.of("foo"))) |
||||
.isEqualTo(ConfigurationPropertyState.UNKNOWN); |
||||
} |
||||
|
||||
@Test |
||||
void containsDescendantOfWhenSourceReturnsPresentShouldReturnPresent() { |
||||
ConfigurationPropertyName name = ConfigurationPropertyName.of("my.foo"); |
||||
ConfigurationPropertySource source = mock(ConfigurationPropertySource.class, Answers.CALLS_REAL_METHODS); |
||||
given(source.containsDescendantOf(name)).willReturn(ConfigurationPropertyState.PRESENT); |
||||
given(source.containsDescendantOf(ConfigurationPropertyName.of("bar"))) |
||||
.willReturn(ConfigurationPropertyState.UNKNOWN); |
||||
ConfigurationPropertySource prefixed = source.withPrefix("my"); |
||||
assertThat(prefixed.containsDescendantOf(ConfigurationPropertyName.of("foo"))) |
||||
.isEqualTo(ConfigurationPropertyState.PRESENT); |
||||
} |
||||
|
||||
@Test |
||||
void containsDescendantOfWhenSourceReturnsAbsentShouldReturnAbsent() { |
||||
ConfigurationPropertyName name = ConfigurationPropertyName.of("my.foo"); |
||||
ConfigurationPropertySource source = mock(ConfigurationPropertySource.class, Answers.CALLS_REAL_METHODS); |
||||
given(source.containsDescendantOf(name)).willReturn(ConfigurationPropertyState.ABSENT); |
||||
given(source.containsDescendantOf(ConfigurationPropertyName.of("bar"))) |
||||
.willReturn(ConfigurationPropertyState.ABSENT); |
||||
ConfigurationPropertySource prefixed = source.withPrefix("my"); |
||||
assertThat(prefixed.containsDescendantOf(ConfigurationPropertyName.of("foo"))) |
||||
.isEqualTo(ConfigurationPropertyState.ABSENT); |
||||
} |
||||
|
||||
private ConfigurationPropertyName getName(ConfigurationPropertySource source, String name) { |
||||
ConfigurationProperty property = source.getConfigurationProperty(ConfigurationPropertyName.of(name)); |
||||
return (property != null) ? property.getName() : null; |
||||
} |
||||
|
||||
private Object getValue(ConfigurationPropertySource source, String name) { |
||||
ConfigurationProperty property = source.getConfigurationProperty(ConfigurationPropertyName.of(name)); |
||||
return (property != null) ? property.getValue() : null; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
/* |
||||
* Copyright 2012-2021 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.context.properties.source; |
||||
|
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link PrefixedIterableConfigurationPropertySource}. |
||||
* |
||||
* @author Madhura Bhave |
||||
*/ |
||||
class PrefixedIterableConfigurationPropertySourceTests { |
||||
|
||||
@Test |
||||
void streamShouldConsiderPrefix() { |
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource(); |
||||
source.put("my.foo.bar", "bing"); |
||||
source.put("my.foo.baz", "biff"); |
||||
source.put("hello.bing", "blah"); |
||||
IterableConfigurationPropertySource prefixed = source.withPrefix("my"); |
||||
assertThat(prefixed.stream()).containsExactly(ConfigurationPropertyName.of("foo.bar"), |
||||
ConfigurationPropertyName.of("foo.baz"), ConfigurationPropertyName.of("hello.bing")); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue