From d86898ebde147470b65d94b0b554c907a8f081af Mon Sep 17 00:00:00 2001 From: Marie-Christine Noreau Date: Thu, 13 Feb 2020 22:53:49 -0500 Subject: [PATCH 1/7] Adding a flag to support retrieving parameters from different regions. --- pom.xml | 2 +- ...ropertySourceEnvironmentPostProcessor.java | 82 ++++++++++++++++--- ...rtySourceEnvironmentPostProcessorTest.java | 45 ++++++++-- 3 files changed, 111 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index c44546e..f1cd4a3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.coveo spring-boot-parameter-store-integration - 1.2.0 + 1.3.0 Spring Boot Parameter Store Integration An integration of Amazon Web Services' Systems Manager Parameter Store for Spring Boot's properties injection. diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java index 07021f4..82fd356 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java @@ -1,5 +1,9 @@ package com.coveo.configuration.parameterstore; +import java.util.Arrays; +import java.util.List; +import java.util.ListIterator; + import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.env.ConfigurableEnvironment; @@ -17,8 +21,10 @@ public class ParameterStorePropertySourceEnvironmentPostProcessor implements Env static final String PARAMETER_STORE_ACCEPTED_PROFILES_CONFIGURATION_PROPERTY = "awsParameterStorePropertySource.enabledProfiles"; static final String PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY = "awsParameterStorePropertySource.enabled"; static final String PARAMETER_STORE_HALT_BOOT_CONFIGURATION_PROPERTY = "awsParameterStorePropertySource.haltBoot"; + static final String PARAMETER_STORE_MULTI_REGION_ENABLED_CONFIGURATION_PROPERTY = "awsParameterStoreSource.ssmClient.multiRegion.enabled"; static final String PARAMETER_STORE_CLIENT_ENDPOINT_CONFIGURATION_PROPERTY = "awsParameterStoreSource.ssmClient.endpointConfiguration.endpoint"; static final String PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGION_CONFIGURATION_PROPERTY = "awsParameterStoreSource.ssmClient.endpointConfiguration.signingRegion"; + static final String PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGIONS_CONFIGURATION_PROPERTY = "awsParameterStoreSource.ssmClient.endpointConfiguration.signingRegions"; static final String PARAMETER_STORE_SUPPORT_MULTIPLE_APPLICATION_CONTEXTS_CONFIGURATION_PROPERTY = "awsParameterStorePropertySource.supportMultipleApplicationContexts"; private static final String PARAMETER_STORE_PROPERTY_SOURCE_NAME = "AWSParameterStorePropertySource"; @@ -29,15 +35,29 @@ public class ParameterStorePropertySourceEnvironmentPostProcessor implements Env public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { if (!initialized && isParameterStorePropertySourceEnabled(environment)) { - environment.getPropertySources() - .addFirst(new ParameterStorePropertySource(PARAMETER_STORE_PROPERTY_SOURCE_NAME, - new ParameterStoreSource(buildAWSSimpleSystemsManagementClient(environment), - environment.getProperty(PARAMETER_STORE_HALT_BOOT_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE)))); - if (!environment.getProperty(PARAMETER_STORE_SUPPORT_MULTIPLE_APPLICATION_CONTEXTS_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE)) { + boolean haltBoot = environment.getProperty(PARAMETER_STORE_HALT_BOOT_CONFIGURATION_PROPERTY, + Boolean.class, + Boolean.FALSE); + if (isMultiRegionEnabled(environment)) { + List signingRegions = getSigningRegions(environment); + ListIterator regionsIterator = signingRegions.listIterator(signingRegions.size()); + + while (regionsIterator.hasPrevious()) { + boolean isLast = regionsIterator.hasNext(); + String region = regionsIterator.previous(); + + environment.getPropertySources() + .addFirst(buildParameterStorePropertySource(PARAMETER_STORE_PROPERTY_SOURCE_NAME + + region, buildSSMClient(region), isLast ? false : haltBoot)); + } + } else { + environment.getPropertySources() + .addFirst(buildParameterStorePropertySource(PARAMETER_STORE_PROPERTY_SOURCE_NAME, + buildSSMClient(environment), + haltBoot)); + } + + if (doesNotSupportMultipleApplicationContexts(environment)) { initialized = true; } } @@ -53,15 +73,53 @@ private boolean isParameterStorePropertySourceEnabled(ConfigurableEnvironment en && environment.acceptsProfiles(userDefinedEnabledProfiles)); } - private AWSSimpleSystemsManagement buildAWSSimpleSystemsManagementClient(ConfigurableEnvironment environment) + private boolean doesNotSupportMultipleApplicationContexts(ConfigurableEnvironment environment) + { + return !environment.getProperty(PARAMETER_STORE_SUPPORT_MULTIPLE_APPLICATION_CONTEXTS_CONFIGURATION_PROPERTY, + Boolean.class, + Boolean.FALSE); + } + + private boolean isMultiRegionEnabled(ConfigurableEnvironment environment) + { + return environment.getProperty(PARAMETER_STORE_MULTI_REGION_ENABLED_CONFIGURATION_PROPERTY, + Boolean.class, + Boolean.FALSE); + } + + private ParameterStorePropertySource buildParameterStorePropertySource(String name, + AWSSimpleSystemsManagement ssmClient, + boolean haltBoot) + { + return new ParameterStorePropertySource(name, new ParameterStoreSource(ssmClient, haltBoot)); + } + + private AWSSimpleSystemsManagement buildSSMClient(ConfigurableEnvironment environment) { if (environment.containsProperty(PARAMETER_STORE_CLIENT_ENDPOINT_CONFIGURATION_PROPERTY)) { return AWSSimpleSystemsManagementClientBuilder.standard() .withEndpointConfiguration(new EndpointConfiguration(environment.getProperty(PARAMETER_STORE_CLIENT_ENDPOINT_CONFIGURATION_PROPERTY), - environment.getProperty(PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGION_CONFIGURATION_PROPERTY, - new DefaultAwsRegionProviderChain().getRegion()))) + getSigningRegion(environment))) .build(); } return AWSSimpleSystemsManagementClientBuilder.defaultClient(); } + + private AWSSimpleSystemsManagement buildSSMClient(String region) + { + return AWSSimpleSystemsManagementClientBuilder.standard().withRegion(region).build(); + } + + private List getSigningRegions(ConfigurableEnvironment environment) + { + return Arrays.asList(environment.getProperty(PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGIONS_CONFIGURATION_PROPERTY, + String[].class, + new String[] { getSigningRegion(environment) })); + } + + private String getSigningRegion(ConfigurableEnvironment environment) + { + return environment.getProperty(PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGION_CONFIGURATION_PROPERTY, + new DefaultAwsRegionProviderChain().getRegion()); + } } diff --git a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java index c2dec44..56b61fd 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java @@ -1,9 +1,22 @@ package com.coveo.configuration.parameterstore; -import static com.amazonaws.SDKGlobalConfiguration.*; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.*; -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.*; +import static com.amazonaws.SDKGlobalConfiguration.ACCESS_KEY_ENV_VAR; +import static com.amazonaws.SDKGlobalConfiguration.AWS_REGION_SYSTEM_PROPERTY; +import static com.amazonaws.SDKGlobalConfiguration.SECRET_KEY_ENV_VAR; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_ACCEPTED_PROFILE; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_ACCEPTED_PROFILES_CONFIGURATION_PROPERTY; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGIONS_CONFIGURATION_PROPERTY; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_HALT_BOOT_CONFIGURATION_PROPERTY; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_MULTI_REGION_ENABLED_CONFIGURATION_PROPERTY; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_SUPPORT_MULTIPLE_APPLICATION_CONTEXTS_CONFIGURATION_PROPERTY; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; @@ -43,6 +56,9 @@ public void setUp() when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_SUPPORT_MULTIPLE_APPLICATION_CONTEXTS_CONFIGURATION_PROPERTY, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); + when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_MULTI_REGION_ENABLED_CONFIGURATION_PROPERTY, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.FALSE); when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); System.setProperty(ACCESS_KEY_ENV_VAR, "id"); @@ -139,7 +155,7 @@ public void testParameterStorePropertySourceEnvironmentPostProcessorCantBeCalled } @Test - public void testParameterStorePropertySourceEnvironmentPostProcessorCanBeCalledTwiceWhenDiablingMultipleContextSupport() + public void testParameterStorePropertySourceEnvironmentPostProcessorCanBeCalledTwiceWhenDisablingMultipleContextSupport() { when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY, Boolean.class, @@ -156,4 +172,23 @@ public void testParameterStorePropertySourceEnvironmentPostProcessorCanBeCalledT verify(mutablePropertySourcesMock, times(2)).addFirst(any(ParameterStorePropertySource.class)); } + + @Test + public void testWhenMultiRegionIsEnabled() + { + when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_MULTI_REGION_ENABLED_CONFIGURATION_PROPERTY, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(eq(PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGIONS_CONFIGURATION_PROPERTY), + any(), + any())).thenReturn(new String[] { "region-1", "region-2" }); + + parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, + applicationMock); + + verify(mutablePropertySourcesMock, times(2)).addFirst(any(ParameterStorePropertySource.class)); + } } From e3953e19ba9ae6826aa115eb7750892518f67d80 Mon Sep 17 00:00:00 2001 From: Marie-Christine Noreau Date: Fri, 14 Feb 2020 12:23:56 -0500 Subject: [PATCH 2/7] Update readme.md --- readme.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/readme.md b/readme.md index 5737a91..cbe5718 100644 --- a/readme.md +++ b/readme.md @@ -81,6 +81,12 @@ Spring Cloud has a second application context named bootstrap that gets initiali If you still want the post processor to run twice or if you are using [spring-boot-devtools](https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools-restart), you can set the optional property `awsParameterStorePropertySource.supportMultipleApplicationContexts` to `true`. The default property value is `false`to prevent multiple initializations. If you are also using Spring Cloud, this property will only work if set in the bootstrap properties. +## Multi-region +- Set `awsParameterStoreSource.ssmClient.multiRegion.enabled` to `true` (yml, properties, or anything [here](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html)) +- Set `awsParameterStoreSource.ssmClient.endpointConfiguration.signingRegions` with the regions from which you need to retrieve parameters using a **comma-separated** list such as `us-east-1,us-east-2`. If not specified, it will fallback on `awsParameterStoreSource.ssmClient.endpointConfiguration.signingRegion`, if present, or the associated signing region fetched from [DefaultAWSRegionProviderChain](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/regions/DefaultAwsRegionProviderChain.html). It adds a PropertySource for each region specified. It will start looking from the first region and so on until it finds the property so put the regions in order of precedence. +**Reminder**: using other list injecting methods like a yaml list won't work because this property gets loaded too early in the boot process. +- If you want to halt the boot when a property isn't found in any of the specified regions, just set `awsParameterStorePropertySource.haltBoot` to `true` in your properties. + ## Contributing Open an issue to report bugs or to request additional features. Pull requests are always welcome. From 374d725a0cdfc20f023bdfe7b08b31ebfbc347f8 Mon Sep 17 00:00:00 2001 From: Marie-Christine Noreau Date: Mon, 17 Feb 2020 22:27:39 -0500 Subject: [PATCH 3/7] refactoring and addind some more unit tests --- readme.md | 4 +- ...rePropertySourceConfigurationProperty.java | 19 +++ ...ropertySourceEnvironmentPostProcessor.java | 104 ++++------------- ...ySourceEnvironmentPostProcessStrategy.java | 71 ++++++++++++ ...ySourceEnvironmentPostProcessStrategy.java | 62 ++++++++++ ...ySourceEnvironmentPostProcessStrategy.java | 8 ++ ...EnvironmentPostProcessStrategyFactory.java | 6 + ...ronmentPostProcessStrategyFactoryImpl.java | 28 +++++ ...rtySourceEnvironmentPostProcessorTest.java | 105 +++++++---------- ...rceEnvironmentPostProcessStrategyTest.java | 66 +++++++++++ ...rceEnvironmentPostProcessStrategyTest.java | 109 ++++++++++++++++++ ...entPostProcessStrategyFactoryImplTest.java | 28 +++++ 12 files changed, 460 insertions(+), 150 deletions(-) create mode 100644 src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java create mode 100644 src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java create mode 100644 src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java create mode 100644 src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategy.java create mode 100644 src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java create mode 100644 src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.java create mode 100644 src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java create mode 100644 src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java create mode 100644 src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java diff --git a/readme.md b/readme.md index cbe5718..c1529a4 100644 --- a/readme.md +++ b/readme.md @@ -82,10 +82,10 @@ Spring Cloud has a second application context named bootstrap that gets initiali If you still want the post processor to run twice or if you are using [spring-boot-devtools](https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools-restart), you can set the optional property `awsParameterStorePropertySource.supportMultipleApplicationContexts` to `true`. The default property value is `false`to prevent multiple initializations. If you are also using Spring Cloud, this property will only work if set in the bootstrap properties. ## Multi-region -- Set `awsParameterStoreSource.ssmClient.multiRegion.enabled` to `true` (yml, properties, or anything [here](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html)) -- Set `awsParameterStoreSource.ssmClient.endpointConfiguration.signingRegions` with the regions from which you need to retrieve parameters using a **comma-separated** list such as `us-east-1,us-east-2`. If not specified, it will fallback on `awsParameterStoreSource.ssmClient.endpointConfiguration.signingRegion`, if present, or the associated signing region fetched from [DefaultAWSRegionProviderChain](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/regions/DefaultAwsRegionProviderChain.html). It adds a PropertySource for each region specified. It will start looking from the first region and so on until it finds the property so put the regions in order of precedence. +- Set `awsParameterStoreSource.ssmClient.signingRegions` with the regions from which you need to retrieve parameters using a **comma-separated** list such as `us-east-1,us-east-2`. It adds a PropertySource for each region specified. It will start looking from the first region and so on until it finds the property so put the regions in order of precedence. **Reminder**: using other list injecting methods like a yaml list won't work because this property gets loaded too early in the boot process. - If you want to halt the boot when a property isn't found in any of the specified regions, just set `awsParameterStorePropertySource.haltBoot` to `true` in your properties. +- Make sure that your service has the necessary permissions to access parameters in the specified regions ## Contributing Open an issue to report bugs or to request additional features. Pull requests are always welcome. diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java new file mode 100644 index 0000000..4285c0d --- /dev/null +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java @@ -0,0 +1,19 @@ +package com.coveo.configuration.parameterstore; + +public final class ParameterStorePropertySourceConfigurationProperty +{ + private static final String PREFIX = "awsParameterStorePropertySource."; + private static final String SSM_CLIENT_PREFIX = "awsParameterStoreSource.ssmClient."; + + public static final String ACCEPTED_PROFILE = "awsParameterStorePropertySourceEnabled"; + + public static final String ENABLED = PREFIX + "enabled"; + public static final String ACCEPTED_PROFILES = PREFIX + "enabledProfiles"; + public static final String HALT_BOOT = PREFIX + "haltBoot"; + public static final String SUPPORT_MULTIPLE_APPLICATION_CONTEXTS = PREFIX + "supportMultipleApplicationContexts"; + public static final String SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT = SSM_CLIENT_PREFIX + + "endpointConfiguration.endpoint"; + public static final String SSM_CLIENT_ENDPOINT_CONFIG_SIGNING_REGION = SSM_CLIENT_PREFIX + + "endpointConfiguration.signingRegion"; + public static final String SSM_CLIENT_SIGNING_REGIONS = SSM_CLIENT_PREFIX + "signingRegions"; +} diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java index 82fd356..1434399 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java @@ -1,61 +1,27 @@ package com.coveo.configuration.parameterstore; -import java.util.Arrays; -import java.util.List; -import java.util.ListIterator; +import static com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.DEFAULT_STRATEGY; +import static com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.MULTI_REGION_STRATEGY; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.util.ObjectUtils; -import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; -import com.amazonaws.regions.DefaultAwsRegionProviderChain; -import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement; -import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; +import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategy; +import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory; +import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl; public class ParameterStorePropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor { - static final String PARAMETER_STORE_ACCEPTED_PROFILE = "awsParameterStorePropertySourceEnabled"; - - static final String PARAMETER_STORE_ACCEPTED_PROFILES_CONFIGURATION_PROPERTY = "awsParameterStorePropertySource.enabledProfiles"; - static final String PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY = "awsParameterStorePropertySource.enabled"; - static final String PARAMETER_STORE_HALT_BOOT_CONFIGURATION_PROPERTY = "awsParameterStorePropertySource.haltBoot"; - static final String PARAMETER_STORE_MULTI_REGION_ENABLED_CONFIGURATION_PROPERTY = "awsParameterStoreSource.ssmClient.multiRegion.enabled"; - static final String PARAMETER_STORE_CLIENT_ENDPOINT_CONFIGURATION_PROPERTY = "awsParameterStoreSource.ssmClient.endpointConfiguration.endpoint"; - static final String PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGION_CONFIGURATION_PROPERTY = "awsParameterStoreSource.ssmClient.endpointConfiguration.signingRegion"; - static final String PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGIONS_CONFIGURATION_PROPERTY = "awsParameterStoreSource.ssmClient.endpointConfiguration.signingRegions"; - static final String PARAMETER_STORE_SUPPORT_MULTIPLE_APPLICATION_CONTEXTS_CONFIGURATION_PROPERTY = "awsParameterStorePropertySource.supportMultipleApplicationContexts"; - - private static final String PARAMETER_STORE_PROPERTY_SOURCE_NAME = "AWSParameterStorePropertySource"; - static boolean initialized; + static ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory postProcessStrategyFactory = new ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl(); @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { if (!initialized && isParameterStorePropertySourceEnabled(environment)) { - boolean haltBoot = environment.getProperty(PARAMETER_STORE_HALT_BOOT_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE); - if (isMultiRegionEnabled(environment)) { - List signingRegions = getSigningRegions(environment); - ListIterator regionsIterator = signingRegions.listIterator(signingRegions.size()); - - while (regionsIterator.hasPrevious()) { - boolean isLast = regionsIterator.hasNext(); - String region = regionsIterator.previous(); - - environment.getPropertySources() - .addFirst(buildParameterStorePropertySource(PARAMETER_STORE_PROPERTY_SOURCE_NAME - + region, buildSSMClient(region), isLast ? false : haltBoot)); - } - } else { - environment.getPropertySources() - .addFirst(buildParameterStorePropertySource(PARAMETER_STORE_PROPERTY_SOURCE_NAME, - buildSSMClient(environment), - haltBoot)); - } + getPostProcessStrategy(environment).postProcess(environment); if (doesNotSupportMultipleApplicationContexts(environment)) { initialized = true; @@ -63,63 +29,33 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringAp } } + private ParameterStorePropertySourceEnvironmentPostProcessStrategy getPostProcessStrategy(ConfigurableEnvironment environment) + { + String type = isMultiRegionEnabled(environment) ? MULTI_REGION_STRATEGY : DEFAULT_STRATEGY; + return postProcessStrategyFactory.getStrategy(type); + } + private boolean isParameterStorePropertySourceEnabled(ConfigurableEnvironment environment) { - String[] userDefinedEnabledProfiles = environment.getProperty(PARAMETER_STORE_ACCEPTED_PROFILES_CONFIGURATION_PROPERTY, + String[] userDefinedEnabledProfiles = environment.getProperty(ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES, String[].class); - return environment.getProperty(PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY, Boolean.class, Boolean.FALSE) - || environment.acceptsProfiles(PARAMETER_STORE_ACCEPTED_PROFILE) + return environment.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + Boolean.class, + Boolean.FALSE) + || environment.acceptsProfiles(ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILE) || (!ObjectUtils.isEmpty(userDefinedEnabledProfiles) && environment.acceptsProfiles(userDefinedEnabledProfiles)); } private boolean doesNotSupportMultipleApplicationContexts(ConfigurableEnvironment environment) { - return !environment.getProperty(PARAMETER_STORE_SUPPORT_MULTIPLE_APPLICATION_CONTEXTS_CONFIGURATION_PROPERTY, + return !environment.getProperty(ParameterStorePropertySourceConfigurationProperty.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, Boolean.class, Boolean.FALSE); } private boolean isMultiRegionEnabled(ConfigurableEnvironment environment) { - return environment.getProperty(PARAMETER_STORE_MULTI_REGION_ENABLED_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE); - } - - private ParameterStorePropertySource buildParameterStorePropertySource(String name, - AWSSimpleSystemsManagement ssmClient, - boolean haltBoot) - { - return new ParameterStorePropertySource(name, new ParameterStoreSource(ssmClient, haltBoot)); - } - - private AWSSimpleSystemsManagement buildSSMClient(ConfigurableEnvironment environment) - { - if (environment.containsProperty(PARAMETER_STORE_CLIENT_ENDPOINT_CONFIGURATION_PROPERTY)) { - return AWSSimpleSystemsManagementClientBuilder.standard() - .withEndpointConfiguration(new EndpointConfiguration(environment.getProperty(PARAMETER_STORE_CLIENT_ENDPOINT_CONFIGURATION_PROPERTY), - getSigningRegion(environment))) - .build(); - } - return AWSSimpleSystemsManagementClientBuilder.defaultClient(); - } - - private AWSSimpleSystemsManagement buildSSMClient(String region) - { - return AWSSimpleSystemsManagementClientBuilder.standard().withRegion(region).build(); - } - - private List getSigningRegions(ConfigurableEnvironment environment) - { - return Arrays.asList(environment.getProperty(PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGIONS_CONFIGURATION_PROPERTY, - String[].class, - new String[] { getSigningRegion(environment) })); - } - - private String getSigningRegion(ConfigurableEnvironment environment) - { - return environment.getProperty(PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGION_CONFIGURATION_PROPERTY, - new DefaultAwsRegionProviderChain().getRegion()); + return environment.containsProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGIONS); } } diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java new file mode 100644 index 0000000..8094f9a --- /dev/null +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java @@ -0,0 +1,71 @@ +package com.coveo.configuration.parameterstore.strategy; + +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_ENDPOINT_CONFIG_SIGNING_REGION; + +import org.springframework.core.env.ConfigurableEnvironment; + +import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; +import com.amazonaws.regions.AwsRegionProviderChain; +import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement; +import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; + +import com.coveo.configuration.parameterstore.ParameterStorePropertySource; +import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty; +import com.coveo.configuration.parameterstore.ParameterStoreSource; + +public class DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy + implements ParameterStorePropertySourceEnvironmentPostProcessStrategy +{ + private static final String PARAMETER_STORE_PROPERTY_SOURCE_NAME = "AWSParameterStorePropertySource"; + + private AwsRegionProviderChain awsRegionProviderChain; + + public DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy(AwsRegionProviderChain awsRegionProviderChain) + { + this.awsRegionProviderChain = awsRegionProviderChain; + } + + @Override + public void postProcess(ConfigurableEnvironment environment) + { + boolean haltBoot = environment.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, + Boolean.class, + Boolean.FALSE); + environment.getPropertySources() + .addFirst(buildParameterStorePropertySource(buildSSMClient(environment), haltBoot)); + } + + private ParameterStorePropertySource buildParameterStorePropertySource(AWSSimpleSystemsManagement ssmClient, + boolean haltBoot) + { + return new ParameterStorePropertySource(PARAMETER_STORE_PROPERTY_SOURCE_NAME, + new ParameterStoreSource(ssmClient, haltBoot)); + } + + private AWSSimpleSystemsManagement buildSSMClient(ConfigurableEnvironment environment) + { + if (hasCustomEndpoint(environment)) { + return AWSSimpleSystemsManagementClientBuilder.standard() + .withEndpointConfiguration(new EndpointConfiguration(getCustomEndpoint(environment), + getSigningRegion(environment))) + .build(); + } + return AWSSimpleSystemsManagementClientBuilder.defaultClient(); + } + + private boolean hasCustomEndpoint(ConfigurableEnvironment environment) + { + return environment.containsProperty(SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT); + } + + private String getCustomEndpoint(ConfigurableEnvironment environment) + { + return environment.getProperty(SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT); + } + + private String getSigningRegion(ConfigurableEnvironment environment) + { + return environment.getProperty(SSM_CLIENT_ENDPOINT_CONFIG_SIGNING_REGION, awsRegionProviderChain.getRegion()); + } +} diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java new file mode 100644 index 0000000..75eba53 --- /dev/null +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java @@ -0,0 +1,62 @@ +package com.coveo.configuration.parameterstore.strategy; + +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.HALT_BOOT; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGIONS; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.ListIterator; + +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.util.ObjectUtils; + +import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement; +import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; + +import com.coveo.configuration.parameterstore.ParameterStorePropertySource; +import com.coveo.configuration.parameterstore.ParameterStoreSource; + +public class MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy + implements ParameterStorePropertySourceEnvironmentPostProcessStrategy +{ + private static final String PARAMETER_STORE_PROPERTY_SOURCE_NAME = "MultiRegionAWSParameterStorePropertySource_"; + + @Override + public void postProcess(ConfigurableEnvironment environment) + { + boolean haltBoot = environment.getProperty(HALT_BOOT, Boolean.class, Boolean.FALSE); + + LinkedList signingRegions = getSigningRegions(environment); + ListIterator regionsIterator = signingRegions.listIterator(signingRegions.size()); + + // To keep the order of precedence, we iterate from the last one to the first one because of the method 'addFirst'. + // If we want the first region specified to be the first property source, we have to add it last. + while (regionsIterator.hasPrevious()) { + // We only want to halt boot (if true) for the last property source so the first one added. + boolean shouldHaltBoot = haltBoot && !regionsIterator.hasNext(); + String region = regionsIterator.previous(); + + environment.getPropertySources() + .addFirst(buildParameterStorePropertySource(PARAMETER_STORE_PROPERTY_SOURCE_NAME + region, + region, + shouldHaltBoot)); + } + } + + private ParameterStorePropertySource buildParameterStorePropertySource(String name, String region, boolean haltBoot) + { + return new ParameterStorePropertySource(name, new ParameterStoreSource(buildSSMClient(region), haltBoot)); + } + + private AWSSimpleSystemsManagement buildSSMClient(String region) + { + return AWSSimpleSystemsManagementClientBuilder.standard().withRegion(region).build(); + } + + private LinkedList getSigningRegions(ConfigurableEnvironment environment) + { + String[] signingRegions = environment.getProperty(SSM_CLIENT_SIGNING_REGIONS, String[].class); + return ObjectUtils.isEmpty(signingRegions) ? new LinkedList<>() + : new LinkedList<>(Arrays.asList(signingRegions)); + } +} diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategy.java new file mode 100644 index 0000000..fbc5e07 --- /dev/null +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategy.java @@ -0,0 +1,8 @@ +package com.coveo.configuration.parameterstore.strategy; + +import org.springframework.core.env.ConfigurableEnvironment; + +public interface ParameterStorePropertySourceEnvironmentPostProcessStrategy +{ + void postProcess(ConfigurableEnvironment environment); +} diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java new file mode 100644 index 0000000..9688e9c --- /dev/null +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java @@ -0,0 +1,6 @@ +package com.coveo.configuration.parameterstore.strategy; + +public interface ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory +{ + ParameterStorePropertySourceEnvironmentPostProcessStrategy getStrategy(String type); +} diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.java new file mode 100644 index 0000000..f032768 --- /dev/null +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.java @@ -0,0 +1,28 @@ +package com.coveo.configuration.parameterstore.strategy; + +import java.util.HashMap; +import java.util.Map; + +import com.amazonaws.regions.DefaultAwsRegionProviderChain; + +public class ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl + implements ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory +{ + public static final String DEFAULT_STRATEGY = "Default"; + public static final String MULTI_REGION_STRATEGY = "MultiRegion"; + + private static Map strategies = new HashMap<>(); + + static { + strategies.put(DEFAULT_STRATEGY, + new DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy(new DefaultAwsRegionProviderChain())); + strategies.put(MULTI_REGION_STRATEGY, + new MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy()); + } + + @Override + public ParameterStorePropertySourceEnvironmentPostProcessStrategy getStrategy(String type) + { + return strategies.get(type); + } +} diff --git a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java index 56b61fd..7aae962 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java @@ -1,17 +1,9 @@ package com.coveo.configuration.parameterstore; -import static com.amazonaws.SDKGlobalConfiguration.ACCESS_KEY_ENV_VAR; -import static com.amazonaws.SDKGlobalConfiguration.AWS_REGION_SYSTEM_PROPERTY; -import static com.amazonaws.SDKGlobalConfiguration.SECRET_KEY_ENV_VAR; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_ACCEPTED_PROFILE; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_ACCEPTED_PROFILES_CONFIGURATION_PROPERTY; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGIONS_CONFIGURATION_PROPERTY; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_HALT_BOOT_CONFIGURATION_PROPERTY; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_MULTI_REGION_ENABLED_CONFIGURATION_PROPERTY; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceEnvironmentPostProcessor.PARAMETER_STORE_SUPPORT_MULTIPLE_APPLICATION_CONTEXTS_CONFIGURATION_PROPERTY; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILE; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.ENABLED; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -25,7 +17,10 @@ import org.mockito.runners.MockitoJUnitRunner; import org.springframework.boot.SpringApplication; import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MutablePropertySources; + +import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategy; +import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory; +import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl; @RunWith(MockitoJUnitRunner.class) public class ParameterStorePropertySourceEnvironmentPostProcessorTest @@ -36,9 +31,13 @@ public class ParameterStorePropertySourceEnvironmentPostProcessorTest @Mock private ConfigurableEnvironment configurableEnvironmentMock; @Mock - private MutablePropertySources mutablePropertySourcesMock; - @Mock private SpringApplication applicationMock; + @Mock + private ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory postProcessStrategyFactoryMock; + @Mock + private ParameterStorePropertySourceEnvironmentPostProcessStrategy defaultPostProcessStrategyMock; + @Mock + private ParameterStorePropertySourceEnvironmentPostProcessStrategy multiRegionPostProcessStrategyMock; private ParameterStorePropertySourceEnvironmentPostProcessor parameterStorePropertySourceEnvironmentPostProcessor = new ParameterStorePropertySourceEnvironmentPostProcessor(); @@ -47,23 +46,14 @@ public void setUp() { ParameterStorePropertySourceEnvironmentPostProcessor.initialized = false; - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE)).thenReturn(Boolean.FALSE); - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_HALT_BOOT_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE)).thenReturn(Boolean.FALSE); - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_SUPPORT_MULTIPLE_APPLICATION_CONTEXTS_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE)).thenReturn(Boolean.FALSE); - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_MULTI_REGION_ENABLED_CONFIGURATION_PROPERTY, + when(postProcessStrategyFactoryMock.getStrategy(ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.DEFAULT_STRATEGY)).thenReturn(defaultPostProcessStrategyMock); + when(postProcessStrategyFactoryMock.getStrategy(ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.MULTI_REGION_STRATEGY)).thenReturn(multiRegionPostProcessStrategyMock); + ParameterStorePropertySourceEnvironmentPostProcessor.postProcessStrategyFactory = postProcessStrategyFactoryMock; + + when(configurableEnvironmentMock.getProperty(ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); + when(configurableEnvironmentMock.getProperty(SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); - when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); - - System.setProperty(ACCESS_KEY_ENV_VAR, "id"); - System.setProperty(SECRET_KEY_ENV_VAR, "secret"); - System.setProperty(AWS_REGION_SYSTEM_PROPERTY, "region"); } @Test @@ -72,78 +62,74 @@ public void testParameterStoreIsDisabledByDefault() parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verifyZeroInteractions(mutablePropertySourcesMock); + verifyZeroInteractions(applicationMock); + verifyZeroInteractions(defaultPostProcessStrategyMock); + verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test public void testParameterStoreIsEnabledWithPropertySetToTrue() { - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(mutablePropertySourcesMock).addFirst(any(ParameterStorePropertySource.class)); + verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); } @Test public void testParameterStoreIsEnabledWithProfile() { - when(configurableEnvironmentMock.acceptsProfiles(PARAMETER_STORE_ACCEPTED_PROFILE)).thenReturn(true); + when(configurableEnvironmentMock.acceptsProfiles(ACCEPTED_PROFILE)).thenReturn(true); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(mutablePropertySourcesMock).addFirst(any(ParameterStorePropertySource.class)); + verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); } @Test public void testParameterStoreIsEnabledWithCustomProfiles() { - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_ACCEPTED_PROFILES_CONFIGURATION_PROPERTY, - String[].class)).thenReturn(CUSTOM_PROFILES); + when(configurableEnvironmentMock.getProperty(ACCEPTED_PROFILES, String[].class)).thenReturn(CUSTOM_PROFILES); when(configurableEnvironmentMock.acceptsProfiles(CUSTOM_PROFILES)).thenReturn(true); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(mutablePropertySourcesMock).addFirst(any(ParameterStorePropertySource.class)); + verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); } @Test public void testParameterStoreIsNotEnabledWithCustomProfilesEmpty() { - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_ACCEPTED_PROFILES_CONFIGURATION_PROPERTY, + when(configurableEnvironmentMock.getProperty(ACCEPTED_PROFILES, String[].class)).thenReturn(EMPTY_CUSTOM_PROFILES); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); verify(configurableEnvironmentMock, never()).acceptsProfiles(EMPTY_CUSTOM_PROFILES); - verifyZeroInteractions(mutablePropertySourcesMock); + verifyZeroInteractions(defaultPostProcessStrategyMock); } @Test public void testParameterStoreIsNotEnabledWithCustomProfilesButNoneOfTheProfilesActive() { - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_ACCEPTED_PROFILES_CONFIGURATION_PROPERTY, - String[].class)).thenReturn(CUSTOM_PROFILES); + when(configurableEnvironmentMock.getProperty(ACCEPTED_PROFILES, String[].class)).thenReturn(CUSTOM_PROFILES); when(configurableEnvironmentMock.acceptsProfiles(CUSTOM_PROFILES)).thenReturn(false); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verifyZeroInteractions(mutablePropertySourcesMock); + verifyZeroInteractions(defaultPostProcessStrategyMock); } @Test public void testParameterStorePropertySourceEnvironmentPostProcessorCantBeCalledTwice() { - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); @@ -151,16 +137,14 @@ public void testParameterStorePropertySourceEnvironmentPostProcessorCantBeCalled parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(mutablePropertySourcesMock, times(1)).addFirst(any(ParameterStorePropertySource.class)); + verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); } @Test public void testParameterStorePropertySourceEnvironmentPostProcessorCanBeCalledTwiceWhenDisablingMultipleContextSupport() { - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_SUPPORT_MULTIPLE_APPLICATION_CONTEXTS_CONFIGURATION_PROPERTY, + when(configurableEnvironmentMock.getProperty(ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); @@ -170,25 +154,18 @@ public void testParameterStorePropertySourceEnvironmentPostProcessorCanBeCalledT parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(mutablePropertySourcesMock, times(2)).addFirst(any(ParameterStorePropertySource.class)); + verify(defaultPostProcessStrategyMock, times(2)).postProcess(configurableEnvironmentMock); } @Test public void testWhenMultiRegionIsEnabled() { - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_ENABLED_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(PARAMETER_STORE_MULTI_REGION_ENABLED_CONFIGURATION_PROPERTY, - Boolean.class, - Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(eq(PARAMETER_STORE_CLIENT_ENDPOINT_SIGNING_REGIONS_CONFIGURATION_PROPERTY), - any(), - any())).thenReturn(new String[] { "region-1", "region-2" }); + when(configurableEnvironmentMock.getProperty(ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGIONS)).thenReturn(Boolean.TRUE); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(mutablePropertySourcesMock, times(2)).addFirst(any(ParameterStorePropertySource.class)); + verify(multiRegionPostProcessStrategyMock, times(1)).postProcess(configurableEnvironmentMock); } } diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java new file mode 100644 index 0000000..d9f5b47 --- /dev/null +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java @@ -0,0 +1,66 @@ +package com.coveo.configuration.parameterstore.strategy; + +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.HALT_BOOT; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_ENDPOINT_CONFIG_SIGNING_REGION; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MutablePropertySources; + +import com.amazonaws.regions.AwsRegionProviderChain; + +import com.coveo.configuration.parameterstore.ParameterStorePropertySource; +import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty; + +@RunWith(MockitoJUnitRunner.class) +public class DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest +{ + @Mock + private ConfigurableEnvironment configurableEnvironmentMock; + @Mock + private MutablePropertySources mutablePropertySourcesMock; + @Mock + private AwsRegionProviderChain awsRegionProviderChain; + + private DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy postProcessStrategy; + + @Before + public void setUp() + { + when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); + when(configurableEnvironmentMock.getProperty(HALT_BOOT, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.FALSE); + when(awsRegionProviderChain.getRegion()).thenReturn("aRegion"); + when(configurableEnvironmentMock.getProperty(SSM_CLIENT_ENDPOINT_CONFIG_SIGNING_REGION, + awsRegionProviderChain.getRegion())).thenReturn("aRegion"); + + postProcessStrategy = new DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy(awsRegionProviderChain); + } + + @Test + public void testShouldAddPropertySource() + { + postProcessStrategy.postProcess(configurableEnvironmentMock); + + verify(mutablePropertySourcesMock).addFirst(any(ParameterStorePropertySource.class)); + } + + @Test + public void testWhenCustomEndpointShouldAddPropertySource() + { + when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT)).thenReturn("customEndpoint"); + + postProcessStrategy.postProcess(configurableEnvironmentMock); + + verify(mutablePropertySourcesMock).addFirst(any(ParameterStorePropertySource.class)); + } +} diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java new file mode 100644 index 0000000..516b482 --- /dev/null +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java @@ -0,0 +1,109 @@ +package com.coveo.configuration.parameterstore.strategy; + +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.HALT_BOOT; +import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGIONS; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.StringEndsWith.endsWith; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.test.util.ReflectionTestUtils; + +import com.coveo.configuration.parameterstore.ParameterStorePropertySource; + +@RunWith(MockitoJUnitRunner.class) +public class MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest +{ + private static final String[] SIGNING_REGIONS = { "ownRegion", "mainRegion", "defaultRegion" }; + private static final String[] SINGLE_SIGNING_REGIONS = { "ownRegion" }; + + @Mock + private ConfigurableEnvironment configurableEnvironmentMock; + @Mock + private MutablePropertySources mutablePropertySourcesMock; + + @Captor + private ArgumentCaptor parameterStorePropertySourceArgumentCaptor; + + private MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy postProcessStrategy; + + @Before + public void setUp() + { + when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); + when(configurableEnvironmentMock.getProperty(HALT_BOOT, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.FALSE); + when(configurableEnvironmentMock.getProperty(SSM_CLIENT_SIGNING_REGIONS, + String[].class)).thenReturn(SIGNING_REGIONS); + + postProcessStrategy = new MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy(); + } + + @Test + public void testShouldAddPropertySourceForEverySigningRegionsInOrderOfPrecedence() + { + postProcessStrategy.postProcess(configurableEnvironmentMock); + + verify(mutablePropertySourcesMock, times(3)).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); + + List parameterStorePropertySources = parameterStorePropertySourceArgumentCaptor.getAllValues(); + + verifyParameterStorePropertySource(parameterStorePropertySources.get(0), SIGNING_REGIONS[2], Boolean.FALSE); + verifyParameterStorePropertySource(parameterStorePropertySources.get(1), SIGNING_REGIONS[1], Boolean.FALSE); + verifyParameterStorePropertySource(parameterStorePropertySources.get(2), SIGNING_REGIONS[0], Boolean.FALSE); + } + + @Test + public void testHaltBootIsTrueThenOnlyLastRegionShouldHaltBoot() + { + when(configurableEnvironmentMock.getProperty(HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); + + postProcessStrategy.postProcess(configurableEnvironmentMock); + + verify(mutablePropertySourcesMock, times(3)).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); + + List parameterStorePropertySources = parameterStorePropertySourceArgumentCaptor.getAllValues(); + + verifyParameterStorePropertySource(parameterStorePropertySources.get(0), SIGNING_REGIONS[2], Boolean.TRUE); + verifyParameterStorePropertySource(parameterStorePropertySources.get(1), SIGNING_REGIONS[1], Boolean.FALSE); + verifyParameterStorePropertySource(parameterStorePropertySources.get(2), SIGNING_REGIONS[0], Boolean.FALSE); + } + + @Test + public void testWithSingleRegion() + { + when(configurableEnvironmentMock.getProperty(HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(SSM_CLIENT_SIGNING_REGIONS, + String[].class)).thenReturn(SINGLE_SIGNING_REGIONS); + + postProcessStrategy.postProcess(configurableEnvironmentMock); + + verify(mutablePropertySourcesMock).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); + + verifyParameterStorePropertySource(parameterStorePropertySourceArgumentCaptor.getValue(), + SINGLE_SIGNING_REGIONS[0], + Boolean.TRUE); + } + + private void verifyParameterStorePropertySource(ParameterStorePropertySource actual, + String region, + Boolean haltBoot) + { + assertThat(actual.getName(), endsWith("_" + region)); + assertThat(ReflectionTestUtils.getField(actual.getSource(), "haltBoot"), is(haltBoot)); + } +} diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java new file mode 100644 index 0000000..f31b8a5 --- /dev/null +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java @@ -0,0 +1,28 @@ +package com.coveo.configuration.parameterstore.strategy; + +import static com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.DEFAULT_STRATEGY; +import static com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.MULTI_REGION_STRATEGY; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +public class ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest +{ + private ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory factory = new ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl(); + + @Test + public void testGettingDefaultStrategy() + { + assertThat(factory.getStrategy(DEFAULT_STRATEGY), + is(instanceOf(DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.class))); + } + + @Test + public void testGettingMultiRegionStrategy() + { + assertThat(factory.getStrategy(MULTI_REGION_STRATEGY), + is(instanceOf(MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.class))); + } +} From e3ee04f96b948e684675ff637976524b0513e855 Mon Sep 17 00:00:00 2001 From: Marie-Christine Noreau Date: Tue, 18 Feb 2020 09:49:04 -0500 Subject: [PATCH 4/7] Added missing sys properties in unit tests --- ...opertySourceEnvironmentPostProcessorTest.java | 15 +++++++++++++++ ...onmentPostProcessStrategyFactoryImplTest.java | 16 +++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java index 7aae962..5530487 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java @@ -1,5 +1,8 @@ package com.coveo.configuration.parameterstore; +import static com.amazonaws.SDKGlobalConfiguration.ACCESS_KEY_ENV_VAR; +import static com.amazonaws.SDKGlobalConfiguration.AWS_REGION_SYSTEM_PROPERTY; +import static com.amazonaws.SDKGlobalConfiguration.SECRET_KEY_ENV_VAR; import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILE; import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES; import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.ENABLED; @@ -54,6 +57,10 @@ public void setUp() when(configurableEnvironmentMock.getProperty(SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); + + System.setProperty(ACCESS_KEY_ENV_VAR, "id"); + System.setProperty(SECRET_KEY_ENV_VAR, "secret"); + System.setProperty(AWS_REGION_SYSTEM_PROPERTY, "region"); } @Test @@ -76,6 +83,7 @@ public void testParameterStoreIsEnabledWithPropertySetToTrue() applicationMock); verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); + verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -87,6 +95,7 @@ public void testParameterStoreIsEnabledWithProfile() applicationMock); verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); + verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -99,6 +108,7 @@ public void testParameterStoreIsEnabledWithCustomProfiles() applicationMock); verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); + verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -112,6 +122,7 @@ public void testParameterStoreIsNotEnabledWithCustomProfilesEmpty() verify(configurableEnvironmentMock, never()).acceptsProfiles(EMPTY_CUSTOM_PROFILES); verifyZeroInteractions(defaultPostProcessStrategyMock); + verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -124,6 +135,7 @@ public void testParameterStoreIsNotEnabledWithCustomProfilesButNoneOfTheProfiles applicationMock); verifyZeroInteractions(defaultPostProcessStrategyMock); + verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -138,6 +150,7 @@ public void testParameterStorePropertySourceEnvironmentPostProcessorCantBeCalled applicationMock); verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); + verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -155,6 +168,7 @@ public void testParameterStorePropertySourceEnvironmentPostProcessorCanBeCalledT applicationMock); verify(defaultPostProcessStrategyMock, times(2)).postProcess(configurableEnvironmentMock); + verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -167,5 +181,6 @@ public void testWhenMultiRegionIsEnabled() applicationMock); verify(multiRegionPostProcessStrategyMock, times(1)).postProcess(configurableEnvironmentMock); + verifyZeroInteractions(defaultPostProcessStrategyMock); } } diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java index f31b8a5..658d80e 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java @@ -1,16 +1,30 @@ package com.coveo.configuration.parameterstore.strategy; +import static com.amazonaws.SDKGlobalConfiguration.ACCESS_KEY_ENV_VAR; +import static com.amazonaws.SDKGlobalConfiguration.AWS_REGION_SYSTEM_PROPERTY; +import static com.amazonaws.SDKGlobalConfiguration.SECRET_KEY_ENV_VAR; import static com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.DEFAULT_STRATEGY; import static com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.MULTI_REGION_STRATEGY; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import org.junit.Before; import org.junit.Test; public class ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest { - private ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory factory = new ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl(); + private ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory factory; + + @Before + public void setUp() + { + factory = new ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl(); + + System.setProperty(ACCESS_KEY_ENV_VAR, "id"); + System.setProperty(SECRET_KEY_ENV_VAR, "secret"); + System.setProperty(AWS_REGION_SYSTEM_PROPERTY, "region"); + } @Test public void testGettingDefaultStrategy() From 94d934a4d3162b5ff68877d1672e134ab107ba47 Mon Sep 17 00:00:00 2001 From: Marie-Christine Noreau Date: Tue, 18 Feb 2020 13:39:54 -0500 Subject: [PATCH 5/7] apply review --- readme.md | 6 +- ...rePropertySourceConfigurationProperty.java | 25 ++++---- ...ropertySourceEnvironmentPostProcessor.java | 13 ++-- ...ySourceEnvironmentPostProcessStrategy.java | 10 ++- ...ySourceEnvironmentPostProcessStrategy.java | 61 ++++++++++--------- ...EnvironmentPostProcessStrategyFactory.java | 20 +++++- ...ronmentPostProcessStrategyFactoryImpl.java | 28 --------- .../parameterstore/strategy/StrategyType.java | 6 ++ ...rtySourceEnvironmentPostProcessorTest.java | 46 ++++++++------ ...rceEnvironmentPostProcessStrategyTest.java | 10 ++- ...rceEnvironmentPostProcessStrategyTest.java | 34 ++++++----- ...onmentPostProcessStrategyFactoryTest.java} | 10 ++- 12 files changed, 133 insertions(+), 136 deletions(-) delete mode 100644 src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.java create mode 100644 src/main/java/com/coveo/configuration/parameterstore/strategy/StrategyType.java rename src/test/java/com/coveo/configuration/parameterstore/strategy/{ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java => ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryTest.java} (72%) diff --git a/readme.md b/readme.md index c1529a4..f9f8b69 100644 --- a/readme.md +++ b/readme.md @@ -81,11 +81,11 @@ Spring Cloud has a second application context named bootstrap that gets initiali If you still want the post processor to run twice or if you are using [spring-boot-devtools](https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools-restart), you can set the optional property `awsParameterStorePropertySource.supportMultipleApplicationContexts` to `true`. The default property value is `false`to prevent multiple initializations. If you are also using Spring Cloud, this property will only work if set in the bootstrap properties. -## Multi-region -- Set `awsParameterStoreSource.ssmClient.signingRegions` with the regions from which you need to retrieve parameters using a **comma-separated** list such as `us-east-1,us-east-2`. It adds a PropertySource for each region specified. It will start looking from the first region and so on until it finds the property so put the regions in order of precedence. +## Multi-region support +- Set `awsParameterStoreSource.multiRegion.ssmClient.regions` with the regions from which you need to retrieve parameters using a **comma-separated** list such as `us-east-1,us-east-2`. It adds a PropertySource for each region specified. It will start looking from the first region and so on until it finds the property so put the regions in order of precedence. **Reminder**: using other list injecting methods like a yaml list won't work because this property gets loaded too early in the boot process. - If you want to halt the boot when a property isn't found in any of the specified regions, just set `awsParameterStorePropertySource.haltBoot` to `true` in your properties. -- Make sure that your service has the necessary permissions to access parameters in the specified regions +- Make sure that your service has the necessary permissions to access parameters in the specified regions. ## Contributing Open an issue to report bugs or to request additional features. Pull requests are always welcome. diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java index 4285c0d..6af1f7a 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java @@ -2,18 +2,19 @@ public final class ParameterStorePropertySourceConfigurationProperty { - private static final String PREFIX = "awsParameterStorePropertySource."; - private static final String SSM_CLIENT_PREFIX = "awsParameterStoreSource.ssmClient."; + private static final String PROPERTY_SOURCE_PREFIX = "awsParameterStorePropertySource."; + private static final String SOURCE_PREFIX = "awsParameterStoreSource."; + private static final String SSM_CLIENT_ENDPOINT_CONFIG_PREFIX = SOURCE_PREFIX + "ssmClient.endpointConfiguration."; - public static final String ACCEPTED_PROFILE = "awsParameterStorePropertySourceEnabled"; + public static final String ENABLED_PROFILE = "awsParameterStorePropertySourceEnabled"; - public static final String ENABLED = PREFIX + "enabled"; - public static final String ACCEPTED_PROFILES = PREFIX + "enabledProfiles"; - public static final String HALT_BOOT = PREFIX + "haltBoot"; - public static final String SUPPORT_MULTIPLE_APPLICATION_CONTEXTS = PREFIX + "supportMultipleApplicationContexts"; - public static final String SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT = SSM_CLIENT_PREFIX - + "endpointConfiguration.endpoint"; - public static final String SSM_CLIENT_ENDPOINT_CONFIG_SIGNING_REGION = SSM_CLIENT_PREFIX - + "endpointConfiguration.signingRegion"; - public static final String SSM_CLIENT_SIGNING_REGIONS = SSM_CLIENT_PREFIX + "signingRegions"; + public static final String ENABLED = PROPERTY_SOURCE_PREFIX + "enabled"; + public static final String ACCEPTED_PROFILES = PROPERTY_SOURCE_PREFIX + "enabledProfiles"; + public static final String HALT_BOOT = PROPERTY_SOURCE_PREFIX + "haltBoot"; + public static final String SUPPORT_MULTIPLE_APPLICATION_CONTEXTS = PROPERTY_SOURCE_PREFIX + + "supportMultipleApplicationContexts"; + + public static final String SSM_CLIENT_CUSTOM_ENDPOINT = SSM_CLIENT_ENDPOINT_CONFIG_PREFIX + "endpoint"; + public static final String SSM_CLIENT_SIGNING_REGION = SSM_CLIENT_ENDPOINT_CONFIG_PREFIX + "signingRegion"; + public static final String MULTI_REGION_SSM_CLIENT_REGIONS = SOURCE_PREFIX + "multiRegion.ssmClient.regions"; } diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java index 1434399..e62db46 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java @@ -1,8 +1,5 @@ package com.coveo.configuration.parameterstore; -import static com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.DEFAULT_STRATEGY; -import static com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.MULTI_REGION_STRATEGY; - import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.env.ConfigurableEnvironment; @@ -10,12 +7,12 @@ import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategy; import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory; -import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl; +import com.coveo.configuration.parameterstore.strategy.StrategyType; public class ParameterStorePropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor { static boolean initialized; - static ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory postProcessStrategyFactory = new ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl(); + protected static ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory postProcessStrategyFactory = new ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory(); @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) @@ -31,7 +28,7 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringAp private ParameterStorePropertySourceEnvironmentPostProcessStrategy getPostProcessStrategy(ConfigurableEnvironment environment) { - String type = isMultiRegionEnabled(environment) ? MULTI_REGION_STRATEGY : DEFAULT_STRATEGY; + StrategyType type = isMultiRegionEnabled(environment) ? StrategyType.MULTI_REGION : StrategyType.DEFAULT; return postProcessStrategyFactory.getStrategy(type); } @@ -42,7 +39,7 @@ private boolean isParameterStorePropertySourceEnabled(ConfigurableEnvironment en return environment.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, Boolean.class, Boolean.FALSE) - || environment.acceptsProfiles(ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILE) + || environment.acceptsProfiles(ParameterStorePropertySourceConfigurationProperty.ENABLED_PROFILE) || (!ObjectUtils.isEmpty(userDefinedEnabledProfiles) && environment.acceptsProfiles(userDefinedEnabledProfiles)); } @@ -56,6 +53,6 @@ private boolean doesNotSupportMultipleApplicationContexts(ConfigurableEnvironmen private boolean isMultiRegionEnabled(ConfigurableEnvironment environment) { - return environment.containsProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGIONS); + return environment.containsProperty(ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS); } } diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java index 8094f9a..528ad20 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java @@ -1,8 +1,5 @@ package com.coveo.configuration.parameterstore.strategy; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_ENDPOINT_CONFIG_SIGNING_REGION; - import org.springframework.core.env.ConfigurableEnvironment; import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; @@ -56,16 +53,17 @@ private AWSSimpleSystemsManagement buildSSMClient(ConfigurableEnvironment enviro private boolean hasCustomEndpoint(ConfigurableEnvironment environment) { - return environment.containsProperty(SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT); + return environment.containsProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_CUSTOM_ENDPOINT); } private String getCustomEndpoint(ConfigurableEnvironment environment) { - return environment.getProperty(SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT); + return environment.getProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_CUSTOM_ENDPOINT); } private String getSigningRegion(ConfigurableEnvironment environment) { - return environment.getProperty(SSM_CLIENT_ENDPOINT_CONFIG_SIGNING_REGION, awsRegionProviderChain.getRegion()); + return environment.getProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGION, + awsRegionProviderChain.getRegion()); } } diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java index 75eba53..aea18ca 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java @@ -1,19 +1,16 @@ package com.coveo.configuration.parameterstore.strategy; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.HALT_BOOT; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGIONS; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.ListIterator; +import java.util.Collections; +import java.util.List; import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.util.ObjectUtils; +import org.springframework.util.CollectionUtils; import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement; import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; import com.coveo.configuration.parameterstore.ParameterStorePropertySource; +import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty; import com.coveo.configuration.parameterstore.ParameterStoreSource; public class MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy @@ -24,28 +21,26 @@ public class MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrate @Override public void postProcess(ConfigurableEnvironment environment) { - boolean haltBoot = environment.getProperty(HALT_BOOT, Boolean.class, Boolean.FALSE); - - LinkedList signingRegions = getSigningRegions(environment); - ListIterator regionsIterator = signingRegions.listIterator(signingRegions.size()); - - // To keep the order of precedence, we iterate from the last one to the first one because of the method 'addFirst'. - // If we want the first region specified to be the first property source, we have to add it last. - while (regionsIterator.hasPrevious()) { - // We only want to halt boot (if true) for the last property source so the first one added. - boolean shouldHaltBoot = haltBoot && !regionsIterator.hasNext(); - String region = regionsIterator.previous(); - - environment.getPropertySources() - .addFirst(buildParameterStorePropertySource(PARAMETER_STORE_PROPERTY_SOURCE_NAME + region, - region, - shouldHaltBoot)); - } + boolean haltBoot = environment.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, + Boolean.class, + Boolean.FALSE); + + List regions = getRegions(environment); + Collections.reverse(regions); + + String lastRegion = regions.get(0); + environment.getPropertySources().addFirst(buildParameterStorePropertySource(lastRegion, haltBoot)); + + regions.stream() + .skip(1) + .forEach(region -> environment.getPropertySources() + .addFirst(buildParameterStorePropertySource(region, false))); } - private ParameterStorePropertySource buildParameterStorePropertySource(String name, String region, boolean haltBoot) + private ParameterStorePropertySource buildParameterStorePropertySource(String region, boolean haltBoot) { - return new ParameterStorePropertySource(name, new ParameterStoreSource(buildSSMClient(region), haltBoot)); + return new ParameterStorePropertySource(PARAMETER_STORE_PROPERTY_SOURCE_NAME + region, + new ParameterStoreSource(buildSSMClient(region), haltBoot)); } private AWSSimpleSystemsManagement buildSSMClient(String region) @@ -53,10 +48,16 @@ private AWSSimpleSystemsManagement buildSSMClient(String region) return AWSSimpleSystemsManagementClientBuilder.standard().withRegion(region).build(); } - private LinkedList getSigningRegions(ConfigurableEnvironment environment) + private List getRegions(ConfigurableEnvironment environment) { - String[] signingRegions = environment.getProperty(SSM_CLIENT_SIGNING_REGIONS, String[].class); - return ObjectUtils.isEmpty(signingRegions) ? new LinkedList<>() - : new LinkedList<>(Arrays.asList(signingRegions)); + List regions = CollectionUtils.arrayToList(environment.getProperty(ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS, + String[].class)); + + if (CollectionUtils.isEmpty(regions)) { + throw new IllegalArgumentException(String.format("To enable multi region support, the property '%s' must not be empty.", + ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS)); + } + + return regions; } } diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java index 9688e9c..f4a8fd7 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java @@ -1,6 +1,22 @@ package com.coveo.configuration.parameterstore.strategy; -public interface ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory +import java.util.EnumMap; + +import com.amazonaws.regions.DefaultAwsRegionProviderChain; + +public class ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory { - ParameterStorePropertySourceEnvironmentPostProcessStrategy getStrategy(String type); + private static EnumMap strategies = new EnumMap<>(StrategyType.class); + + static { + strategies.put(StrategyType.DEFAULT, + new DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy(new DefaultAwsRegionProviderChain())); + strategies.put(StrategyType.MULTI_REGION, + new MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy()); + } + + public ParameterStorePropertySourceEnvironmentPostProcessStrategy getStrategy(StrategyType strategyType) + { + return strategies.get(strategyType); + } } diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.java deleted file mode 100644 index f032768..0000000 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.coveo.configuration.parameterstore.strategy; - -import java.util.HashMap; -import java.util.Map; - -import com.amazonaws.regions.DefaultAwsRegionProviderChain; - -public class ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl - implements ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory -{ - public static final String DEFAULT_STRATEGY = "Default"; - public static final String MULTI_REGION_STRATEGY = "MultiRegion"; - - private static Map strategies = new HashMap<>(); - - static { - strategies.put(DEFAULT_STRATEGY, - new DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy(new DefaultAwsRegionProviderChain())); - strategies.put(MULTI_REGION_STRATEGY, - new MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy()); - } - - @Override - public ParameterStorePropertySourceEnvironmentPostProcessStrategy getStrategy(String type) - { - return strategies.get(type); - } -} diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/StrategyType.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/StrategyType.java new file mode 100644 index 0000000..e8787fd --- /dev/null +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/StrategyType.java @@ -0,0 +1,6 @@ +package com.coveo.configuration.parameterstore.strategy; + +public enum StrategyType +{ + DEFAULT, MULTI_REGION; +} diff --git a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java index 5530487..dec1b95 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java @@ -3,10 +3,6 @@ import static com.amazonaws.SDKGlobalConfiguration.ACCESS_KEY_ENV_VAR; import static com.amazonaws.SDKGlobalConfiguration.AWS_REGION_SYSTEM_PROPERTY; import static com.amazonaws.SDKGlobalConfiguration.SECRET_KEY_ENV_VAR; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILE; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.ENABLED; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -23,7 +19,7 @@ import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategy; import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory; -import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl; +import com.coveo.configuration.parameterstore.strategy.StrategyType; @RunWith(MockitoJUnitRunner.class) public class ParameterStorePropertySourceEnvironmentPostProcessorTest @@ -49,12 +45,14 @@ public void setUp() { ParameterStorePropertySourceEnvironmentPostProcessor.initialized = false; - when(postProcessStrategyFactoryMock.getStrategy(ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.DEFAULT_STRATEGY)).thenReturn(defaultPostProcessStrategyMock); - when(postProcessStrategyFactoryMock.getStrategy(ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.MULTI_REGION_STRATEGY)).thenReturn(multiRegionPostProcessStrategyMock); + when(postProcessStrategyFactoryMock.getStrategy(StrategyType.DEFAULT)).thenReturn(defaultPostProcessStrategyMock); + when(postProcessStrategyFactoryMock.getStrategy(StrategyType.MULTI_REGION)).thenReturn(multiRegionPostProcessStrategyMock); ParameterStorePropertySourceEnvironmentPostProcessor.postProcessStrategyFactory = postProcessStrategyFactoryMock; - when(configurableEnvironmentMock.getProperty(ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); - when(configurableEnvironmentMock.getProperty(SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.FALSE); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); @@ -77,7 +75,9 @@ public void testParameterStoreIsDisabledByDefault() @Test public void testParameterStoreIsEnabledWithPropertySetToTrue() { - when(configurableEnvironmentMock.getProperty(ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.TRUE); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); @@ -89,7 +89,7 @@ public void testParameterStoreIsEnabledWithPropertySetToTrue() @Test public void testParameterStoreIsEnabledWithProfile() { - when(configurableEnvironmentMock.acceptsProfiles(ACCEPTED_PROFILE)).thenReturn(true); + when(configurableEnvironmentMock.acceptsProfiles(ParameterStorePropertySourceConfigurationProperty.ENABLED_PROFILE)).thenReturn(true); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); @@ -101,7 +101,8 @@ public void testParameterStoreIsEnabledWithProfile() @Test public void testParameterStoreIsEnabledWithCustomProfiles() { - when(configurableEnvironmentMock.getProperty(ACCEPTED_PROFILES, String[].class)).thenReturn(CUSTOM_PROFILES); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES, + String[].class)).thenReturn(CUSTOM_PROFILES); when(configurableEnvironmentMock.acceptsProfiles(CUSTOM_PROFILES)).thenReturn(true); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, @@ -114,7 +115,7 @@ public void testParameterStoreIsEnabledWithCustomProfiles() @Test public void testParameterStoreIsNotEnabledWithCustomProfilesEmpty() { - when(configurableEnvironmentMock.getProperty(ACCEPTED_PROFILES, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES, String[].class)).thenReturn(EMPTY_CUSTOM_PROFILES); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, @@ -128,7 +129,8 @@ public void testParameterStoreIsNotEnabledWithCustomProfilesEmpty() @Test public void testParameterStoreIsNotEnabledWithCustomProfilesButNoneOfTheProfilesActive() { - when(configurableEnvironmentMock.getProperty(ACCEPTED_PROFILES, String[].class)).thenReturn(CUSTOM_PROFILES); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES, + String[].class)).thenReturn(CUSTOM_PROFILES); when(configurableEnvironmentMock.acceptsProfiles(CUSTOM_PROFILES)).thenReturn(false); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, @@ -141,7 +143,9 @@ public void testParameterStoreIsNotEnabledWithCustomProfilesButNoneOfTheProfiles @Test public void testParameterStorePropertySourceEnvironmentPostProcessorCantBeCalledTwice() { - when(configurableEnvironmentMock.getProperty(ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.TRUE); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); @@ -156,8 +160,10 @@ public void testParameterStorePropertySourceEnvironmentPostProcessorCantBeCalled @Test public void testParameterStorePropertySourceEnvironmentPostProcessorCanBeCalledTwiceWhenDisablingMultipleContextSupport() { - when(configurableEnvironmentMock.getProperty(ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); @@ -174,8 +180,10 @@ public void testParameterStorePropertySourceEnvironmentPostProcessorCanBeCalledT @Test public void testWhenMultiRegionIsEnabled() { - when(configurableEnvironmentMock.getProperty(ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGIONS)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS)).thenReturn(Boolean.TRUE); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java index d9f5b47..35b7c10 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java @@ -1,7 +1,5 @@ package com.coveo.configuration.parameterstore.strategy; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.HALT_BOOT; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_ENDPOINT_CONFIG_SIGNING_REGION; import static org.mockito.Matchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -35,11 +33,11 @@ public class DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTe public void setUp() { when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); - when(configurableEnvironmentMock.getProperty(HALT_BOOT, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); when(awsRegionProviderChain.getRegion()).thenReturn("aRegion"); - when(configurableEnvironmentMock.getProperty(SSM_CLIENT_ENDPOINT_CONFIG_SIGNING_REGION, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGION, awsRegionProviderChain.getRegion())).thenReturn("aRegion"); postProcessStrategy = new DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy(awsRegionProviderChain); @@ -56,8 +54,8 @@ public void testShouldAddPropertySource() @Test public void testWhenCustomEndpointShouldAddPropertySource() { - when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_ENDPOINT_CONFIG_ENDPOINT)).thenReturn("customEndpoint"); + when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_CUSTOM_ENDPOINT)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_CUSTOM_ENDPOINT)).thenReturn("customEndpoint"); postProcessStrategy.postProcess(configurableEnvironmentMock); diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java index 516b482..b218121 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java @@ -1,7 +1,5 @@ package com.coveo.configuration.parameterstore.strategy; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.HALT_BOOT; -import static com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGIONS; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.StringEndsWith.endsWith; import static org.junit.Assert.assertThat; @@ -23,6 +21,7 @@ import org.springframework.test.util.ReflectionTestUtils; import com.coveo.configuration.parameterstore.ParameterStorePropertySource; +import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty; @RunWith(MockitoJUnitRunner.class) public class MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest @@ -44,10 +43,10 @@ public class MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrate public void setUp() { when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); - when(configurableEnvironmentMock.getProperty(HALT_BOOT, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); - when(configurableEnvironmentMock.getProperty(SSM_CLIENT_SIGNING_REGIONS, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS, String[].class)).thenReturn(SIGNING_REGIONS); postProcessStrategy = new MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy(); @@ -60,40 +59,43 @@ public void testShouldAddPropertySourceForEverySigningRegionsInOrderOfPrecedence verify(mutablePropertySourcesMock, times(3)).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); - List parameterStorePropertySources = parameterStorePropertySourceArgumentCaptor.getAllValues(); + List propertySources = parameterStorePropertySourceArgumentCaptor.getAllValues(); - verifyParameterStorePropertySource(parameterStorePropertySources.get(0), SIGNING_REGIONS[2], Boolean.FALSE); - verifyParameterStorePropertySource(parameterStorePropertySources.get(1), SIGNING_REGIONS[1], Boolean.FALSE); - verifyParameterStorePropertySource(parameterStorePropertySources.get(2), SIGNING_REGIONS[0], Boolean.FALSE); + verifyParameterStorePropertySource(propertySources.get(0), SIGNING_REGIONS[0], Boolean.FALSE); + verifyParameterStorePropertySource(propertySources.get(1), SIGNING_REGIONS[1], Boolean.FALSE); + verifyParameterStorePropertySource(propertySources.get(2), SIGNING_REGIONS[2], Boolean.FALSE); } @Test public void testHaltBootIsTrueThenOnlyLastRegionShouldHaltBoot() { - when(configurableEnvironmentMock.getProperty(HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.TRUE); postProcessStrategy.postProcess(configurableEnvironmentMock); verify(mutablePropertySourcesMock, times(3)).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); - List parameterStorePropertySources = parameterStorePropertySourceArgumentCaptor.getAllValues(); + List propertySources = parameterStorePropertySourceArgumentCaptor.getAllValues(); - verifyParameterStorePropertySource(parameterStorePropertySources.get(0), SIGNING_REGIONS[2], Boolean.TRUE); - verifyParameterStorePropertySource(parameterStorePropertySources.get(1), SIGNING_REGIONS[1], Boolean.FALSE); - verifyParameterStorePropertySource(parameterStorePropertySources.get(2), SIGNING_REGIONS[0], Boolean.FALSE); + verifyParameterStorePropertySource(propertySources.get(0), SIGNING_REGIONS[0], Boolean.TRUE); + verifyParameterStorePropertySource(propertySources.get(1), SIGNING_REGIONS[1], Boolean.FALSE); + verifyParameterStorePropertySource(propertySources.get(2), SIGNING_REGIONS[2], Boolean.FALSE); } @Test public void testWithSingleRegion() { - when(configurableEnvironmentMock.getProperty(HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(SSM_CLIENT_SIGNING_REGIONS, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, + Boolean.class, + Boolean.FALSE)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS, String[].class)).thenReturn(SINGLE_SIGNING_REGIONS); postProcessStrategy.postProcess(configurableEnvironmentMock); verify(mutablePropertySourcesMock).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); - verifyParameterStorePropertySource(parameterStorePropertySourceArgumentCaptor.getValue(), SINGLE_SIGNING_REGIONS[0], Boolean.TRUE); diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryTest.java similarity index 72% rename from src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java rename to src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryTest.java index 658d80e..8ec19ea 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryTest.java @@ -3,8 +3,6 @@ import static com.amazonaws.SDKGlobalConfiguration.ACCESS_KEY_ENV_VAR; import static com.amazonaws.SDKGlobalConfiguration.AWS_REGION_SYSTEM_PROPERTY; import static com.amazonaws.SDKGlobalConfiguration.SECRET_KEY_ENV_VAR; -import static com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.DEFAULT_STRATEGY; -import static com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl.MULTI_REGION_STRATEGY; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; @@ -12,14 +10,14 @@ import org.junit.Before; import org.junit.Test; -public class ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImplTest +public class ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryTest { private ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory factory; @Before public void setUp() { - factory = new ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryImpl(); + factory = new ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory(); System.setProperty(ACCESS_KEY_ENV_VAR, "id"); System.setProperty(SECRET_KEY_ENV_VAR, "secret"); @@ -29,14 +27,14 @@ public void setUp() @Test public void testGettingDefaultStrategy() { - assertThat(factory.getStrategy(DEFAULT_STRATEGY), + assertThat(factory.getStrategy(StrategyType.DEFAULT), is(instanceOf(DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.class))); } @Test public void testGettingMultiRegionStrategy() { - assertThat(factory.getStrategy(MULTI_REGION_STRATEGY), + assertThat(factory.getStrategy(StrategyType.MULTI_REGION), is(instanceOf(MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.class))); } } From bdbe46ea76038607426856744aaafa8713221471 Mon Sep 17 00:00:00 2001 From: Marie-Christine Noreau Date: Tue, 18 Feb 2020 22:35:01 -0500 Subject: [PATCH 6/7] Refactoring after second review --- readme.md | 3 +- ...PropertySourceConfigurationProperties.java | 31 ++++++++++++ ...rePropertySourceConfigurationProperty.java | 20 -------- ...ropertySourceEnvironmentPostProcessor.java | 20 ++++---- ...ePropertySourceConfigurationStrategy.java} | 18 +++---- ...ePropertySourceConfigurationStrategy.java} | 22 +++++---- ...rePropertySourceConfigurationStrategy.java | 8 ++++ ...tySourceConfigurationStrategyFactory.java} | 10 ++-- ...ySourceEnvironmentPostProcessStrategy.java | 8 ---- ...rtySourceEnvironmentPostProcessorTest.java | 48 ++++++++++--------- ...pertySourceConfigurationStrategyTest.java} | 20 ++++---- ...pertySourceConfigurationStrategyTest.java} | 24 +++++----- ...urceConfigurationStrategyFactoryTest.java} | 10 ++-- 13 files changed, 131 insertions(+), 111 deletions(-) create mode 100644 src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperties.java delete mode 100644 src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java rename src/main/java/com/coveo/configuration/parameterstore/strategy/{DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java => DefaultParameterStorePropertySourceConfigurationStrategy.java} (82%) rename src/main/java/com/coveo/configuration/parameterstore/strategy/{MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java => MultiRegionParameterStorePropertySourceConfigurationStrategy.java} (73%) create mode 100644 src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategy.java rename src/main/java/com/coveo/configuration/parameterstore/strategy/{ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java => ParameterStorePropertySourceConfigurationStrategyFactory.java} (50%) delete mode 100644 src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategy.java rename src/test/java/com/coveo/configuration/parameterstore/strategy/{DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java => DefaultParameterStorePropertySourceConfigurationStrategyTest.java} (73%) rename src/test/java/com/coveo/configuration/parameterstore/strategy/{MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java => MultiRegionParameterStorePropertySourceConfigurationStrategyTest.java} (84%) rename src/test/java/com/coveo/configuration/parameterstore/strategy/{ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryTest.java => ParameterStorePropertySourceConfigurationStrategyFactoryTest.java} (75%) diff --git a/readme.md b/readme.md index f9f8b69..5befd4f 100644 --- a/readme.md +++ b/readme.md @@ -85,7 +85,8 @@ If you still want the post processor to run twice or if you are using [spring-bo - Set `awsParameterStoreSource.multiRegion.ssmClient.regions` with the regions from which you need to retrieve parameters using a **comma-separated** list such as `us-east-1,us-east-2`. It adds a PropertySource for each region specified. It will start looking from the first region and so on until it finds the property so put the regions in order of precedence. **Reminder**: using other list injecting methods like a yaml list won't work because this property gets loaded too early in the boot process. - If you want to halt the boot when a property isn't found in any of the specified regions, just set `awsParameterStorePropertySource.haltBoot` to `true` in your properties. -- Make sure that your service has the necessary permissions to access parameters in the specified regions. +- Make sure that your service has the necessary permissions to access parameters in the specified regions. +**Important**: If set, it takes precedence over `awsParameterStoreSource.ssmClient.endpointConfiguration.endpoint` and `awsParameterStoreSource.ssmClient.endpointConfiguration.signingRegion`. They are mutually exclusive. ## Contributing Open an issue to report bugs or to request additional features. Pull requests are always welcome. diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperties.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperties.java new file mode 100644 index 0000000..30f322c --- /dev/null +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperties.java @@ -0,0 +1,31 @@ +package com.coveo.configuration.parameterstore; + +public final class ParameterStorePropertySourceConfigurationProperties +{ + private static final String PROPERTY_SOURCE_PREFIX = "awsParameterStorePropertySource"; + private static final String SOURCE_PREFIX = "awsParameterStoreSource"; + private static final String SSM_CLIENT_ENDPOINT_CONFIG_PREFIX = joinWithDot(SOURCE_PREFIX, + "ssmClient", + "endpointConfiguration"); + + public static final String ENABLED_PROFILE = "awsParameterStorePropertySourceEnabled"; + + public static final String ENABLED = joinWithDot(PROPERTY_SOURCE_PREFIX, "enabled"); + public static final String ACCEPTED_PROFILES = joinWithDot(PROPERTY_SOURCE_PREFIX, "enabledProfiles"); + public static final String HALT_BOOT = joinWithDot(PROPERTY_SOURCE_PREFIX, "haltBoot"); + public static final String SUPPORT_MULTIPLE_APPLICATION_CONTEXTS = joinWithDot(PROPERTY_SOURCE_PREFIX, + "supportMultipleApplicationContexts"); + + public static final String SSM_CLIENT_CUSTOM_ENDPOINT = joinWithDot(SSM_CLIENT_ENDPOINT_CONFIG_PREFIX, "endpoint"); + public static final String SSM_CLIENT_SIGNING_REGION = joinWithDot(SSM_CLIENT_ENDPOINT_CONFIG_PREFIX, + "signingRegion"); + public static final String MULTI_REGION_SSM_CLIENT_REGIONS = joinWithDot(SOURCE_PREFIX, + "multiRegion", + "ssmClient", + "regions"); + + private static String joinWithDot(String... elements) + { + return String.join(".", elements); + } +} diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java deleted file mode 100644 index 6af1f7a..0000000 --- a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceConfigurationProperty.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.coveo.configuration.parameterstore; - -public final class ParameterStorePropertySourceConfigurationProperty -{ - private static final String PROPERTY_SOURCE_PREFIX = "awsParameterStorePropertySource."; - private static final String SOURCE_PREFIX = "awsParameterStoreSource."; - private static final String SSM_CLIENT_ENDPOINT_CONFIG_PREFIX = SOURCE_PREFIX + "ssmClient.endpointConfiguration."; - - public static final String ENABLED_PROFILE = "awsParameterStorePropertySourceEnabled"; - - public static final String ENABLED = PROPERTY_SOURCE_PREFIX + "enabled"; - public static final String ACCEPTED_PROFILES = PROPERTY_SOURCE_PREFIX + "enabledProfiles"; - public static final String HALT_BOOT = PROPERTY_SOURCE_PREFIX + "haltBoot"; - public static final String SUPPORT_MULTIPLE_APPLICATION_CONTEXTS = PROPERTY_SOURCE_PREFIX - + "supportMultipleApplicationContexts"; - - public static final String SSM_CLIENT_CUSTOM_ENDPOINT = SSM_CLIENT_ENDPOINT_CONFIG_PREFIX + "endpoint"; - public static final String SSM_CLIENT_SIGNING_REGION = SSM_CLIENT_ENDPOINT_CONFIG_PREFIX + "signingRegion"; - public static final String MULTI_REGION_SSM_CLIENT_REGIONS = SOURCE_PREFIX + "multiRegion.ssmClient.regions"; -} diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java index e62db46..a376724 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java @@ -5,20 +5,20 @@ import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.util.ObjectUtils; -import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategy; -import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory; +import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceConfigurationStrategy; +import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceConfigurationStrategyFactory; import com.coveo.configuration.parameterstore.strategy.StrategyType; public class ParameterStorePropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor { static boolean initialized; - protected static ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory postProcessStrategyFactory = new ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory(); + protected static ParameterStorePropertySourceConfigurationStrategyFactory postProcessStrategyFactory = new ParameterStorePropertySourceConfigurationStrategyFactory(); @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { if (!initialized && isParameterStorePropertySourceEnabled(environment)) { - getPostProcessStrategy(environment).postProcess(environment); + getPostProcessStrategy(environment).configureParameterStorePropertySources(environment); if (doesNotSupportMultipleApplicationContexts(environment)) { initialized = true; @@ -26,7 +26,7 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringAp } } - private ParameterStorePropertySourceEnvironmentPostProcessStrategy getPostProcessStrategy(ConfigurableEnvironment environment) + private ParameterStorePropertySourceConfigurationStrategy getPostProcessStrategy(ConfigurableEnvironment environment) { StrategyType type = isMultiRegionEnabled(environment) ? StrategyType.MULTI_REGION : StrategyType.DEFAULT; return postProcessStrategyFactory.getStrategy(type); @@ -34,25 +34,25 @@ private ParameterStorePropertySourceEnvironmentPostProcessStrategy getPostProces private boolean isParameterStorePropertySourceEnabled(ConfigurableEnvironment environment) { - String[] userDefinedEnabledProfiles = environment.getProperty(ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES, + String[] userDefinedEnabledProfiles = environment.getProperty(ParameterStorePropertySourceConfigurationProperties.ACCEPTED_PROFILES, String[].class); - return environment.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + return environment.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, Boolean.FALSE) - || environment.acceptsProfiles(ParameterStorePropertySourceConfigurationProperty.ENABLED_PROFILE) + || environment.acceptsProfiles(ParameterStorePropertySourceConfigurationProperties.ENABLED_PROFILE) || (!ObjectUtils.isEmpty(userDefinedEnabledProfiles) && environment.acceptsProfiles(userDefinedEnabledProfiles)); } private boolean doesNotSupportMultipleApplicationContexts(ConfigurableEnvironment environment) { - return !environment.getProperty(ParameterStorePropertySourceConfigurationProperty.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, + return !environment.getProperty(ParameterStorePropertySourceConfigurationProperties.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, Boolean.class, Boolean.FALSE); } private boolean isMultiRegionEnabled(ConfigurableEnvironment environment) { - return environment.containsProperty(ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS); + return environment.containsProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS); } } diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategy.java similarity index 82% rename from src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java rename to src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategy.java index 528ad20..315e515 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategy.java @@ -8,25 +8,25 @@ import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; import com.coveo.configuration.parameterstore.ParameterStorePropertySource; -import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty; +import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperties; import com.coveo.configuration.parameterstore.ParameterStoreSource; -public class DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy - implements ParameterStorePropertySourceEnvironmentPostProcessStrategy +public class DefaultParameterStorePropertySourceConfigurationStrategy + implements ParameterStorePropertySourceConfigurationStrategy { private static final String PARAMETER_STORE_PROPERTY_SOURCE_NAME = "AWSParameterStorePropertySource"; private AwsRegionProviderChain awsRegionProviderChain; - public DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy(AwsRegionProviderChain awsRegionProviderChain) + public DefaultParameterStorePropertySourceConfigurationStrategy(AwsRegionProviderChain awsRegionProviderChain) { this.awsRegionProviderChain = awsRegionProviderChain; } @Override - public void postProcess(ConfigurableEnvironment environment) + public void configureParameterStorePropertySources(ConfigurableEnvironment environment) { - boolean haltBoot = environment.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, + boolean haltBoot = environment.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, Boolean.FALSE); environment.getPropertySources() @@ -53,17 +53,17 @@ private AWSSimpleSystemsManagement buildSSMClient(ConfigurableEnvironment enviro private boolean hasCustomEndpoint(ConfigurableEnvironment environment) { - return environment.containsProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_CUSTOM_ENDPOINT); + return environment.containsProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_CUSTOM_ENDPOINT); } private String getCustomEndpoint(ConfigurableEnvironment environment) { - return environment.getProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_CUSTOM_ENDPOINT); + return environment.getProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_CUSTOM_ENDPOINT); } private String getSigningRegion(ConfigurableEnvironment environment) { - return environment.getProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGION, + return environment.getProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_SIGNING_REGION, awsRegionProviderChain.getRegion()); } } diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategy.java similarity index 73% rename from src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java rename to src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategy.java index aea18ca..90626d8 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategy.java @@ -10,25 +10,31 @@ import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; import com.coveo.configuration.parameterstore.ParameterStorePropertySource; -import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty; +import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperties; import com.coveo.configuration.parameterstore.ParameterStoreSource; -public class MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy - implements ParameterStorePropertySourceEnvironmentPostProcessStrategy +public class MultiRegionParameterStorePropertySourceConfigurationStrategy + implements ParameterStorePropertySourceConfigurationStrategy { private static final String PARAMETER_STORE_PROPERTY_SOURCE_NAME = "MultiRegionAWSParameterStorePropertySource_"; @Override - public void postProcess(ConfigurableEnvironment environment) + public void configureParameterStorePropertySources(ConfigurableEnvironment environment) { - boolean haltBoot = environment.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, + boolean haltBoot = environment.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, Boolean.FALSE); List regions = getRegions(environment); - Collections.reverse(regions); + // To keep the order of precedence, we have to iterate from the last region to the first one. + // If we want the first region specified to be the first property source, we have to add it last. + // We cannot use addLast since it adds the property source with lowest precedence and we want the + // Parameter store property sources to have highest precedence on the other property sources + Collections.reverse(regions); String lastRegion = regions.get(0); + + // We only want to halt boot (if true) for the last region environment.getPropertySources().addFirst(buildParameterStorePropertySource(lastRegion, haltBoot)); regions.stream() @@ -50,12 +56,12 @@ private AWSSimpleSystemsManagement buildSSMClient(String region) private List getRegions(ConfigurableEnvironment environment) { - List regions = CollectionUtils.arrayToList(environment.getProperty(ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS, + List regions = CollectionUtils.arrayToList(environment.getProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS, String[].class)); if (CollectionUtils.isEmpty(regions)) { throw new IllegalArgumentException(String.format("To enable multi region support, the property '%s' must not be empty.", - ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS)); + ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS)); } return regions; diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategy.java new file mode 100644 index 0000000..95aad5e --- /dev/null +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategy.java @@ -0,0 +1,8 @@ +package com.coveo.configuration.parameterstore.strategy; + +import org.springframework.core.env.ConfigurableEnvironment; + +public interface ParameterStorePropertySourceConfigurationStrategy +{ + void configureParameterStorePropertySources(ConfigurableEnvironment environment); +} diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactory.java similarity index 50% rename from src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java rename to src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactory.java index f4a8fd7..4e58cf8 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactory.java @@ -4,18 +4,18 @@ import com.amazonaws.regions.DefaultAwsRegionProviderChain; -public class ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory +public class ParameterStorePropertySourceConfigurationStrategyFactory { - private static EnumMap strategies = new EnumMap<>(StrategyType.class); + private static EnumMap strategies = new EnumMap<>(StrategyType.class); static { strategies.put(StrategyType.DEFAULT, - new DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy(new DefaultAwsRegionProviderChain())); + new DefaultParameterStorePropertySourceConfigurationStrategy(new DefaultAwsRegionProviderChain())); strategies.put(StrategyType.MULTI_REGION, - new MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy()); + new MultiRegionParameterStorePropertySourceConfigurationStrategy()); } - public ParameterStorePropertySourceEnvironmentPostProcessStrategy getStrategy(StrategyType strategyType) + public ParameterStorePropertySourceConfigurationStrategy getStrategy(StrategyType strategyType) { return strategies.get(strategyType); } diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategy.java deleted file mode 100644 index fbc5e07..0000000 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategy.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.coveo.configuration.parameterstore.strategy; - -import org.springframework.core.env.ConfigurableEnvironment; - -public interface ParameterStorePropertySourceEnvironmentPostProcessStrategy -{ - void postProcess(ConfigurableEnvironment environment); -} diff --git a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java index dec1b95..b5a8875 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java @@ -17,8 +17,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.core.env.ConfigurableEnvironment; -import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategy; -import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory; +import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceConfigurationStrategy; +import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceConfigurationStrategyFactory; import com.coveo.configuration.parameterstore.strategy.StrategyType; @RunWith(MockitoJUnitRunner.class) @@ -32,11 +32,11 @@ public class ParameterStorePropertySourceEnvironmentPostProcessorTest @Mock private SpringApplication applicationMock; @Mock - private ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory postProcessStrategyFactoryMock; + private ParameterStorePropertySourceConfigurationStrategyFactory postProcessStrategyFactoryMock; @Mock - private ParameterStorePropertySourceEnvironmentPostProcessStrategy defaultPostProcessStrategyMock; + private ParameterStorePropertySourceConfigurationStrategy defaultPostProcessStrategyMock; @Mock - private ParameterStorePropertySourceEnvironmentPostProcessStrategy multiRegionPostProcessStrategyMock; + private ParameterStorePropertySourceConfigurationStrategy multiRegionPostProcessStrategyMock; private ParameterStorePropertySourceEnvironmentPostProcessor parameterStorePropertySourceEnvironmentPostProcessor = new ParameterStorePropertySourceEnvironmentPostProcessor(); @@ -49,10 +49,10 @@ public void setUp() when(postProcessStrategyFactoryMock.getStrategy(StrategyType.MULTI_REGION)).thenReturn(multiRegionPostProcessStrategyMock); ParameterStorePropertySourceEnvironmentPostProcessor.postProcessStrategyFactory = postProcessStrategyFactoryMock; - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); @@ -75,47 +75,47 @@ public void testParameterStoreIsDisabledByDefault() @Test public void testParameterStoreIsEnabledWithPropertySetToTrue() { - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); + verify(defaultPostProcessStrategyMock).configureParameterStorePropertySources(configurableEnvironmentMock); verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test public void testParameterStoreIsEnabledWithProfile() { - when(configurableEnvironmentMock.acceptsProfiles(ParameterStorePropertySourceConfigurationProperty.ENABLED_PROFILE)).thenReturn(true); + when(configurableEnvironmentMock.acceptsProfiles(ParameterStorePropertySourceConfigurationProperties.ENABLED_PROFILE)).thenReturn(true); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); + verify(defaultPostProcessStrategyMock).configureParameterStorePropertySources(configurableEnvironmentMock); verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test public void testParameterStoreIsEnabledWithCustomProfiles() { - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ACCEPTED_PROFILES, String[].class)).thenReturn(CUSTOM_PROFILES); when(configurableEnvironmentMock.acceptsProfiles(CUSTOM_PROFILES)).thenReturn(true); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); + verify(defaultPostProcessStrategyMock).configureParameterStorePropertySources(configurableEnvironmentMock); verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test public void testParameterStoreIsNotEnabledWithCustomProfilesEmpty() { - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ACCEPTED_PROFILES, String[].class)).thenReturn(EMPTY_CUSTOM_PROFILES); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, @@ -129,7 +129,7 @@ public void testParameterStoreIsNotEnabledWithCustomProfilesEmpty() @Test public void testParameterStoreIsNotEnabledWithCustomProfilesButNoneOfTheProfilesActive() { - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ACCEPTED_PROFILES, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ACCEPTED_PROFILES, String[].class)).thenReturn(CUSTOM_PROFILES); when(configurableEnvironmentMock.acceptsProfiles(CUSTOM_PROFILES)).thenReturn(false); @@ -143,7 +143,7 @@ public void testParameterStoreIsNotEnabledWithCustomProfilesButNoneOfTheProfiles @Test public void testParameterStorePropertySourceEnvironmentPostProcessorCantBeCalledTwice() { - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); @@ -153,17 +153,17 @@ public void testParameterStorePropertySourceEnvironmentPostProcessorCantBeCalled parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(defaultPostProcessStrategyMock).postProcess(configurableEnvironmentMock); + verify(defaultPostProcessStrategyMock).configureParameterStorePropertySources(configurableEnvironmentMock); verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test public void testParameterStorePropertySourceEnvironmentPostProcessorCanBeCalledTwiceWhenDisablingMultipleContextSupport() { - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.SUPPORT_MULTIPLE_APPLICATION_CONTEXTS, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); @@ -173,22 +173,24 @@ public void testParameterStorePropertySourceEnvironmentPostProcessorCanBeCalledT parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(defaultPostProcessStrategyMock, times(2)).postProcess(configurableEnvironmentMock); + verify(defaultPostProcessStrategyMock, + times(2)).configureParameterStorePropertySources(configurableEnvironmentMock); verifyZeroInteractions(multiRegionPostProcessStrategyMock); } @Test public void testWhenMultiRegionIsEnabled() { - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.ENABLED, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS)).thenReturn(Boolean.TRUE); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verify(multiRegionPostProcessStrategyMock, times(1)).postProcess(configurableEnvironmentMock); + verify(multiRegionPostProcessStrategyMock, + times(1)).configureParameterStorePropertySources(configurableEnvironmentMock); verifyZeroInteractions(defaultPostProcessStrategyMock); } } diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategyTest.java similarity index 73% rename from src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java rename to src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategyTest.java index 35b7c10..e243fbb 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategyTest.java @@ -15,10 +15,10 @@ import com.amazonaws.regions.AwsRegionProviderChain; import com.coveo.configuration.parameterstore.ParameterStorePropertySource; -import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty; +import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperties; @RunWith(MockitoJUnitRunner.class) -public class DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTest +public class DefaultParameterStorePropertySourceConfigurationStrategyTest { @Mock private ConfigurableEnvironment configurableEnvironmentMock; @@ -27,26 +27,26 @@ public class DefaultParameterStorePropertySourceEnvironmentPostProcessStrategyTe @Mock private AwsRegionProviderChain awsRegionProviderChain; - private DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy postProcessStrategy; + private DefaultParameterStorePropertySourceConfigurationStrategy postProcessStrategy; @Before public void setUp() { when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); when(awsRegionProviderChain.getRegion()).thenReturn("aRegion"); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_SIGNING_REGION, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_SIGNING_REGION, awsRegionProviderChain.getRegion())).thenReturn("aRegion"); - postProcessStrategy = new DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy(awsRegionProviderChain); + postProcessStrategy = new DefaultParameterStorePropertySourceConfigurationStrategy(awsRegionProviderChain); } @Test public void testShouldAddPropertySource() { - postProcessStrategy.postProcess(configurableEnvironmentMock); + postProcessStrategy.configureParameterStorePropertySources(configurableEnvironmentMock); verify(mutablePropertySourcesMock).addFirst(any(ParameterStorePropertySource.class)); } @@ -54,10 +54,10 @@ public void testShouldAddPropertySource() @Test public void testWhenCustomEndpointShouldAddPropertySource() { - when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_CUSTOM_ENDPOINT)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.SSM_CLIENT_CUSTOM_ENDPOINT)).thenReturn("customEndpoint"); + when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_CUSTOM_ENDPOINT)).thenReturn(Boolean.TRUE); + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_CUSTOM_ENDPOINT)).thenReturn("customEndpoint"); - postProcessStrategy.postProcess(configurableEnvironmentMock); + postProcessStrategy.configureParameterStorePropertySources(configurableEnvironmentMock); verify(mutablePropertySourcesMock).addFirst(any(ParameterStorePropertySource.class)); } diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategyTest.java similarity index 84% rename from src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java rename to src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategyTest.java index b218121..1a1e77b 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategyTest.java @@ -21,10 +21,10 @@ import org.springframework.test.util.ReflectionTestUtils; import com.coveo.configuration.parameterstore.ParameterStorePropertySource; -import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperty; +import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperties; @RunWith(MockitoJUnitRunner.class) -public class MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategyTest +public class MultiRegionParameterStorePropertySourceConfigurationStrategyTest { private static final String[] SIGNING_REGIONS = { "ownRegion", "mainRegion", "defaultRegion" }; private static final String[] SINGLE_SIGNING_REGIONS = { "ownRegion" }; @@ -37,25 +37,25 @@ public class MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrate @Captor private ArgumentCaptor parameterStorePropertySourceArgumentCaptor; - private MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy postProcessStrategy; + private MultiRegionParameterStorePropertySourceConfigurationStrategy postProcessStrategy; @Before public void setUp() { when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS, String[].class)).thenReturn(SIGNING_REGIONS); - postProcessStrategy = new MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy(); + postProcessStrategy = new MultiRegionParameterStorePropertySourceConfigurationStrategy(); } @Test public void testShouldAddPropertySourceForEverySigningRegionsInOrderOfPrecedence() { - postProcessStrategy.postProcess(configurableEnvironmentMock); + postProcessStrategy.configureParameterStorePropertySources(configurableEnvironmentMock); verify(mutablePropertySourcesMock, times(3)).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); @@ -69,11 +69,11 @@ public void testShouldAddPropertySourceForEverySigningRegionsInOrderOfPrecedence @Test public void testHaltBootIsTrueThenOnlyLastRegionShouldHaltBoot() { - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - postProcessStrategy.postProcess(configurableEnvironmentMock); + postProcessStrategy.configureParameterStorePropertySources(configurableEnvironmentMock); verify(mutablePropertySourcesMock, times(3)).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); @@ -87,13 +87,13 @@ public void testHaltBootIsTrueThenOnlyLastRegionShouldHaltBoot() @Test public void testWithSingleRegion() { - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.HALT_BOOT, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperty.MULTI_REGION_SSM_CLIENT_REGIONS, + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS, String[].class)).thenReturn(SINGLE_SIGNING_REGIONS); - postProcessStrategy.postProcess(configurableEnvironmentMock); + postProcessStrategy.configureParameterStorePropertySources(configurableEnvironmentMock); verify(mutablePropertySourcesMock).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); verifyParameterStorePropertySource(parameterStorePropertySourceArgumentCaptor.getValue(), diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactoryTest.java similarity index 75% rename from src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryTest.java rename to src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactoryTest.java index 8ec19ea..677bd8f 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactoryTest.java @@ -10,14 +10,14 @@ import org.junit.Before; import org.junit.Test; -public class ParameterStorePropertySourceEnvironmentPostProcessStrategyFactoryTest +public class ParameterStorePropertySourceConfigurationStrategyFactoryTest { - private ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory factory; + private ParameterStorePropertySourceConfigurationStrategyFactory factory; @Before public void setUp() { - factory = new ParameterStorePropertySourceEnvironmentPostProcessStrategyFactory(); + factory = new ParameterStorePropertySourceConfigurationStrategyFactory(); System.setProperty(ACCESS_KEY_ENV_VAR, "id"); System.setProperty(SECRET_KEY_ENV_VAR, "secret"); @@ -28,13 +28,13 @@ public void setUp() public void testGettingDefaultStrategy() { assertThat(factory.getStrategy(StrategyType.DEFAULT), - is(instanceOf(DefaultParameterStorePropertySourceEnvironmentPostProcessStrategy.class))); + is(instanceOf(DefaultParameterStorePropertySourceConfigurationStrategy.class))); } @Test public void testGettingMultiRegionStrategy() { assertThat(factory.getStrategy(StrategyType.MULTI_REGION), - is(instanceOf(MultiRegionParameterStorePropertySourceEnvironmentPostProcessStrategy.class))); + is(instanceOf(MultiRegionParameterStorePropertySourceConfigurationStrategy.class))); } } From 18a31b731a5d07a5ab05a80742dbfbe5ddf95012 Mon Sep 17 00:00:00 2001 From: Marie-Christine Noreau Date: Fri, 21 Feb 2020 09:14:22 -0500 Subject: [PATCH 7/7] * Update readme and rename variables --- readme.md | 2 +- ...ropertySourceEnvironmentPostProcessor.java | 8 +++---- ...rtySourceEnvironmentPostProcessorTest.java | 8 +++---- ...opertySourceConfigurationStrategyTest.java | 8 +++---- ...opertySourceConfigurationStrategyTest.java | 22 +++++++++++++------ 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/readme.md b/readme.md index 5befd4f..49bbe95 100644 --- a/readme.md +++ b/readme.md @@ -82,7 +82,7 @@ Spring Cloud has a second application context named bootstrap that gets initiali If you still want the post processor to run twice or if you are using [spring-boot-devtools](https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools-restart), you can set the optional property `awsParameterStorePropertySource.supportMultipleApplicationContexts` to `true`. The default property value is `false`to prevent multiple initializations. If you are also using Spring Cloud, this property will only work if set in the bootstrap properties. ## Multi-region support -- Set `awsParameterStoreSource.multiRegion.ssmClient.regions` with the regions from which you need to retrieve parameters using a **comma-separated** list such as `us-east-1,us-east-2`. It adds a PropertySource for each region specified. It will start looking from the first region and so on until it finds the property so put the regions in order of precedence. +- Set `awsParameterStoreSource.multiRegion.ssmClient.regions` with the regions from which you need to retrieve parameters using a **comma-separated** list such as `us-east-1,us-east-2`. It adds a `ParameterStorePropertySource` to the property sources for each region specified. It will start looking from the first region and so on until it finds the property so put the regions in order of precedence. **Reminder**: using other list injecting methods like a yaml list won't work because this property gets loaded too early in the boot process. - If you want to halt the boot when a property isn't found in any of the specified regions, just set `awsParameterStorePropertySource.haltBoot` to `true` in your properties. - Make sure that your service has the necessary permissions to access parameters in the specified regions. diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java index a376724..7bdfd5d 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java @@ -12,13 +12,13 @@ public class ParameterStorePropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor { static boolean initialized; - protected static ParameterStorePropertySourceConfigurationStrategyFactory postProcessStrategyFactory = new ParameterStorePropertySourceConfigurationStrategyFactory(); + static ParameterStorePropertySourceConfigurationStrategyFactory strategyFactory = new ParameterStorePropertySourceConfigurationStrategyFactory(); @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { if (!initialized && isParameterStorePropertySourceEnabled(environment)) { - getPostProcessStrategy(environment).configureParameterStorePropertySources(environment); + getParameterStorePropertySourceConfigurationStrategy(environment).configureParameterStorePropertySources(environment); if (doesNotSupportMultipleApplicationContexts(environment)) { initialized = true; @@ -26,10 +26,10 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringAp } } - private ParameterStorePropertySourceConfigurationStrategy getPostProcessStrategy(ConfigurableEnvironment environment) + private ParameterStorePropertySourceConfigurationStrategy getParameterStorePropertySourceConfigurationStrategy(ConfigurableEnvironment environment) { StrategyType type = isMultiRegionEnabled(environment) ? StrategyType.MULTI_REGION : StrategyType.DEFAULT; - return postProcessStrategyFactory.getStrategy(type); + return strategyFactory.getStrategy(type); } private boolean isParameterStorePropertySourceEnabled(ConfigurableEnvironment environment) diff --git a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java index b5a8875..9c25bf3 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java @@ -32,7 +32,7 @@ public class ParameterStorePropertySourceEnvironmentPostProcessorTest @Mock private SpringApplication applicationMock; @Mock - private ParameterStorePropertySourceConfigurationStrategyFactory postProcessStrategyFactoryMock; + private ParameterStorePropertySourceConfigurationStrategyFactory strategyFactoryMock; @Mock private ParameterStorePropertySourceConfigurationStrategy defaultPostProcessStrategyMock; @Mock @@ -45,9 +45,9 @@ public void setUp() { ParameterStorePropertySourceEnvironmentPostProcessor.initialized = false; - when(postProcessStrategyFactoryMock.getStrategy(StrategyType.DEFAULT)).thenReturn(defaultPostProcessStrategyMock); - when(postProcessStrategyFactoryMock.getStrategy(StrategyType.MULTI_REGION)).thenReturn(multiRegionPostProcessStrategyMock); - ParameterStorePropertySourceEnvironmentPostProcessor.postProcessStrategyFactory = postProcessStrategyFactoryMock; + when(strategyFactoryMock.getStrategy(StrategyType.DEFAULT)).thenReturn(defaultPostProcessStrategyMock); + when(strategyFactoryMock.getStrategy(StrategyType.MULTI_REGION)).thenReturn(multiRegionPostProcessStrategyMock); + ParameterStorePropertySourceEnvironmentPostProcessor.strategyFactory = strategyFactoryMock; when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategyTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategyTest.java index e243fbb..c2b6bd7 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategyTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategyTest.java @@ -27,7 +27,7 @@ public class DefaultParameterStorePropertySourceConfigurationStrategyTest @Mock private AwsRegionProviderChain awsRegionProviderChain; - private DefaultParameterStorePropertySourceConfigurationStrategy postProcessStrategy; + private DefaultParameterStorePropertySourceConfigurationStrategy strategy; @Before public void setUp() @@ -40,13 +40,13 @@ public void setUp() when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_SIGNING_REGION, awsRegionProviderChain.getRegion())).thenReturn("aRegion"); - postProcessStrategy = new DefaultParameterStorePropertySourceConfigurationStrategy(awsRegionProviderChain); + strategy = new DefaultParameterStorePropertySourceConfigurationStrategy(awsRegionProviderChain); } @Test public void testShouldAddPropertySource() { - postProcessStrategy.configureParameterStorePropertySources(configurableEnvironmentMock); + strategy.configureParameterStorePropertySources(configurableEnvironmentMock); verify(mutablePropertySourcesMock).addFirst(any(ParameterStorePropertySource.class)); } @@ -57,7 +57,7 @@ public void testWhenCustomEndpointShouldAddPropertySource() when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_CUSTOM_ENDPOINT)).thenReturn(Boolean.TRUE); when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_CUSTOM_ENDPOINT)).thenReturn("customEndpoint"); - postProcessStrategy.configureParameterStorePropertySources(configurableEnvironmentMock); + strategy.configureParameterStorePropertySources(configurableEnvironmentMock); verify(mutablePropertySourcesMock).addFirst(any(ParameterStorePropertySource.class)); } diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategyTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategyTest.java index 1a1e77b..ce8ef02 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategyTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategyTest.java @@ -28,6 +28,7 @@ public class MultiRegionParameterStorePropertySourceConfigurationStrategyTest { private static final String[] SIGNING_REGIONS = { "ownRegion", "mainRegion", "defaultRegion" }; private static final String[] SINGLE_SIGNING_REGIONS = { "ownRegion" }; + private static final String[] EMPTY_REGIONS = {}; @Mock private ConfigurableEnvironment configurableEnvironmentMock; @@ -37,7 +38,7 @@ public class MultiRegionParameterStorePropertySourceConfigurationStrategyTest @Captor private ArgumentCaptor parameterStorePropertySourceArgumentCaptor; - private MultiRegionParameterStorePropertySourceConfigurationStrategy postProcessStrategy; + private MultiRegionParameterStorePropertySourceConfigurationStrategy strategy; @Before public void setUp() @@ -49,18 +50,17 @@ public void setUp() when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS, String[].class)).thenReturn(SIGNING_REGIONS); - postProcessStrategy = new MultiRegionParameterStorePropertySourceConfigurationStrategy(); + strategy = new MultiRegionParameterStorePropertySourceConfigurationStrategy(); } @Test public void testShouldAddPropertySourceForEverySigningRegionsInOrderOfPrecedence() { - postProcessStrategy.configureParameterStorePropertySources(configurableEnvironmentMock); + strategy.configureParameterStorePropertySources(configurableEnvironmentMock); verify(mutablePropertySourcesMock, times(3)).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); List propertySources = parameterStorePropertySourceArgumentCaptor.getAllValues(); - verifyParameterStorePropertySource(propertySources.get(0), SIGNING_REGIONS[0], Boolean.FALSE); verifyParameterStorePropertySource(propertySources.get(1), SIGNING_REGIONS[1], Boolean.FALSE); verifyParameterStorePropertySource(propertySources.get(2), SIGNING_REGIONS[2], Boolean.FALSE); @@ -73,12 +73,11 @@ public void testHaltBootIsTrueThenOnlyLastRegionShouldHaltBoot() Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - postProcessStrategy.configureParameterStorePropertySources(configurableEnvironmentMock); + strategy.configureParameterStorePropertySources(configurableEnvironmentMock); verify(mutablePropertySourcesMock, times(3)).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); List propertySources = parameterStorePropertySourceArgumentCaptor.getAllValues(); - verifyParameterStorePropertySource(propertySources.get(0), SIGNING_REGIONS[0], Boolean.TRUE); verifyParameterStorePropertySource(propertySources.get(1), SIGNING_REGIONS[1], Boolean.FALSE); verifyParameterStorePropertySource(propertySources.get(2), SIGNING_REGIONS[2], Boolean.FALSE); @@ -93,7 +92,7 @@ public void testWithSingleRegion() when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS, String[].class)).thenReturn(SINGLE_SIGNING_REGIONS); - postProcessStrategy.configureParameterStorePropertySources(configurableEnvironmentMock); + strategy.configureParameterStorePropertySources(configurableEnvironmentMock); verify(mutablePropertySourcesMock).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); verifyParameterStorePropertySource(parameterStorePropertySourceArgumentCaptor.getValue(), @@ -101,6 +100,15 @@ public void testWithSingleRegion() Boolean.TRUE); } + @Test(expected = IllegalArgumentException.class) + public void testShouldThrowWhenRegionsIsEmpty() + { + when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS, + String[].class)).thenReturn(EMPTY_REGIONS); + + strategy.configureParameterStorePropertySources(configurableEnvironmentMock); + } + private void verifyParameterStorePropertySource(ParameterStorePropertySource actual, String region, Boolean haltBoot)