diff --git a/spring-cloud-aws-parameter-store-config/src/main/java/org/springframework/cloud/aws/paramstore/AwsParamStorePropertySourceLocator.java b/spring-cloud-aws-parameter-store-config/src/main/java/org/springframework/cloud/aws/paramstore/AwsParamStorePropertySourceLocator.java index 4caa4ed32..0d1cc215f 100644 --- a/spring-cloud-aws-parameter-store-config/src/main/java/org/springframework/cloud/aws/paramstore/AwsParamStorePropertySourceLocator.java +++ b/spring-cloud-aws-parameter-store-config/src/main/java/org/springframework/cloud/aws/paramstore/AwsParamStorePropertySourceLocator.java @@ -124,9 +124,9 @@ private AwsParamStorePropertySource create(String context) { private void addProfiles(Set contexts, String baseContext, List profiles) { - for (String profile : profiles) { - contexts.add( - baseContext + this.properties.getProfileSeparator() + profile + "/"); + for (int index = profiles.size() - 1; index >= 0; --index) { + contexts.add(baseContext + this.properties.getProfileSeparator() + + profiles.get(index) + "/"); } } diff --git a/spring-cloud-aws-parameter-store-config/src/test/java/org/springframework/cloud/aws/paramstore/AwsParamStorePropertySourceLocatorTest.java b/spring-cloud-aws-parameter-store-config/src/test/java/org/springframework/cloud/aws/paramstore/AwsParamStorePropertySourceLocatorTest.java index d6ab4041d..82a4d3950 100644 --- a/spring-cloud-aws-parameter-store-config/src/test/java/org/springframework/cloud/aws/paramstore/AwsParamStorePropertySourceLocatorTest.java +++ b/spring-cloud-aws-parameter-store-config/src/test/java/org/springframework/cloud/aws/paramstore/AwsParamStorePropertySourceLocatorTest.java @@ -25,10 +25,12 @@ import com.amazonaws.services.simplesystemsmanagement.model.Parameter; import org.junit.Test; +import org.springframework.core.env.PropertySource; import org.springframework.mock.env.MockEnvironment; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -36,6 +38,7 @@ * Unit test for {@link AwsParamStorePropertySourceLocator}. * * @author Matej Nedic + * @author Pete Guyatt */ public class AwsParamStorePropertySourceLocatorTest { @@ -91,28 +94,92 @@ public void contextSpecificOrderExpected() { AwsParamStorePropertySourceLocator locator = new AwsParamStorePropertySourceLocator( ssmClient, properties); - env.setActiveProfiles("test"); + env.setActiveProfiles("test", "more-specific", "most-specific"); locator.locate(env); List contextToBeTested = new ArrayList<>(locator.getContexts()); assertThat(contextToBeTested.get(0)) + .isEqualTo("application/messaging-service_most-specific/"); + assertThat(contextToBeTested.get(1)) + .isEqualTo("application/messaging-service_more-specific/"); + assertThat(contextToBeTested.get(2)) .isEqualTo("application/messaging-service_test/"); - assertThat(contextToBeTested.get(1)).isEqualTo("application/messaging-service/"); - assertThat(contextToBeTested.get(2)).isEqualTo("application/application_test/"); - assertThat(contextToBeTested.get(3)).isEqualTo("application/application/"); + assertThat(contextToBeTested.get(3)).isEqualTo("application/messaging-service/"); + assertThat(contextToBeTested.get(4)) + .isEqualTo("application/application_most-specific/"); + assertThat(contextToBeTested.get(5)) + .isEqualTo("application/application_more-specific/"); + assertThat(contextToBeTested.get(6)).isEqualTo("application/application_test/"); + assertThat(contextToBeTested.get(7)).isEqualTo("application/application/"); + } + + @Test + public void contextWithMultipleProfilesValidatePropertyPrecedence() { + AwsParamStoreProperties properties = new AwsParamStorePropertiesBuilder() + .withDefaultContext("context").withName("application").build(); + + String[] activeProfiles = { "test", "more-specific", "most-specific" }; + String propertyKey = "my-test-value"; + + when(ssmClient.getParametersByPath( + eq(newGetParametersByPathRequest("context/application/")))).thenReturn( + newGetParametersByPathResult("context/application/" + propertyKey, + "")); + + for (String profile : activeProfiles) { + String path = String.format("context/application_%s/", profile); + when(ssmClient.getParametersByPath(eq(newGetParametersByPathRequest(path)))) + .thenReturn( + newGetParametersByPathResult(path + propertyKey, profile)); + } + + AwsParamStorePropertySourceLocator locator = new AwsParamStorePropertySourceLocator( + ssmClient, properties); + env.setActiveProfiles(activeProfiles); + PropertySource propertySource = locator.locate(env); + + assertThat(propertySource.getProperty(propertyKey)) + .isEqualTo(activeProfiles[activeProfiles.length - 1]); + + List contexts = locator.getContexts(); + assertThat(contexts).hasSize(4); + + assertThat(contexts.get(0)).isEqualTo("context/application_most-specific/"); + assertThat(contexts.get(1)).isEqualTo("context/application_more-specific/"); + assertThat(contexts.get(2)).isEqualTo("context/application_test/"); + assertThat(contexts.get(3)).isEqualTo("context/application/"); + } + + private static GetParametersByPathResult newGetParametersByPathResult(String name, + String value) { + return newGetParametersByPathResult(newParameter(name, value)); + } + + private static GetParametersByPathResult newGetParametersByPathResult( + Parameter... parameters) { + return new GetParametersByPathResult().withParameters(parameters); + } + + private static GetParametersByPathRequest newGetParametersByPathRequest(String path) { + return new GetParametersByPathRequest().withPath(path).withRecursive(true) + .withWithDecryption(true); + } + + public static Parameter newParameter(String name, String value) { + return new Parameter().withName(name).withValue(value); } private static GetParametersByPathResult getNextResult() { - return new GetParametersByPathResult().withParameters( - new Parameter().withName("/config/myservice/key3").withValue("value3"), - new Parameter().withName("/config/myservice/key4").withValue("value4")); + return newGetParametersByPathResult( + newParameter("/config/myservice/key3", "value3"), + newParameter("/config/myservice/key4", "value3")); } private static GetParametersByPathResult getFirstResult() { - return new GetParametersByPathResult().withParameters( - new Parameter().withName("/config/myservice/key3").withValue("value3"), - new Parameter().withName("/config/myservice/key4").withValue("value4")); + return newGetParametersByPathResult( + newParameter("/config/myservice/key3", "value3"), + newParameter("/config/myservice/key4", "value3")); } private static final class AwsParamStorePropertiesBuilder {