Fix caching issues with map property sources

Update `SpringIterableConfigurationPropertySource` so that the cache
key from a `MapPropertySource` is invalidated when the map contents
changes.

Prior to this commit, the actual keys of the map were used as the key.
This meant that if the underlying map changed, they key wouldn't be
invalidated because it ultimately pointed to the same object instance.

See gh-13344
This commit is contained in:
Fahim Farook 2018-06-04 00:06:13 +05:30 committed by Phillip Webb
parent 461202bc25
commit c556d2b58f
3 changed files with 33 additions and 4 deletions

View File

@ -142,9 +142,7 @@ class SpringIterableConfigurationPropertySource extends SpringConfigurationPrope
}
private Object getCacheKey() {
if (getPropertySource() instanceof MapPropertySource) {
return ((MapPropertySource) getPropertySource()).getSource().keySet();
}
// gh-13344
return getPropertySource().getPropertyNames();
}

View File

@ -76,6 +76,7 @@ import static org.hamcrest.Matchers.not;
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Ben Hale
* @author Fahim Farook
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions("log4j*.jar")
@ -500,12 +501,23 @@ public class LoggingApplicationListenerTests {
@Test
public void environmentPropertiesIgnoreUnresolvablePlaceholders() {
// gh-7719
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context,
"logging.pattern.console=console ${doesnotexist}");
this.initializer.initialize(this.context.getEnvironment(),
this.context.getClassLoader());
assertThat(System.getProperty(LoggingSystemProperties.CONSOLE_LOG_PATTERN))
.isEqualTo("console ${doesnotexist}");
}
@Test
public void environmentPropertiesResolvePlaceholders() {
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context,
"logging.pattern.console=console ${pid}");
this.initializer.initialize(this.context.getEnvironment(),
this.context.getClassLoader());
assertThat(System.getProperty(LoggingSystemProperties.CONSOLE_LOG_PATTERN))
.isEqualTo("console ${pid}");
.isEqualTo(this.context.getEnvironment()
.getProperty("logging.pattern.console"));
}
@Test

View File

@ -37,6 +37,7 @@ import static org.mockito.Mockito.mock;
*
* @author Phillip Webb
* @author Madhura Bhave
* @author Fahim Farook
*/
public class SpringIterableConfigurationPropertySourceTests {
@ -157,6 +158,24 @@ public class SpringIterableConfigurationPropertySourceTests {
.isEqualTo(ConfigurationPropertyState.ABSENT);
}
@SuppressWarnings("unchecked")
@Test
public void propertySourceChangeReflects() {
// gh-13344
final Map<String, Object> source = new LinkedHashMap<>();
source.put("key1", "value1");
source.put("key2", "value2");
final EnumerablePropertySource<?> propertySource = new MapPropertySource("test",
source);
final SpringIterableConfigurationPropertySource adapter = new SpringIterableConfigurationPropertySource(
propertySource, DefaultPropertyMapper.INSTANCE);
assertThat(adapter.stream().count()).isEqualTo(2);
((Map<String, Object>) adapter.getPropertySource().getSource()).put("key3",
"value3");
assertThat(adapter.stream().count()).isEqualTo(3);
}
/**
* Test {@link PropertySource} that's also an {@link OriginLookup}.
*/