Skip to content

Commit aadbb1a

Browse files
Merge pull request #34 from folio-org/EDGAPIUTL-30-aws2
EDGAPIUTL-30: Sunflower 2025 R1 - Migrate AWS SDK from 1.x to 2.x
2 parents e99dca8 + b00b632 commit aadbb1a

5 files changed

Lines changed: 171 additions & 223 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ Only intended for _development purposes_. Credentials are defined in plain text
2121

2222
#### AwsParamStore ####
2323

24-
Retrieves credentials from Amazon Web Services Systems Manager (AWS SSM), more specifically the Parameter Store, where they're stored encrypted using a KMS key. `src.main/resources/aws_ss.properties`
24+
Retrieves credentials from Amazon Web Services Systems Manager (AWS SSM), more specifically the Parameter Store, where they're stored encrypted using a KMS key.
2525

2626
**Key:** `<salt>_<tenantId>_<username>`
2727

2828
e.g. Key=`ab73kbw90e_diku_diku`
2929

30+
You can set the HTTP endpoint to use for retrieving AWS credentials: Use the system property `ecsCredentialsEndpoint` (for example `http://example.com`). The path is taken from the `ecsCredentialsPath` system property, or from the `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` environment variable (standard on ECS containers). You also need to set the system properties `region` to the AWS region and `useIAM` to `false`.
31+
3032
#### VaultStore ####
3133

