Skip to content

Commit b8a7432

Browse files
authored
Create new DefaultCredentialsProvider instance every time instead of … (#6080)
* Create new DefaultCredentialsProvider instance every time instead of using single instance * Add type assertion in test
1 parent f0a4011 commit b8a7432

File tree

5 files changed

+58
-7
lines changed

5 files changed

+58
-7
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "bugfix",
3+
"category": "AWS CRT-based S3 Client",
4+
"contributor": "",
5+
"description": "Fixed \"Connection pool shut down\" error thrown when a default AWS CRT-based S3 client is created and closed per request. See [#5881](https://github.com/aws/aws-sdk-java-v2/issues/5881)"
6+
}

services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClient.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import java.util.concurrent.Executor;
3636
import software.amazon.awssdk.annotations.SdkInternalApi;
3737
import software.amazon.awssdk.annotations.SdkTestInternalApi;
38+
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
39+
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
3840
import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
3941
import software.amazon.awssdk.awscore.AwsRequest;
4042
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
@@ -126,6 +128,10 @@ private static S3AsyncClient initializeS3AsyncClient(DefaultS3CrtClientBuilder b
126128
builder.executionInterceptors.forEach(overrideConfigurationBuilder::addExecutionInterceptor);
127129
}
128130

131+
if (builder.credentialsProvider == null) {
132+
builder = builder.credentialsProvider(DefaultCredentialsProvider.builder().build());
133+
}
134+
129135
DefaultS3CrtClientBuilder finalBuilder = resolveChecksumConfiguration(builder);
130136

131137
S3AsyncClientBuilder s3AsyncClientBuilder =
@@ -228,6 +234,13 @@ public static final class DefaultS3CrtClientBuilder implements S3CrtAsyncClientB
228234
private Executor futureCompletionExecutor;
229235
private Boolean disableS3ExpressSessionAuth;
230236

