Skip to content

Commit

Permalink
Merge default property sources
Browse files Browse the repository at this point in the history
Fixes gh-25408
  • Loading branch information
mbhave committed Mar 4, 2021
1 parent ca41473 commit 181d0ee
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.springframework.boot;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

Expand Down Expand Up @@ -72,6 +73,40 @@ public static void ifNotEmpty(Map<String, Object> source, Consumer<DefaultProper
}
}

/**
* Add a new {@link DefaultPropertiesPropertySource} or merge with an existing one.
* @param source the {@code Map} source
* @param sources the existing sources
* @since 2.4.4
*/
public static void addOrMerge(Map<String, Object> source, MutablePropertySources sources) {
if (!CollectionUtils.isEmpty(source)) {
Map<String, Object> resultingSource = new HashMap<>();
DefaultPropertiesPropertySource propertySource = new DefaultPropertiesPropertySource(resultingSource);
if (sources.contains(NAME)) {
mergeIfPossible(source, sources, resultingSource);
sources.replace(NAME, propertySource);
}
else {
resultingSource.putAll(source);
sources.addLast(propertySource);
}
}
}

@SuppressWarnings("unchecked")
private static void mergeIfPossible(Map<String, Object> source, MutablePropertySources sources,
Map<String, Object> resultingSource) {
PropertySource<?> existingSource = sources.get(NAME);
if (existingSource != null) {
Object underlyingSource = existingSource.getSource();
if (underlyingSource instanceof Map) {
resultingSource.putAll((Map<String, Object>) underlyingSource);
}
resultingSource.putAll(source);
}
}

/**
* Move the 'defaultProperties' property source so that it's the last source in the
* given {@link ConfigurableEnvironment}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,9 @@ protected void configureEnvironment(ConfigurableEnvironment environment, String[
*/
protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
MutablePropertySources sources = environment.getPropertySources();
DefaultPropertiesPropertySource.ifNotEmpty(this.defaultProperties, sources::addLast);
if (!CollectionUtils.isEmpty(this.defaultProperties)) {
DefaultPropertiesPropertySource.addOrMerge(this.defaultProperties, sources);
}
if (this.addCommandLineProperties && args.length > 0) {
String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
if (sources.contains(name)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
Expand All @@ -39,6 +40,7 @@
* Tests for {@link DefaultPropertiesPropertySource}.
*
* @author Phillip Webb
* @author Madhura Bhave
*/
@ExtendWith(MockitoExtension.class)
class DefaultPropertiesPropertySourceTests {
Expand Down Expand Up @@ -104,6 +106,39 @@ void moveToEndWhenNotPresentDoesNothing() {
DefaultPropertiesPropertySource.moveToEnd(environment);
}

@Test
void addOrMergeWhenExistingNotFoundShouldAdd() {
MockEnvironment environment = new MockEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
DefaultPropertiesPropertySource.addOrMerge(Collections.singletonMap("spring", "boot"), propertySources);
assertThat(propertySources.contains(DefaultPropertiesPropertySource.NAME)).isTrue();
assertThat(propertySources.get(DefaultPropertiesPropertySource.NAME).getProperty("spring")).isEqualTo("boot");
}

@Test
void addOrMergeWhenExistingFoundShouldMerge() {
MockEnvironment environment = new MockEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
propertySources.addLast(new DefaultPropertiesPropertySource(Collections.singletonMap("spring", "boot")));
DefaultPropertiesPropertySource.addOrMerge(Collections.singletonMap("hello", "world"), propertySources);
assertThat(propertySources.contains(DefaultPropertiesPropertySource.NAME)).isTrue();
assertThat(propertySources.get(DefaultPropertiesPropertySource.NAME).getProperty("spring")).isEqualTo("boot");
assertThat(propertySources.get(DefaultPropertiesPropertySource.NAME).getProperty("hello")).isEqualTo("world");
}

@Test
void addOrMergeWhenExistingNotMapPropertySourceShouldNotMerge() {
MockEnvironment environment = new MockEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
CompositePropertySource composite = new CompositePropertySource(DefaultPropertiesPropertySource.NAME);
composite.addPropertySource(new DefaultPropertiesPropertySource(Collections.singletonMap("spring", "boot")));
propertySources.addFirst(composite);
DefaultPropertiesPropertySource.addOrMerge(Collections.singletonMap("hello", "world"), propertySources);
assertThat(propertySources.contains(DefaultPropertiesPropertySource.NAME)).isTrue();
assertThat(propertySources.get(DefaultPropertiesPropertySource.NAME).getProperty("spring")).isNull();
assertThat(propertySources.get(DefaultPropertiesPropertySource.NAME).getProperty("hello")).isEqualTo("world");
}

@Test
void moveToEndWhenPresentMovesToEnd() {
MockEnvironment environment = new MockEnvironment();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.springframework.boot.availability.AvailabilityState;
import org.springframework.boot.availability.LivenessState;
import org.springframework.boot.availability.ReadinessState;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.event.ApplicationContextInitializedEvent;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.event.ApplicationFailedEvent;
Expand Down Expand Up @@ -105,6 +106,7 @@
import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.core.metrics.StartupStep;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.test.context.support.TestPropertySourceUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
Expand Down Expand Up @@ -887,6 +889,18 @@ void defaultCommandLineArgs() {
assertThat(getEnvironment().getProperty("baz")).isEqualTo("");
}

@Test
void defaultPropertiesShouldBeMerged() {
MockEnvironment environment = new MockEnvironment();
environment.getPropertySources().addFirst(
new MapPropertySource(DefaultPropertiesPropertySource.NAME, Collections.singletonMap("bar", "foo")));
SpringApplication application = new SpringApplicationBuilder(ExampleConfig.class).environment(environment)
.properties("baz=bing").web(WebApplicationType.NONE).build();
this.context = application.run();
assertThat(getEnvironment().getProperty("bar")).isEqualTo("foo");
assertThat(getEnvironment().getProperty("baz")).isEqualTo("bing");
}

@Test
void commandLineArgsApplyToSpringApplication() {
TestSpringApplication application = new TestSpringApplication(ExampleConfig.class);
Expand Down

0 comments on commit 181d0ee

Please sign in to comment.