3234
Retrieves credentials from a Vault (https://vaultproject.io). This was added as a more generic alternative for those not using AWS. `src/main/resources/vault.properties`

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<java.version>21</java.version>
2121
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2222
<vault.version>6.2.0</vault.version>
23-
<aws-java-sdk.version>1.12.671</aws-java-sdk.version>
23+
<aws-java-sdk.version>2.30.31</aws-java-sdk.version>
2424
<versions-maven-plugin.version>2.18.0</versions-maven-plugin.version>
2525
<maven-enforcer-plugin.version>3.5.0</maven-enforcer-plugin.version>
2626
<maven-source-plugin.version>3.3.1</maven-source-plugin.version>
@@ -87,8 +87,8 @@
8787
</dependency>
8888
<!-- Only needed for AwsParamStore -->
8989
<dependency>
90-
<groupId>com.amazonaws</groupId>
91-
<artifactId>aws-java-sdk-ssm</artifactId>
90+
<groupId>software.amazon.awssdk</groupId>
91+
<artifactId>ssm</artifactId>
9292
<version>${aws-java-sdk.version}</version>
9393
</dependency>
9494
<dependency>
Lines changed: 69 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
package org.folio.edge.api.utils.security;
22

3-
import static org.folio.common.utils.tls.FipsChecker.ENABLED;
4-
import static org.folio.common.utils.tls.FipsChecker.getApprovedSecureRandomSafe;
5-
import static org.folio.common.utils.tls.FipsChecker.isInBouncycastleApprovedOnlyMode;
6-
7-
import com.amazonaws.ClientConfigurationFactory;
8-
import com.amazonaws.SdkClientException;
9-
import com.amazonaws.auth.AWSCredentialsProvider;
10-
import com.amazonaws.auth.ContainerCredentialsProvider;
11-
import com.amazonaws.auth.EnvironmentVariableCredentialsProvider;
12-
import com.amazonaws.auth.SystemPropertiesCredentialsProvider;
13-
import com.amazonaws.internal.CredentialsEndpointProvider;
14-
import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement;
15-
import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder;
16-
import com.amazonaws.services.simplesystemsmanagement.model.GetParameterRequest;
17-
import java.net.URI;
18-
import java.net.URISyntaxException;
19-
import java.util.Properties;
203
import org.apache.logging.log4j.LogManager;
214
import org.apache.logging.log4j.Logger;
5+
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
6+
import software.amazon.awssdk.auth.credentials.ContainerCredentialsProvider;
7+
import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
8+
import software.amazon.awssdk.auth.credentials.SystemPropertyCredentialsProvider;
9+
import software.amazon.awssdk.core.SdkSystemSetting;
10+
import software.amazon.awssdk.regions.Region;
11+
import software.amazon.awssdk.services.ssm.SsmClient;
12+
import software.amazon.awssdk.services.ssm.SsmClientBuilder;
13+
import software.amazon.awssdk.services.ssm.model.GetParameterRequest;
14+
import software.amazon.awssdk.services.ssm.model.ParameterNotFoundException;
15+
import java.util.Properties;
2216

2317
public class AwsParamStore extends SecureStore {
2418

@@ -30,15 +24,17 @@ public class AwsParamStore extends SecureStore {
3024
public static final String PROP_USE_IAM = "useIAM";
3125
public static final String PROP_ECS_CREDENTIALS_PATH = "ecsCredentialsPath";
3226
public static final String PROP_ECS_CREDENTIALS_ENDPOINT = "ecsCredentialsEndpoint";
27+
public static final String PROP_AWS_CONTAINER_CREDENTIALS_RELATIVE_URI =
28+
SdkSystemSetting.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI.property();
29+
public static final String ENV_AWS_CONTAINER_CREDENTIALS_RELATIVE_URI =
30+
SdkSystemSetting.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI.toString();
3331

3432
public static final String DEFAULT_USE_IAM = "true";
3533

3634
private String region;
3735
private boolean useIAM;
38-
private String ecsCredEndpoint;
39-
private String ecsCredPath;
4036

41-
protected AWSSimpleSystemsManagement ssm;
37+
protected SsmClient ssm;
4238

4339
public AwsParamStore(Properties properties) {
4440
super(properties);
@@ -47,100 +43,89 @@ public AwsParamStore(Properties properties) {
4743
if (properties != null) {
4844
region = properties.getProperty(PROP_REGION);
4945
useIAM = Boolean.parseBoolean(properties.getProperty(PROP_USE_IAM, DEFAULT_USE_IAM));
50-
ecsCredEndpoint = properties.getProperty(PROP_ECS_CREDENTIALS_ENDPOINT);
51-
ecsCredPath = properties.getProperty(PROP_ECS_CREDENTIALS_PATH);
5246
}
5347

54-
AWSSimpleSystemsManagementClientBuilder builder = AWSSimpleSystemsManagementClientBuilder.standard();
55-
56-
if (ENABLED.equals(isInBouncycastleApprovedOnlyMode())) {
57-
var clientConfigurationFactory = new ClientConfigurationFactory();
58-
var clientConfiguration = clientConfigurationFactory.getConfig();
59-
var secureRandom = getApprovedSecureRandomSafe();
60-
clientConfiguration.setSecureRandom(secureRandom);
61-
builder.setClientConfiguration(clientConfiguration);
62-
63-
logger.info("SecureRandom used for AwsParamStore: {}", secureRandom);
64-
}
48+
SsmClientBuilder builder = SsmClient.builder();
6549

6650
if (region != null) {
67-
builder.withRegion(region);
51+
builder.region(Region.of(region));
6852
}
6953

7054
if (useIAM) {
7155
logger.info("Using IAM");
7256
} else {
73-
AWSCredentialsProvider credProvider;
74-
try {
75-
credProvider = new EnvironmentVariableCredentialsProvider();
76-
credProvider.getCredentials();
77-
} catch (Exception e) {
78-
try {
79-
credProvider = new SystemPropertiesCredentialsProvider();
80-
credProvider.getCredentials();
81-
} catch (Exception e2) {
82-
credProvider = new ContainerCredentialsProvider(
83-
new ECSCredentialsEndpointProvider(ecsCredEndpoint, ecsCredPath));
84-
credProvider.getCredentials();
85-
}
86-
}
87-
logger.info("Using {}", credProvider.getClass().getName());
88-
builder.withCredentials(credProvider);
57+
var credProvider = getAwsCredentialsProvider();
58+
builder.credentialsProvider(credProvider);
8959
}
9060

9161
ssm = builder.build();
9262
}
9363

94-
@Override
95-
public String get(String clientId, String tenant, String username) throws NotFoundException {
96-
String key = String.format("%s_%s_%s", clientId, tenant, username);
97-
GetParameterRequest req = new GetParameterRequest()
98-
.withName(key)
99-
.withWithDecryption(true);
100-
64+
private AwsCredentialsProvider getAwsCredentialsProvider() {
10165
try {
102-
return ssm.getParameter(req).getParameter().getValue();
66+
logger.debug("Trying EnvironmentVariableCredentialsProvider");
67+
var credProvider = EnvironmentVariableCredentialsProvider.create();
68+
credProvider.resolveCredentials();
69+
logger.info("Using EnvironmentVariableCredentialsProvider");
70+
return credProvider;
10371
} catch (Exception e) {
104-
throw new NotFoundException(e);
72+
// ignore, try next
10573
}
74+
try {
75+
logger.debug("Trying SystemPropertyCredentialsProvider");
76+
var credProvider = SystemPropertyCredentialsProvider.create();
77+
credProvider.resolveCredentials();
78+
logger.info("Using SystemPropertyCredentialsProvider");
79+
return credProvider;
80+
} catch (Exception e) {
81+
// ignore, try next
82+
}
83+
logger.debug("Trying ContainerCredentialsProvider");
84+
var credProvider = ContainerCredentialsProvider.builder().endpoint(endpoint()).build();
85+
credProvider.resolveCredentials();
86+
logger.info("Using ContainerCredentialsProvider");
87+
return credProvider;
10688
}
10789

108-
protected static class ECSCredentialsEndpointProvider extends CredentialsEndpointProvider {
109-
public static final String ECS_CREDENTIALS_PATH_VAR = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
90+
private String endpoint() {
91+
if (properties == null) {
92+
return null;
93+
}
11094

111-
public final String ecsCredEndpoint;
112-
public final String ecsCredPath;
95+
var endpoint = properties.getProperty(PROP_ECS_CREDENTIALS_ENDPOINT);
96+
if (endpoint == null) {
97+
return null;
98+
}
11399

114-
public ECSCredentialsEndpointProvider(String ecsCredEndpoint, String ecsCredPath) {
115-
this.ecsCredEndpoint = ecsCredEndpoint;
116-
this.ecsCredPath = ecsCredPath;
100+
var path = properties.getProperty(PROP_ECS_CREDENTIALS_PATH);
101+
if (path != null) {
102+
System.setProperty(PROP_AWS_CONTAINER_CREDENTIALS_RELATIVE_URI, path);
117103
}
118104

119-
@Override
120-
public URI getCredentialsEndpoint() {
121-
String path = ecsCredPath;
122-
if (path == null) {
123-
path = System.getenv(ECS_CREDENTIALS_PATH_VAR);
124-
}
125-
if (path == null) {
126-
throw new SdkClientException(
127-
"No credentials path was provided and the environment variable " + ECS_CREDENTIALS_PATH_VAR + " is empty");
128-
}
129-
130-
try {
131-
return new URI(ecsCredEndpoint + path);
132-
} catch (URISyntaxException e) {
133-
throw new SdkClientException(e);
134-
}
105+
return endpoint;
106+
}
107+
108+
@Override
109+
public String get(String clientId, String tenant, String username) throws NotFoundException {
110+
String key = String.format("%s_%s_%s", clientId, tenant, username);
111+
GetParameterRequest req = GetParameterRequest.builder()
112+
.name(key)
113+
.withDecryption(true)
114+
.build();
115+
116+
try {
117+
return ssm.getParameter(req).parameter().value();
118+
} catch (ParameterNotFoundException e) {
119+
throw new NotFoundException(e);
135120
}
136121
}
137122

138123
public String getRegion() {
139124
return region;
140125
}
141126

142-
public Boolean getUseIAM() {
127+
public boolean getUseIAM() {
143128
return useIAM;
144129
}
145130

146-
}
131+
}

0 commit comments

Comments
 (0)