diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java index 3933abfd..0c868645 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java @@ -16,6 +16,7 @@ package org.springframework.cloud.bootstrap.encrypt; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; @@ -184,9 +185,11 @@ public class EnvironmentDecryptApplicationInitializer implements Map overrides) { if (source instanceof CompositePropertySource) { + List> propertySources = new ArrayList<>( + ((CompositePropertySource) source).getPropertySources()); + Collections.reverse(propertySources); - for (PropertySource nested : ((CompositePropertySource) source) - .getPropertySources()) { + for (PropertySource nested : propertySources) { collectEncryptedProperties(nested, overrides); } diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializerTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializerTests.java index 54ac03a4..a74906ee 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializerTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializerTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.bootstrap.encrypt; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import org.junit.Test; @@ -36,7 +37,6 @@ import org.springframework.security.crypto.encrypt.TextEncryptor; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -168,23 +168,31 @@ public class EnvironmentDecryptApplicationInitializerTests { @Test public void testDecryptCompositePropertySource() { - String expected = "always"; - TextEncryptor textEncryptor = mock(TextEncryptor.class); - when(textEncryptor.decrypt(anyString())).thenReturn(expected); - ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(); EnvironmentDecryptApplicationInitializer initializer = new EnvironmentDecryptApplicationInitializer( - textEncryptor); + Encryptors.noOpText()); - MapPropertySource source = new MapPropertySource("nobody", - Collections.singletonMap("key", "{cipher}value")); - CompositePropertySource cps = mock(CompositePropertySource.class); - when(cps.getPropertyNames()).thenReturn(source.getPropertyNames()); - when(cps.getPropertySources()).thenReturn(Collections.singleton(source)); + CompositePropertySource cps = new CompositePropertySource("testCPS"); + Map map1 = new HashMap<>(); + map1.put("key1", "{cipher}value1b"); + map1.put("key2", "value2b"); + cps.addPropertySource(new MapPropertySource("profile1", map1)); + Map map2 = new HashMap<>(); + map2.put("key1", "{cipher}value1"); + map2.put("key2", "value2"); + map1.put("key3", "value3"); + cps.addPropertySource(new MapPropertySource("profile2", map2)); + // add non-enumerable property source that will fail cps.getPropertyNames() + cps.addPropertySource(mock(PropertySource.class)); ctx.getEnvironment().getPropertySources().addLast(cps); initializer.initialize(ctx); - assertEquals(expected, ctx.getEnvironment().getProperty("key")); + // validate behaviour with encryption + assertEquals("value1b", ctx.getEnvironment().getProperty("key1")); + // validate behaviour without encryption + assertEquals("value2b", ctx.getEnvironment().getProperty("key2")); + // validate behaviour without override + assertEquals("value3", ctx.getEnvironment().getProperty("key3")); } @Test