From 728f288a816e8c7ccd7c0002d78ccb28fd8c5818 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Beaudet Date: Fri, 5 Jul 2024 18:43:43 -0400 Subject: [PATCH] AWS sdk v2 migration --- .gitignore | 1 + pom.xml | 58 +++++--- ...ropertySourceEnvironmentPostProcessor.java | 28 ++-- .../parameterstore/ParameterStoreSource.java | 39 ++--- ...rePropertySourceConfigurationStrategy.java | 29 ++-- ...rePropertySourceConfigurationStrategy.java | 21 +-- ...rePropertySourceConfigurationStrategy.java | 5 +- ...rtySourceConfigurationStrategyFactory.java | 6 +- .../parameterstore/strategy/StrategyType.java | 2 +- ...rtySourceEnvironmentPostProcessorTest.java | 134 +++++++++--------- .../ParameterStorePropertySourceTest.java | 23 ++- .../ParameterStoreSourceTest.java | 102 ++++++------- ...opertySourceConfigurationStrategyTest.java | 41 +++--- ...opertySourceConfigurationStrategyTest.java | 56 +++++--- ...ourceConfigurationStrategyFactoryTest.java | 23 +-- 15 files changed, 315 insertions(+), 253 deletions(-) diff --git a/.gitignore b/.gitignore index 3462f9b..b535ace 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ target *.classpath *.project *.xml.versionsBackup +.idea diff --git a/pom.xml b/pom.xml index ce5a355..113a290 100644 --- a/pom.xml +++ b/pom.xml @@ -5,14 +5,17 @@ com.coveo spring-boot-parameter-store-integration - 1.5.0 + 2.0.0 Spring Boot Parameter Store Integration An integration of Amazon Web Services' Systems Manager Parameter Store for Spring Boot's properties injection. https://github.com/coveo/spring-boot-parameter-store-integration + 17 UTF-8 + 2.17.1 + 3.3.1 @@ -26,14 +29,19 @@ Frederic Boutin Coveo - https://github.com/coveo + https://github.com/coveooss + + + Jacques-Etienne Beaudet + Coveo + https://github.com/coveooss - scm:git:git@github.com:coveo/spring-boot-parameter-store-integration.git - scm:git:git@github.com:coveo/spring-boot-parameter-store-integration.git - http://github.com/coveo/spring-boot-parameter-store-integration + scm:git:git@github.com:coveooss/spring-boot-parameter-store-integration.git + scm:git:git@github.com:coveooss/spring-boot-parameter-store-integration.git + http://github.com/coveooss/spring-boot-parameter-store-integration @@ -41,10 +49,24 @@ com.fasterxml.jackson jackson-bom - 2.10.3 + ${jackson.version} import pom + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + import + pom + + + software.amazon.awssdk + bom + 2.26.15 + pom + import + @@ -52,21 +74,29 @@ org.springframework.boot spring-boot - 1.5.22.RELEASE - com.amazonaws - aws-java-sdk-ssm - 1.11.833 + software.amazon.awssdk + ssm - org.springframework.boot spring-boot-starter-test - 1.5.21.RELEASE test + + com.google.truth + truth + 1.4.3 + test + + + junit + junit + + + @@ -106,10 +136,6 @@ org.apache.maven.plugins maven-compiler-plugin 3.7.0 - - 1.8 - 1.8 - diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java index 0ca517e..ba49cf5 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessor.java @@ -4,14 +4,17 @@ import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.Ordered; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Profiles; import org.springframework.util.ObjectUtils; -import com.amazonaws.ClientConfigurationFactory; -import com.amazonaws.retry.PredefinedRetryPolicies; -import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceConfigurationStrategy; import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceConfigurationStrategyFactory; import com.coveo.configuration.parameterstore.strategy.StrategyType; +import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; +import software.amazon.awssdk.core.internal.retry.SdkDefaultRetrySetting; +import software.amazon.awssdk.core.retry.RetryMode; +import software.amazon.awssdk.services.ssm.SsmClient; +import software.amazon.awssdk.services.ssm.SsmClientBuilder; public class ParameterStorePropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { @@ -26,13 +29,16 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringAp } } - private AWSSimpleSystemsManagementClientBuilder preconfigureSSMClientBuilder(ConfigurableEnvironment environment) + private SsmClientBuilder preconfigureSSMClientBuilder(ConfigurableEnvironment environment) { - return AWSSimpleSystemsManagementClientBuilder.standard() - .withClientConfiguration(new ClientConfigurationFactory().getConfig() - .withRetryPolicy(PredefinedRetryPolicies.getDefaultRetryPolicyWithCustomMaxRetries(environment.getProperty(ParameterStorePropertySourceConfigurationProperties.MAX_ERROR_RETRY, - Integer.class, - PredefinedRetryPolicies.DEFAULT_MAX_ERROR_RETRY)))); + Integer maxRetries = environment.getProperty(ParameterStorePropertySourceConfigurationProperties.MAX_ERROR_RETRY, + Integer.class, + SdkDefaultRetrySetting.maxAttempts(RetryMode.STANDARD)); + ClientOverrideConfiguration clientOverrideConfiguration = ClientOverrideConfiguration.builder() + .retryStrategy(configurator -> configurator.maxAttempts(maxRetries + + 1)) + .build(); + return SsmClient.builder().overrideConfiguration(clientOverrideConfiguration); } private ParameterStorePropertySourceConfigurationStrategy getParameterStorePropertySourceConfigurationStrategy(ConfigurableEnvironment environment) @@ -48,9 +54,9 @@ private boolean isParameterStorePropertySourceEnabled(ConfigurableEnvironment en return environment.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, Boolean.FALSE) - || environment.acceptsProfiles(ParameterStorePropertySourceConfigurationProperties.ENABLED_PROFILE) + || environment.acceptsProfiles(Profiles.of(ParameterStorePropertySourceConfigurationProperties.ENABLED_PROFILE)) || (!ObjectUtils.isEmpty(userDefinedEnabledProfiles) - && environment.acceptsProfiles(userDefinedEnabledProfiles)); + && environment.acceptsProfiles(Profiles.of(userDefinedEnabledProfiles))); } private boolean isMultiRegionEnabled(ConfigurableEnvironment environment) diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStoreSource.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStoreSource.java index e6809e4..1dfd343 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/ParameterStoreSource.java +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStoreSource.java @@ -1,31 +1,36 @@ package com.coveo.configuration.parameterstore; -import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement; -import com.amazonaws.services.simplesystemsmanagement.model.GetParameterRequest; -import com.amazonaws.services.simplesystemsmanagement.model.GetParameterResult; -import com.amazonaws.services.simplesystemsmanagement.model.ParameterNotFoundException; import com.coveo.configuration.parameterstore.exception.ParameterStoreError; import com.coveo.configuration.parameterstore.exception.ParameterStoreParameterNotFoundError; +import software.amazon.awssdk.services.ssm.SsmClient; +import software.amazon.awssdk.services.ssm.model.GetParameterRequest; +import software.amazon.awssdk.services.ssm.model.GetParameterResponse; +import software.amazon.awssdk.services.ssm.model.ParameterNotFoundException; +import software.amazon.awssdk.services.ssm.model.ParameterVersionNotFoundException; + +import java.util.Objects; public class ParameterStoreSource { - private AWSSimpleSystemsManagement ssmClient; - private boolean haltBoot; + private final SsmClient ssmClient; + private final boolean haltBoot; - public ParameterStoreSource(AWSSimpleSystemsManagement ssmClient, boolean haltBoot) + public ParameterStoreSource(SsmClient ssmClient, boolean haltBoot) { - this.ssmClient = ssmClient; + this.ssmClient = Objects.requireNonNull(ssmClient); this.haltBoot = haltBoot; } public Object getProperty(String propertyName) { try { - GetParameterResult getParameterResult = ssmClient.getParameter(new GetParameterRequest().withName(propertyName) - .withWithDecryption(true)); + GetParameterResponse getParameterResult = ssmClient.getParameter(GetParameterRequest.builder() + .name(propertyName) + .withDecryption(true) + .build()); validate(propertyName, getParameterResult); - return getParameterResult.getParameter().getValue(); - } catch (ParameterNotFoundException e) { + return getParameterResult.parameter().value(); + } catch (ParameterNotFoundException | ParameterVersionNotFoundException e) { if (haltBoot) { throw new ParameterStoreParameterNotFoundError(propertyName, e); } @@ -35,10 +40,10 @@ public Object getProperty(String propertyName) return null; } - private void validate(String propertyName, GetParameterResult getParameterResult) + private void validate(String propertyName, GetParameterResponse getParameterResponse) { - String requestId = getParameterResult.getSdkResponseMetadata().getRequestId(); - int statusCode = getParameterResult.getSdkHttpMetadata().getHttpStatusCode(); + String requestId = getParameterResponse.responseMetadata().requestId(); + int statusCode = getParameterResponse.sdkHttpResponse().statusCode(); if (statusCode != 200) { throw new ParameterStoreError(propertyName, String.format("Invalid response code '%s' received from AWS. AWS Request ID : '%s'.", @@ -46,13 +51,13 @@ private void validate(String propertyName, GetParameterResult getParameterResult requestId)); } - if (getParameterResult.getParameter() == null) { + if (getParameterResponse.parameter() == null) { throw new ParameterStoreError(propertyName, String.format("A null Parameter was received from AWS. AWS Request ID : '%s'.", requestId)); } - if (getParameterResult.getParameter().getValue() == null) { + if (getParameterResponse.parameter().value() == null) { throw new ParameterStoreError(propertyName, String.format("A null Parameter value was received from AWS. AWS Request ID : '%s'.", requestId)); diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategy.java index e1a7343..c26aafd 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategy.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategy.java @@ -2,29 +2,32 @@ 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.ParameterStorePropertySourceConfigurationProperties; import com.coveo.configuration.parameterstore.ParameterStoreSource; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.regions.providers.AwsRegionProviderChain; +import software.amazon.awssdk.services.ssm.SsmClient; +import software.amazon.awssdk.services.ssm.SsmClientBuilder; + +import java.net.URI; +import java.util.Objects; public class DefaultParameterStorePropertySourceConfigurationStrategy implements ParameterStorePropertySourceConfigurationStrategy { private static final String PARAMETER_STORE_PROPERTY_SOURCE_NAME = "AWSParameterStorePropertySource"; - private AwsRegionProviderChain awsRegionProviderChain; + private final AwsRegionProviderChain awsRegionProviderChain; public DefaultParameterStorePropertySourceConfigurationStrategy(AwsRegionProviderChain awsRegionProviderChain) { - this.awsRegionProviderChain = awsRegionProviderChain; + this.awsRegionProviderChain = Objects.requireNonNull(awsRegionProviderChain); } @Override public void configureParameterStorePropertySources(ConfigurableEnvironment environment, - AWSSimpleSystemsManagementClientBuilder ssmClientBuilder) + SsmClientBuilder ssmClientBuilder) { boolean haltBoot = environment.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, @@ -34,19 +37,17 @@ public void configureParameterStorePropertySources(ConfigurableEnvironment envir haltBoot)); } - private ParameterStorePropertySource buildParameterStorePropertySource(AWSSimpleSystemsManagement ssmClient, - boolean haltBoot) + private ParameterStorePropertySource buildParameterStorePropertySource(SsmClient ssmClient, boolean haltBoot) { return new ParameterStorePropertySource(PARAMETER_STORE_PROPERTY_SOURCE_NAME, new ParameterStoreSource(ssmClient, haltBoot)); } - private AWSSimpleSystemsManagement buildSSMClient(ConfigurableEnvironment environment, - AWSSimpleSystemsManagementClientBuilder ssmClientBuilder) + private SsmClient buildSSMClient(ConfigurableEnvironment environment, SsmClientBuilder ssmClientBuilder) { if (hasCustomEndpoint(environment)) { - return ssmClientBuilder.withEndpointConfiguration(new EndpointConfiguration(getCustomEndpoint(environment), - getSigningRegion(environment))) + return ssmClientBuilder.endpointOverride(URI.create(getCustomEndpoint(environment))) + .region(Region.of(getSigningRegion(environment))) .build(); } return ssmClientBuilder.build(); @@ -65,6 +66,6 @@ private String getCustomEndpoint(ConfigurableEnvironment environment) private String getSigningRegion(ConfigurableEnvironment environment) { return environment.getProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_SIGNING_REGION, - awsRegionProviderChain.getRegion()); + awsRegionProviderChain.getRegion().toString()); } } diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategy.java index 4d77124..a9545fc 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategy.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategy.java @@ -1,16 +1,19 @@ package com.coveo.configuration.parameterstore.strategy; +import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import org.springframework.core.env.ConfigurableEnvironment; 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.ParameterStorePropertySourceConfigurationProperties; import com.coveo.configuration.parameterstore.ParameterStoreSource; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.ssm.SsmClient; +import software.amazon.awssdk.services.ssm.SsmClientBuilder; public class MultiRegionParameterStorePropertySourceConfigurationStrategy implements ParameterStorePropertySourceConfigurationStrategy @@ -19,7 +22,7 @@ public class MultiRegionParameterStorePropertySourceConfigurationStrategy @Override public void configureParameterStorePropertySources(ConfigurableEnvironment environment, - AWSSimpleSystemsManagementClientBuilder ssmClientBuilder) + SsmClientBuilder ssmClientBuilder) { boolean haltBoot = environment.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, @@ -46,7 +49,7 @@ public void configureParameterStorePropertySources(ConfigurableEnvironment envir false))); } - private ParameterStorePropertySource buildParameterStorePropertySource(AWSSimpleSystemsManagementClientBuilder ssmClientBuilder, + private ParameterStorePropertySource buildParameterStorePropertySource(SsmClientBuilder ssmClientBuilder, String region, boolean haltBoot) { @@ -54,16 +57,16 @@ private ParameterStorePropertySource buildParameterStorePropertySource(AWSSimple + region, new ParameterStoreSource(buildSSMClient(ssmClientBuilder, region), haltBoot)); } - private AWSSimpleSystemsManagement buildSSMClient(AWSSimpleSystemsManagementClientBuilder ssmClientBuilder, - String region) + private SsmClient buildSSMClient(SsmClientBuilder ssmClientBuilder, String region) { - return ssmClientBuilder.withRegion(region).build(); + return ssmClientBuilder.region(Region.of(region)).build(); } private List getRegions(ConfigurableEnvironment environment) { - List regions = CollectionUtils.arrayToList(environment.getProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS, - String[].class)); + List regions = Arrays.asList(Optional.ofNullable(environment.getProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS, + String[].class)) + .orElseGet(() -> new String[0])); if (CollectionUtils.isEmpty(regions)) { throw new IllegalArgumentException(String.format("To enable multi region support, the property '%s' must not be empty.", diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategy.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategy.java index d757177..2953459 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategy.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategy.java @@ -2,10 +2,9 @@ import org.springframework.core.env.ConfigurableEnvironment; -import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; +import software.amazon.awssdk.services.ssm.SsmClientBuilder; public interface ParameterStorePropertySourceConfigurationStrategy { - void configureParameterStorePropertySources(ConfigurableEnvironment environment, - AWSSimpleSystemsManagementClientBuilder ssmClientBuilder); + void configureParameterStorePropertySources(ConfigurableEnvironment environment, SsmClientBuilder ssmClientBuilder); } diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactory.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactory.java index db851d1..8cc2044 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactory.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactory.java @@ -1,12 +1,12 @@ package com.coveo.configuration.parameterstore.strategy; -import java.util.EnumMap; +import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain; -import com.amazonaws.regions.DefaultAwsRegionProviderChain; +import java.util.EnumMap; public class ParameterStorePropertySourceConfigurationStrategyFactory { - private static EnumMap strategies = new EnumMap<>(StrategyType.class); + private static final EnumMap strategies = new EnumMap<>(StrategyType.class); static { strategies.put(StrategyType.DEFAULT, diff --git a/src/main/java/com/coveo/configuration/parameterstore/strategy/StrategyType.java b/src/main/java/com/coveo/configuration/parameterstore/strategy/StrategyType.java index e8787fd..240ebb0 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/strategy/StrategyType.java +++ b/src/main/java/com/coveo/configuration/parameterstore/strategy/StrategyType.java @@ -2,5 +2,5 @@ public enum StrategyType { - DEFAULT, MULTI_REGION; + 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 e576bc8..f28fb74 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceEnvironmentPostProcessorTest.java @@ -1,58 +1,52 @@ 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 org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -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; -import org.junit.runner.RunWith; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.boot.SpringApplication; import org.springframework.core.env.ConfigurableEnvironment; -import com.amazonaws.retry.PredefinedRetryPolicies; -import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceConfigurationStrategy; import com.coveo.configuration.parameterstore.strategy.ParameterStorePropertySourceConfigurationStrategyFactory; import com.coveo.configuration.parameterstore.strategy.StrategyType; +import org.springframework.core.env.Profiles; +import software.amazon.awssdk.retries.api.RetryStrategy; +import software.amazon.awssdk.services.ssm.SsmClientBuilder; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class ParameterStorePropertySourceEnvironmentPostProcessorTest { private static final int SPECIFIC_MAX_ERROR_RETRY = 10; private static final String[] EMPTY_CUSTOM_PROFILES = new String[] {}; private static final String[] CUSTOM_PROFILES = new String[] { "open", "source", "this" }; + private static final int MAX_RETRIES = 3; - @Mock + @Mock(strictness = Mock.Strictness.LENIENT) private ConfigurableEnvironment configurableEnvironmentMock; @Mock private SpringApplication applicationMock; - @Mock + @Mock(strictness = Mock.Strictness.LENIENT) private ParameterStorePropertySourceConfigurationStrategyFactory strategyFactoryMock; @Mock private ParameterStorePropertySourceConfigurationStrategy defaultPostProcessStrategyMock; @Mock private ParameterStorePropertySourceConfigurationStrategy multiRegionPostProcessStrategyMock; + @Mock + private RetryStrategy.Builder retryStrategyBuilderMock; @Captor - private ArgumentCaptor ssmClientBuilderCaptor; + private ArgumentCaptor ssmClientBuilderCaptor; private ParameterStorePropertySourceEnvironmentPostProcessor parameterStorePropertySourceEnvironmentPostProcessor = new ParameterStorePropertySourceEnvironmentPostProcessor(); - @Before + @BeforeEach public void setUp() { when(strategyFactoryMock.getStrategy(StrategyType.DEFAULT)).thenReturn(defaultPostProcessStrategyMock); @@ -62,13 +56,9 @@ public void setUp() when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.MAX_ERROR_RETRY, - Integer.class, - PredefinedRetryPolicies.DEFAULT_MAX_ERROR_RETRY)).thenReturn(PredefinedRetryPolicies.DEFAULT_MAX_ERROR_RETRY); - - System.setProperty(ACCESS_KEY_ENV_VAR, "id"); - System.setProperty(SECRET_KEY_ENV_VAR, "secret"); - System.setProperty(AWS_REGION_SYSTEM_PROPERTY, "region"); + when(configurableEnvironmentMock.getProperty(eq(ParameterStorePropertySourceConfigurationProperties.MAX_ERROR_RETRY), + eq(Integer.class), + any())).thenReturn(MAX_RETRIES); } @Test @@ -77,9 +67,9 @@ public void testParameterStoreIsDisabledByDefault() parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verifyZeroInteractions(applicationMock); - verifyZeroInteractions(defaultPostProcessStrategyMock); - verifyZeroInteractions(multiRegionPostProcessStrategyMock); + verifyNoInteractions(applicationMock); + verifyNoInteractions(defaultPostProcessStrategyMock); + verifyNoInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -94,23 +84,27 @@ public void testParameterStoreIsEnabledWithPropertySetToTrue() verify(defaultPostProcessStrategyMock).configureParameterStorePropertySources(eq(configurableEnvironmentMock), ssmClientBuilderCaptor.capture()); - assertThat(ssmClientBuilderCaptor.getValue().getClientConfiguration().getRetryPolicy().getMaxErrorRetry(), - is(PredefinedRetryPolicies.DEFAULT_MAX_ERROR_RETRY)); - - verifyZeroInteractions(multiRegionPostProcessStrategyMock); + ssmClientBuilderCaptor.getValue() + .overrideConfiguration() + .retryStrategyConfigurator() + .orElseThrow() + .accept(retryStrategyBuilderMock); + verify(retryStrategyBuilderMock).maxAttempts(MAX_RETRIES + 1); + + verifyNoInteractions(multiRegionPostProcessStrategyMock); } @Test public void testParameterStoreIsEnabledWithProfile() { - when(configurableEnvironmentMock.acceptsProfiles(ParameterStorePropertySourceConfigurationProperties.ENABLED_PROFILE)).thenReturn(true); + when(configurableEnvironmentMock.acceptsProfiles(Profiles.of(ParameterStorePropertySourceConfigurationProperties.ENABLED_PROFILE))).thenReturn(true); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); verify(defaultPostProcessStrategyMock).configureParameterStorePropertySources(eq(configurableEnvironmentMock), - any(AWSSimpleSystemsManagementClientBuilder.class)); - verifyZeroInteractions(multiRegionPostProcessStrategyMock); + any(SsmClientBuilder.class)); + verifyNoInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -118,14 +112,14 @@ public void testParameterStoreIsEnabledWithCustomProfiles() { when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ACCEPTED_PROFILES, String[].class)).thenReturn(CUSTOM_PROFILES); - when(configurableEnvironmentMock.acceptsProfiles(CUSTOM_PROFILES)).thenReturn(true); + when(configurableEnvironmentMock.acceptsProfiles(Profiles.of(CUSTOM_PROFILES))).thenReturn(true); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); verify(defaultPostProcessStrategyMock).configureParameterStorePropertySources(eq(configurableEnvironmentMock), - any(AWSSimpleSystemsManagementClientBuilder.class)); - verifyZeroInteractions(multiRegionPostProcessStrategyMock); + any(SsmClientBuilder.class)); + verifyNoInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -138,8 +132,8 @@ public void testParameterStoreIsNotEnabledWithCustomProfilesEmpty() applicationMock); verify(configurableEnvironmentMock, never()).acceptsProfiles(EMPTY_CUSTOM_PROFILES); - verifyZeroInteractions(defaultPostProcessStrategyMock); - verifyZeroInteractions(multiRegionPostProcessStrategyMock); + verifyNoInteractions(defaultPostProcessStrategyMock); + verifyNoInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -152,8 +146,8 @@ public void testParameterStoreIsNotEnabledWithCustomProfilesButNoneOfTheProfiles parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); - verifyZeroInteractions(defaultPostProcessStrategyMock); - verifyZeroInteractions(multiRegionPostProcessStrategyMock); + verifyNoInteractions(defaultPostProcessStrategyMock); + verifyNoInteractions(multiRegionPostProcessStrategyMock); } @Test @@ -170,10 +164,14 @@ public void testWhenMultiRegionIsEnabled() verify(multiRegionPostProcessStrategyMock, times(1)).configureParameterStorePropertySources(eq(configurableEnvironmentMock), ssmClientBuilderCaptor.capture()); - assertThat(ssmClientBuilderCaptor.getValue().getClientConfiguration().getRetryPolicy().getMaxErrorRetry(), - is(PredefinedRetryPolicies.DEFAULT_MAX_ERROR_RETRY)); - - verifyZeroInteractions(defaultPostProcessStrategyMock); + ssmClientBuilderCaptor.getValue() + .overrideConfiguration() + .retryStrategyConfigurator() + .orElseThrow() + .accept(retryStrategyBuilderMock); + verify(retryStrategyBuilderMock).maxAttempts(MAX_RETRIES + 1); + + verifyNoInteractions(defaultPostProcessStrategyMock); } @Test @@ -182,17 +180,21 @@ public void testWhenMaxRetryErrorIsSpecified() when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.MAX_ERROR_RETRY, - Integer.class, - PredefinedRetryPolicies.DEFAULT_MAX_ERROR_RETRY)).thenReturn(SPECIFIC_MAX_ERROR_RETRY); + when(configurableEnvironmentMock.getProperty(eq(ParameterStorePropertySourceConfigurationProperties.MAX_ERROR_RETRY), + eq(Integer.class), + any())).thenReturn(SPECIFIC_MAX_ERROR_RETRY); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, applicationMock); verify(defaultPostProcessStrategyMock).configureParameterStorePropertySources(eq(configurableEnvironmentMock), ssmClientBuilderCaptor.capture()); - assertThat(ssmClientBuilderCaptor.getValue().getClientConfiguration().getRetryPolicy().getMaxErrorRetry(), - is(SPECIFIC_MAX_ERROR_RETRY)); + ssmClientBuilderCaptor.getValue() + .overrideConfiguration() + .retryStrategyConfigurator() + .orElseThrow() + .accept(retryStrategyBuilderMock); + verify(retryStrategyBuilderMock).maxAttempts(SPECIFIC_MAX_ERROR_RETRY + 1); } @Test @@ -201,9 +203,9 @@ public void testWhenMaxRetryErrorIsSpecifiedAndMultiRegionIsEnabled() when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.ENABLED, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.MAX_ERROR_RETRY, - Integer.class, - PredefinedRetryPolicies.DEFAULT_MAX_ERROR_RETRY)).thenReturn(SPECIFIC_MAX_ERROR_RETRY); + when(configurableEnvironmentMock.getProperty(eq(ParameterStorePropertySourceConfigurationProperties.MAX_ERROR_RETRY), + eq(Integer.class), + any())).thenReturn(SPECIFIC_MAX_ERROR_RETRY); when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS)).thenReturn(Boolean.TRUE); parameterStorePropertySourceEnvironmentPostProcessor.postProcessEnvironment(configurableEnvironmentMock, @@ -212,9 +214,13 @@ public void testWhenMaxRetryErrorIsSpecifiedAndMultiRegionIsEnabled() verify(multiRegionPostProcessStrategyMock, times(1)).configureParameterStorePropertySources(eq(configurableEnvironmentMock), ssmClientBuilderCaptor.capture()); - assertThat(ssmClientBuilderCaptor.getValue().getClientConfiguration().getRetryPolicy().getMaxErrorRetry(), - is(SPECIFIC_MAX_ERROR_RETRY)); - - verifyZeroInteractions(defaultPostProcessStrategyMock); + ssmClientBuilderCaptor.getValue() + .overrideConfiguration() + .retryStrategyConfigurator() + .orElseThrow() + .accept(retryStrategyBuilderMock); + verify(retryStrategyBuilderMock).maxAttempts(SPECIFIC_MAX_ERROR_RETRY + 1); + + verifyNoInteractions(defaultPostProcessStrategyMock); } } diff --git a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceTest.java b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceTest.java index 54ec15a..6203d17 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/ParameterStorePropertySourceTest.java @@ -1,17 +1,15 @@ package com.coveo.configuration.parameterstore; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; -import static org.mockito.Matchers.any; +import static com.google.common.truth.Truth.*; import static org.mockito.Mockito.*; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class ParameterStorePropertySourceTest { private static final String VALID_PROPERTY_NAME = "/validproperty"; @@ -22,11 +20,10 @@ public class ParameterStorePropertySourceTest private ParameterStorePropertySource parameterStorePropertySource; - @Before + @BeforeEach public void setUp() { parameterStorePropertySource = new ParameterStorePropertySource("someuselessname", parameterStoreSourceMock); - when(parameterStoreSourceMock.getProperty(VALID_PROPERTY_NAME)).thenReturn(VALID_VALUE); } @Test @@ -34,16 +31,18 @@ public void testGetPropertyReturnsNullWithoutPingingParameterStoreIfPrefixIsNotP { Object value = parameterStorePropertySource.getProperty("somepropswithoutslashbefore"); - assertThat(value, is(nullValue())); + assertThat(value).isNull(); verify(parameterStoreSourceMock, never()).getProperty(any()); } @Test public void testGetProperty() { + when(parameterStoreSourceMock.getProperty(VALID_PROPERTY_NAME)).thenReturn(VALID_VALUE); + Object value = parameterStorePropertySource.getProperty(VALID_PROPERTY_NAME); - assertThat(value, is(VALID_VALUE)); + assertThat(value).isEqualTo(VALID_VALUE); verify(parameterStoreSourceMock).getProperty(VALID_PROPERTY_NAME); } } diff --git a/src/test/java/com/coveo/configuration/parameterstore/ParameterStoreSourceTest.java b/src/test/java/com/coveo/configuration/parameterstore/ParameterStoreSourceTest.java index 745c242..33b590c 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/ParameterStoreSourceTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/ParameterStoreSourceTest.java @@ -1,26 +1,24 @@ package com.coveo.configuration.parameterstore; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.*; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import com.amazonaws.ResponseMetadata; -import com.amazonaws.http.SdkHttpMetadata; -import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement; -import com.amazonaws.services.simplesystemsmanagement.model.GetParameterRequest; -import com.amazonaws.services.simplesystemsmanagement.model.GetParameterResult; -import com.amazonaws.services.simplesystemsmanagement.model.Parameter; -import com.amazonaws.services.simplesystemsmanagement.model.ParameterNotFoundException; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; + import com.coveo.configuration.parameterstore.exception.ParameterStoreError; import com.coveo.configuration.parameterstore.exception.ParameterStoreParameterNotFoundError; +import software.amazon.awssdk.awscore.AwsResponseMetadata; +import software.amazon.awssdk.http.SdkHttpResponse; +import software.amazon.awssdk.services.ssm.SsmClient; +import software.amazon.awssdk.services.ssm.model.*; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class ParameterStoreSourceTest { private static final String VALID_PROPERTY_NAME = "awesomeproperty"; @@ -29,97 +27,105 @@ public class ParameterStoreSourceTest private static final String INVALID_PROPERTY_NAME = "notawesomeproperty"; @Mock - private AWSSimpleSystemsManagement ssmClientMock; - @Mock - private SdkHttpMetadata sdkHttpMetadataMock; + private SsmClient ssmClientMock; @Mock - private ResponseMetadata responseMetadataMock; + private SdkHttpResponse sdkHttpMetadataMock; + @Spy + private AwsResponseMetadata responseMetadataSpy = SsmResponseMetadata.create(null); private ParameterStoreSource parameterStoreSource; - @Before + @BeforeEach public void setUp() { - when(sdkHttpMetadataMock.getHttpStatusCode()).thenReturn(200); - parameterStoreSource = new ParameterStoreSource(ssmClientMock, false); } @Test public void testGetProperty() { - when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResult().withParameter(new Parameter().withValue(VALID_PROPERTY_VALUE))); + when(sdkHttpMetadataMock.statusCode()).thenReturn(200); + when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResponse().toBuilder() + .parameter(Parameter.builder() + .value(VALID_PROPERTY_VALUE) + .build()) + .build()); Object value = parameterStoreSource.getProperty(VALID_PROPERTY_NAME); - assertThat(value, is(VALID_PROPERTY_VALUE)); + assertThat(value).isEqualTo(VALID_PROPERTY_VALUE); } @Test public void testGetPropertyWhenNotFoundReturnsNull() { - when(ssmClientMock.getParameter(getParameterRequest(INVALID_PROPERTY_NAME))).thenThrow(new ParameterNotFoundException("")); + when(ssmClientMock.getParameter(getParameterRequest(INVALID_PROPERTY_NAME))).thenThrow(ParameterNotFoundException.builder() + .build()); Object value = parameterStoreSource.getProperty(INVALID_PROPERTY_NAME); - assertThat(value, is(nullValue())); + assertThat(value).isNull(); } - @Test(expected = ParameterStoreError.class) + @Test public void shouldThrowOnUnexpectedExceptionAccessingParameterStore() { when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenThrow(new RuntimeException()); - parameterStoreSource.getProperty(VALID_PROPERTY_NAME); + assertThrows(ParameterStoreError.class, () -> parameterStoreSource.getProperty(VALID_PROPERTY_NAME)); } - @Test(expected = ParameterStoreParameterNotFoundError.class) + @Test public void shouldThrowOnGetPropertyWhenNotFoundAndHaltBootIsTrue() { - when(ssmClientMock.getParameter(getParameterRequest(INVALID_PROPERTY_NAME))).thenThrow(new ParameterNotFoundException("")); + when(ssmClientMock.getParameter(getParameterRequest(INVALID_PROPERTY_NAME))).thenThrow(ParameterNotFoundException.builder() + .build()); ParameterStoreSource parameterStoreSourceHaltingBoot = new ParameterStoreSource(ssmClientMock, true); - parameterStoreSourceHaltingBoot.getProperty(INVALID_PROPERTY_NAME); + assertThrows(ParameterStoreParameterNotFoundError.class, + () -> parameterStoreSourceHaltingBoot.getProperty(INVALID_PROPERTY_NAME)); } - @Test(expected = ParameterStoreError.class) + @Test public void shouldThrowWhenStatusCodeIsNot200() { - when(sdkHttpMetadataMock.getHttpStatusCode()).thenReturn(503); - when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResult()); + when(sdkHttpMetadataMock.statusCode()).thenReturn(503); + when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResponse()); ParameterStoreSource parameterStoreSourceHaltingBoot = new ParameterStoreSource(ssmClientMock, true); - parameterStoreSourceHaltingBoot.getProperty(VALID_PROPERTY_NAME); + assertThrows(ParameterStoreError.class, () -> parameterStoreSourceHaltingBoot.getProperty(VALID_PROPERTY_NAME)); } - @Test(expected = ParameterStoreError.class) + @Test public void shouldThrowWhenParameterIsNull() { - when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResult()); + when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResponse()); ParameterStoreSource parameterStoreSourceHaltingBoot = new ParameterStoreSource(ssmClientMock, true); - parameterStoreSourceHaltingBoot.getProperty(VALID_PROPERTY_NAME); + assertThrows(ParameterStoreError.class, () -> parameterStoreSourceHaltingBoot.getProperty(VALID_PROPERTY_NAME)); } - @Test(expected = ParameterStoreError.class) + @Test public void shouldThrowWhenParameterValueIsNull() { - when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResult().withParameter(new Parameter())); + when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResponse().toBuilder() + .parameter((Parameter.builder() + .build())) + .build()); ParameterStoreSource parameterStoreSourceHaltingBoot = new ParameterStoreSource(ssmClientMock, true); - - parameterStoreSourceHaltingBoot.getProperty(VALID_PROPERTY_NAME); + assertThrows(ParameterStoreError.class, () -> parameterStoreSourceHaltingBoot.getProperty(VALID_PROPERTY_NAME)); } - private GetParameterResult getGetParameterResult() + private GetParameterResponse getGetParameterResponse() { - GetParameterResult getParameterResult = new GetParameterResult(); - getParameterResult.setSdkHttpMetadata(sdkHttpMetadataMock); - getParameterResult.setSdkResponseMetadata(responseMetadataMock); - return getParameterResult; + return (GetParameterResponse) GetParameterResponse.builder() + .responseMetadata(responseMetadataSpy) + .sdkHttpResponse(sdkHttpMetadataMock) + .build(); } private GetParameterRequest getParameterRequest(String parameterName) { - return new GetParameterRequest().withName(parameterName).withWithDecryption(true); + return GetParameterRequest.builder().name(parameterName).withDecryption(true).build(); } } 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 19d8aeb..249e85e 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategyTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/DefaultParameterStorePropertySourceConfigurationStrategyTest.java @@ -1,44 +1,50 @@ package com.coveo.configuration.parameterstore.strategy; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; 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.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MutablePropertySources; -import com.amazonaws.regions.AwsRegionProviderChain; -import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; import com.coveo.configuration.parameterstore.ParameterStorePropertySource; import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperties; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.regions.providers.AwsRegionProviderChain; +import software.amazon.awssdk.services.ssm.SsmClient; +import software.amazon.awssdk.services.ssm.SsmClientBuilder; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class DefaultParameterStorePropertySourceConfigurationStrategyTest { + private static final Region PROVIDER_CHAIN_REGION = Region.US_EAST_1; @Mock private ConfigurableEnvironment configurableEnvironmentMock; @Mock private MutablePropertySources mutablePropertySourcesMock; @Mock private AwsRegionProviderChain awsRegionProviderChain; + @Mock + private SsmClientBuilder ssmClientBuilderMock; + @Mock + private SsmClient ssmClientMock; private DefaultParameterStorePropertySourceConfigurationStrategy strategy; - @Before + @BeforeEach public void setUp() { + when(ssmClientBuilderMock.build()).thenReturn(ssmClientMock); when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); - when(awsRegionProviderChain.getRegion()).thenReturn("aRegion"); - when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_SIGNING_REGION, - awsRegionProviderChain.getRegion())).thenReturn("aRegion"); strategy = new DefaultParameterStorePropertySourceConfigurationStrategy(awsRegionProviderChain); } @@ -46,8 +52,7 @@ public void setUp() @Test public void testShouldAddPropertySource() { - strategy.configureParameterStorePropertySources(configurableEnvironmentMock, - AWSSimpleSystemsManagementClientBuilder.standard()); + strategy.configureParameterStorePropertySources(configurableEnvironmentMock, ssmClientBuilderMock); verify(mutablePropertySourcesMock).addFirst(any(ParameterStorePropertySource.class)); } @@ -55,11 +60,15 @@ public void testShouldAddPropertySource() @Test public void testWhenCustomEndpointShouldAddPropertySource() { + when(ssmClientBuilderMock.endpointOverride(any())).thenReturn(ssmClientBuilderMock); + when(ssmClientBuilderMock.region(any())).thenReturn(ssmClientBuilderMock); + when(awsRegionProviderChain.getRegion()).thenReturn(PROVIDER_CHAIN_REGION); + when(configurableEnvironmentMock.getProperty(eq(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_SIGNING_REGION), + any(String.class))).thenReturn(PROVIDER_CHAIN_REGION.toString()); when(configurableEnvironmentMock.containsProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_CUSTOM_ENDPOINT)).thenReturn(Boolean.TRUE); when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.SSM_CLIENT_CUSTOM_ENDPOINT)).thenReturn("customEndpoint"); - strategy.configureParameterStorePropertySources(configurableEnvironmentMock, - AWSSimpleSystemsManagementClientBuilder.standard()); + strategy.configureParameterStorePropertySources(configurableEnvironmentMock, ssmClientBuilderMock); 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 817bf18..5622458 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategyTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/MultiRegionParameterStorePropertySourceConfigurationStrategyTest.java @@ -1,30 +1,31 @@ package com.coveo.configuration.parameterstore.strategy; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.StringEndsWith.endsWith; -import static org.junit.Assert.assertThat; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; 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.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MutablePropertySources; import org.springframework.test.util.ReflectionTestUtils; -import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder; import com.coveo.configuration.parameterstore.ParameterStorePropertySource; import com.coveo.configuration.parameterstore.ParameterStorePropertySourceConfigurationProperties; +import software.amazon.awssdk.services.ssm.SsmClient; +import software.amazon.awssdk.services.ssm.SsmClientBuilder; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class MultiRegionParameterStorePropertySourceConfigurationStrategyTest { private static final String[] SIGNING_REGIONS = { "ownRegion", "mainRegion", "defaultRegion" }; @@ -35,16 +36,19 @@ public class MultiRegionParameterStorePropertySourceConfigurationStrategyTest private ConfigurableEnvironment configurableEnvironmentMock; @Mock private MutablePropertySources mutablePropertySourcesMock; + @Mock + private SsmClientBuilder ssmClientBuilderMock; + @Mock + private SsmClient ssmClientMock; @Captor private ArgumentCaptor parameterStorePropertySourceArgumentCaptor; private MultiRegionParameterStorePropertySourceConfigurationStrategy strategy; - @Before + @BeforeEach public void setUp() { - when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.FALSE); @@ -57,8 +61,11 @@ public void setUp() @Test public void testShouldAddPropertySourceForEverySigningRegionsInOrderOfPrecedence() { - strategy.configureParameterStorePropertySources(configurableEnvironmentMock, - AWSSimpleSystemsManagementClientBuilder.standard()); + when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); + when(ssmClientBuilderMock.region(any())).thenReturn(ssmClientBuilderMock); + when(ssmClientBuilderMock.build()).thenReturn(ssmClientMock); + + strategy.configureParameterStorePropertySources(configurableEnvironmentMock, ssmClientBuilderMock); verify(mutablePropertySourcesMock, times(3)).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); @@ -71,12 +78,14 @@ public void testShouldAddPropertySourceForEverySigningRegionsInOrderOfPrecedence @Test public void testHaltBootIsTrueThenOnlyLastRegionShouldHaltBoot() { + when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); + when(ssmClientBuilderMock.region(any())).thenReturn(ssmClientBuilderMock); + when(ssmClientBuilderMock.build()).thenReturn(ssmClientMock); when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); - strategy.configureParameterStorePropertySources(configurableEnvironmentMock, - AWSSimpleSystemsManagementClientBuilder.standard()); + strategy.configureParameterStorePropertySources(configurableEnvironmentMock, ssmClientBuilderMock); verify(mutablePropertySourcesMock, times(3)).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); @@ -89,14 +98,16 @@ public void testHaltBootIsTrueThenOnlyLastRegionShouldHaltBoot() @Test public void testWithSingleRegion() { + when(configurableEnvironmentMock.getPropertySources()).thenReturn(mutablePropertySourcesMock); + when(ssmClientBuilderMock.region(any())).thenReturn(ssmClientBuilderMock); + when(ssmClientBuilderMock.build()).thenReturn(ssmClientMock); when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.HALT_BOOT, Boolean.class, Boolean.FALSE)).thenReturn(Boolean.TRUE); when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS, String[].class)).thenReturn(SINGLE_SIGNING_REGIONS); - strategy.configureParameterStorePropertySources(configurableEnvironmentMock, - AWSSimpleSystemsManagementClientBuilder.standard()); + strategy.configureParameterStorePropertySources(configurableEnvironmentMock, ssmClientBuilderMock); verify(mutablePropertySourcesMock).addFirst(parameterStorePropertySourceArgumentCaptor.capture()); verifyParameterStorePropertySource(parameterStorePropertySourceArgumentCaptor.getValue(), @@ -104,21 +115,22 @@ public void testWithSingleRegion() Boolean.TRUE); } - @Test(expected = IllegalArgumentException.class) + @Test public void testShouldThrowWhenRegionsIsEmpty() { when(configurableEnvironmentMock.getProperty(ParameterStorePropertySourceConfigurationProperties.MULTI_REGION_SSM_CLIENT_REGIONS, String[].class)).thenReturn(EMPTY_REGIONS); - strategy.configureParameterStorePropertySources(configurableEnvironmentMock, - AWSSimpleSystemsManagementClientBuilder.standard()); + assertThrows(IllegalArgumentException.class, + () -> strategy.configureParameterStorePropertySources(configurableEnvironmentMock, + ssmClientBuilderMock)); } private void verifyParameterStorePropertySource(ParameterStorePropertySource actual, String region, Boolean haltBoot) { - assertThat(actual.getName(), endsWith("_" + region)); - assertThat(ReflectionTestUtils.getField(actual.getSource(), "haltBoot"), is(haltBoot)); + assertThat(actual.getName()).endsWith("_" + region); + assertThat(ReflectionTestUtils.getField(actual.getSource(), "haltBoot")).isEqualTo(haltBoot); } } diff --git a/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactoryTest.java b/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactoryTest.java index 677bd8f..1d44ec0 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactoryTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/strategy/ParameterStorePropertySourceConfigurationStrategyFactoryTest.java @@ -1,40 +1,29 @@ 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 org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; +import static com.google.common.truth.Truth.assertThat; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class ParameterStorePropertySourceConfigurationStrategyFactoryTest { private ParameterStorePropertySourceConfigurationStrategyFactory factory; - @Before + @BeforeEach public void setUp() { factory = new ParameterStorePropertySourceConfigurationStrategyFactory(); - - 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() { - assertThat(factory.getStrategy(StrategyType.DEFAULT), - is(instanceOf(DefaultParameterStorePropertySourceConfigurationStrategy.class))); + assertThat(factory.getStrategy(StrategyType.DEFAULT)).isInstanceOf(DefaultParameterStorePropertySourceConfigurationStrategy.class); } @Test public void testGettingMultiRegionStrategy() { - assertThat(factory.getStrategy(StrategyType.MULTI_REGION), - is(instanceOf(MultiRegionParameterStorePropertySourceConfigurationStrategy.class))); + assertThat(factory.getStrategy(StrategyType.MULTI_REGION)).isInstanceOf(MultiRegionParameterStorePropertySourceConfigurationStrategy.class); } }