Skip to content

Commit

Permalink
Merge pull request #164 from coveooss/feature/aws-sdk-v2-migration
Browse files Browse the repository at this point in the history
  • Loading branch information
jebeaudet authored Aug 5, 2024
2 parents b478b52 + 728f288 commit 5f25d5b
Show file tree
Hide file tree
Showing 15 changed files with 315 additions and 253 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ target
*.classpath
*.project
*.xml.versionsBackup
.idea
58 changes: 42 additions & 16 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@

<groupId>com.coveo</groupId>
<artifactId>spring-boot-parameter-store-integration</artifactId>
<version>1.5.0</version>
<version>2.0.0</version>

<name>Spring Boot Parameter Store Integration</name>
<description>An integration of Amazon Web Services' Systems Manager Parameter Store for Spring Boot's properties injection.</description>
<url>https://github.com/coveo/spring-boot-parameter-store-integration</url>

<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jackson.version>2.17.1</jackson.version>
<spring-boot.version>3.3.1</spring-boot.version>
</properties>

<licenses>
Expand All @@ -26,47 +29,74 @@
<developer>
<name>Frederic Boutin</name>
<organization>Coveo</organization>
<organizationUrl>https://github.com/coveo</organizationUrl>
<organizationUrl>https://github.com/coveooss</organizationUrl>
</developer>
<developer>
<name>Jacques-Etienne Beaudet</name>
<organization>Coveo</organization>
<organizationUrl>https://github.com/coveooss</organizationUrl>
</developer>
</developers>

<scm>
<connection>scm:git:[email protected]:coveo/spring-boot-parameter-store-integration.git</connection>
<developerConnection>scm:git:[email protected]:coveo/spring-boot-parameter-store-integration.git</developerConnection>
<url>http://github.com/coveo/spring-boot-parameter-store-integration</url>
<connection>scm:git:[email protected]:coveooss/spring-boot-parameter-store-integration.git</connection>
<developerConnection>scm:git:[email protected]:coveooss/spring-boot-parameter-store-integration.git</developerConnection>
<url>http://github.com/coveooss/spring-boot-parameter-store-integration</url>
</scm>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.10.3</version>
<version>${jackson.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.26.15</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>1.5.22.RELEASE</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-ssm</artifactId>
<version>1.11.833</version>
<groupId>software.amazon.awssdk</groupId>
<artifactId>ssm</artifactId>
</dependency>

<!-- Test libraries -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>1.5.21.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.truth</groupId>
<artifactId>truth</artifactId>
<version>1.4.3</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>junit</artifactId>
<groupId>junit</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -106,10 +136,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
Expand All @@ -35,24 +40,24 @@ 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'.",
statusCode,
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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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();
Expand All @@ -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());
}
}
Loading

0 comments on commit 5f25d5b

Please sign in to comment.