237+
238+
@Override
239+
public DefaultS3CrtClientBuilder credentialsProvider(AwsCredentialsProvider credentialsProvider) {
240+
this.credentialsProvider = credentialsProvider;
241+
return this;
242+
}
243+
231244
@Override
232245
public DefaultS3CrtClientBuilder credentialsProvider(
233246
IdentityProvider<? extends AwsCredentialsIdentity> credentialsProvider) {

services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/crt/S3NativeClientConfiguration.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.net.URI;
2222
import java.time.Duration;
2323
import software.amazon.awssdk.annotations.SdkInternalApi;
24-
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
2524
import software.amazon.awssdk.crt.auth.credentials.CredentialsProvider;
2625
import software.amazon.awssdk.crt.http.HttpMonitoringOptions;
2726
import software.amazon.awssdk.crt.http.HttpProxyOptions;
@@ -36,6 +35,7 @@
3635
import software.amazon.awssdk.services.s3.crt.S3CrtHttpConfiguration;
3736
import software.amazon.awssdk.utils.Logger;
3837
import software.amazon.awssdk.utils.SdkAutoCloseable;
38+
import software.amazon.awssdk.utils.Validate;
3939

4040
/**
4141
* Internal client configuration resolver
@@ -80,10 +80,8 @@ public S3NativeClientConfiguration(Builder builder) {
8080
clientTlsContextOptions.withVerifyPeer(!builder.httpConfiguration.trustAllCertificatesEnabled());
8181
}
8282
this.tlsContext = new TlsContext(clientTlsContextOptions);
83-
this.credentialProviderAdapter =
84-
builder.credentialsProvider == null ?
85-
new CrtCredentialsProviderAdapter(DefaultCredentialsProvider.create()) :
86-
new CrtCredentialsProviderAdapter(builder.credentialsProvider);
83+
this.credentialProviderAdapter = new CrtCredentialsProviderAdapter(
84+
Validate.paramNotNull(builder.credentialsProvider, "credentialsProvider"));
8785

8886
this.credentialsProvider = credentialProviderAdapter.crtCredentials();
8987

services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/crt/DefaultS3CrtAsyncClientTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@
2222
import org.junit.jupiter.api.Test;
2323
import org.junit.jupiter.params.ParameterizedTest;
2424
import org.junit.jupiter.params.provider.ValueSource;
25+
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
2526
import software.amazon.awssdk.auth.signer.AwsS3V4Signer;
2627
import software.amazon.awssdk.core.async.AsyncRequestBody;
2728
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
2829
import software.amazon.awssdk.core.interceptor.Context;
2930
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
3031
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
3132
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
33+
import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
34+
import software.amazon.awssdk.identity.spi.IdentityProvider;
3235
import software.amazon.awssdk.services.s3.DelegatingS3AsyncClient;
3336
import software.amazon.awssdk.services.s3.S3AsyncClient;
3437
import software.amazon.awssdk.services.s3.endpoints.S3ClientContextParams;
@@ -116,4 +119,25 @@ void crtClient_with_crossRegionAccessEnabled_asFalse() {
116119
}
117120
}
118121

122+
@Test
123+
void defaultClient_credentialsProvidersNotSingleton() {
124+
try (S3AsyncClient client = S3AsyncClient.crtBuilder().build();
125+
S3AsyncClient anotherClient = S3AsyncClient.crtBuilder().build()) {
126+
127+
IdentityProvider<? extends AwsCredentialsIdentity> identityProvider =
128+
client.serviceClientConfiguration().credentialsProvider();
129+
130+
IdentityProvider<? extends AwsCredentialsIdentity> identityProviderFromAnotherClient =
131+
anotherClient.serviceClientConfiguration().credentialsProvider();
132+
133+
assertThat(identityProvider)
134+
.isNotEqualTo(identityProviderFromAnotherClient);
135+
assertThat(identityProvider)
136+
.isInstanceOf(DefaultCredentialsProvider.class);
137+
assertThat(identityProvider)
138+
.isNotEqualTo(DefaultCredentialsProvider.create());
139+
assertThat(identityProviderFromAnotherClient)
140+
.isNotEqualTo(DefaultCredentialsProvider.create());
141+
}
142+
}
119143
}

services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/crt/S3CrtAsyncHttpClientTest.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ public void operationWithResponseAlgorithms_optOutValidationFromClient_shouldHon
287287

288288
s3NativeClientConfiguration = S3NativeClientConfiguration.builder()
289289
.endpointOverride(DEFAULT_ENDPOINT)
290-
.credentialsProvider(null)
290+
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test",
291+
"test")))
291292
.build();
292293

293294
asyncHttpClient = new S3CrtAsyncHttpClient(s3Client, S3CrtAsyncHttpClient.builder()
@@ -312,7 +313,8 @@ public void operationWithResponseAlgorithms_optInFromRequest_shouldHonor() {
312313

313314
s3NativeClientConfiguration = S3NativeClientConfiguration.builder()
314315
.endpointOverride(DEFAULT_ENDPOINT)
315-
.credentialsProvider(null)
316+
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test",
317+
"test")))
316318
.build();
317319

318320
asyncHttpClient = new S3CrtAsyncHttpClient(s3Client, S3CrtAsyncHttpClient.builder()
@@ -425,6 +427,8 @@ void build_shouldPassThroughParameters() {
425427
.signingRegion(signingRegion)
426428
.thresholdInBytes(1024L)
427429
.targetThroughputInGbps(3.5)
430+
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test",
431+
"test")))
428432
.maxNativeMemoryLimitInBytes(5L * 1024 * 1024 * 1024)
429433
.standardRetryOptions(
430434
new StandardRetryOptions()
@@ -466,6 +470,8 @@ void build_partSizeConfigured_shouldApplyToThreshold() {
466470
long partSizeInBytes = 1024 * 8L;
467471
S3NativeClientConfiguration configuration =
468472
S3NativeClientConfiguration.builder()
473+
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test",
474+
"test")))
469475
.partSizeInBytes(partSizeInBytes)
470476
.build();
471477
try (S3CrtAsyncHttpClient client =
@@ -480,6 +486,8 @@ void build_partSizeConfigured_shouldApplyToThreshold() {
480486
void build_nullHttpConfiguration() {
481487
S3NativeClientConfiguration configuration =
482488
S3NativeClientConfiguration.builder()
489+
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test",
490+
"test")))
483491
.build();
484492
try (S3CrtAsyncHttpClient client =
485493
(S3CrtAsyncHttpClient) S3CrtAsyncHttpClient.builder().s3ClientConfiguration(configuration).build()) {
@@ -539,6 +547,8 @@ void build_ProxyConfigurationWithEnvironmentVariables(S3CrtHttpConfiguration s3C
539547
S3NativeClientConfiguration configuration =
540548
S3NativeClientConfiguration.builder()
541549
.httpConfiguration(s3CrtHttpConfiguration)
550+
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test",
551+
"test")))
542552
.build();
543553
try(S3CrtAsyncHttpClient client =
544554
(S3CrtAsyncHttpClient) S3CrtAsyncHttpClient.builder().s3ClientConfiguration(configuration).build()) {

0 commit comments

Comments
 (0)