Skip to content

Commit 9cf9894

Browse files
committed
EDGAPIUTL-30: Sunflower 2025 R1 - Migrate AWS SDK for Java from 1.x to 2.x
https://folio-org.atlassian.net/browse/EDGAPIUTL-30 See edge-common: folio-org/edge-common#118
1 parent 9226bf6 commit 9cf9894

5 files changed

Lines changed: 168 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.16.2</versions-maven-plugin.version>
2525
<maven-enforcer-plugin.version>3.4.1</maven-enforcer-plugin.version>
2626
<maven-source-plugin.version>3.3.0</maven-source-plugin.version>
@@ -88,8 +88,8 @@
8888
</dependency>
8989
<!-- Only needed for AwsParamStore -->
9090
<dependency>
91-
<groupId>com.amazonaws</groupId>
92-
<artifactId>aws-java-sdk-ssm</artifactId>
91+
<groupId>software.amazon.awssdk</groupId>
92+
<artifactId>ssm</artifactId>
9393
<version>${aws-java-sdk.version}</version>
9494
</dependency>
9595
<dependency>
Lines changed: 66 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,86 @@ 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+
var credProvider = EnvironmentVariableCredentialsProvider.create();
67+
credProvider.resolveCredentials();
68+
logger.info("Using EnvironmentVariableCredentialsProvider");
69+
return credProvider;
10370
} catch (Exception e) {
104-
throw new NotFoundException(e);
71+
// ignore, try next
10572
}
73+
try {
74+
var credProvider = SystemPropertyCredentialsProvider.create();
75+
credProvider.resolveCredentials();
76+
logger.info("Using SystemPropertyCredentialsProvider");
77+
return credProvider;
78+
} catch (Exception e) {
79+
// ignore, try next
80+
}
81+
logger.info("Using ContainerCredentialsProvider");
82+
var credProvider = ContainerCredentialsProvider.builder().endpoint(endpoint()).build();
83+
credProvider.resolveCredentials();
84+
return credProvider;
10685
}
10786

108-
protected static class ECSCredentialsEndpointProvider extends CredentialsEndpointProvider {
109-
public static final String ECS_CREDENTIALS_PATH_VAR = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
87+
private String endpoint() {
88+
if (properties == null) {
89+
return null;
90+
}
11091

111-
public final String ecsCredEndpoint;
112-
public final String ecsCredPath;
92+
var endpoint = properties.getProperty(PROP_ECS_CREDENTIALS_ENDPOINT);
93+
if (endpoint == null) {
94+
return null;
95+
}
11396

114-
public ECSCredentialsEndpointProvider(String ecsCredEndpoint, String ecsCredPath) {
115-
this.ecsCredEndpoint = ecsCredEndpoint;
116-
this.ecsCredPath = ecsCredPath;
97+
var path = properties.getProperty(PROP_ECS_CREDENTIALS_PATH);
98+
if (path != null) {
99+
System.setProperty(PROP_AWS_CONTAINER_CREDENTIALS_RELATIVE_URI, path);
117100
}
118101

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-
}
102+
return endpoint;
103+
}
104+
105+
@Override
106+
public String get(String clientId, String tenant, String username) throws NotFoundException {
107+
String key = String.format("%s_%s_%s", clientId, tenant, username);
108+
GetParameterRequest req = GetParameterRequest.builder()
109+
.name(key)
110+
.withDecryption(true)
111+
.build();
112+
113+
try {
114+
return ssm.getParameter(req).parameter().value();
115+
} catch (ParameterNotFoundException e) {
116+
throw new NotFoundException(e);
135117
}
136118
}
137119

138120
public String getRegion() {
139121
return region;
140122
}
141123

142-
public Boolean getUseIAM() {
124+
public boolean getUseIAM() {
143125
return useIAM;
144126
}
145127

146-
}
128+
}

0 commit comments

Comments
 (0)