Skip to content

Commit 602fd9a

Browse files
committed
Added wrapper class for CRT retry config
1 parent 708a2cb commit 602fd9a

File tree

3 files changed

+162
-5
lines changed

3 files changed

+162
-5
lines changed

services/s3/src/main/java/software/amazon/awssdk/services/s3/S3CrtAsyncClientBuilder.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
2323
import software.amazon.awssdk.regions.Region;
2424
import software.amazon.awssdk.services.s3.crt.S3CrtHttpConfiguration;
25+
import software.amazon.awssdk.services.s3.crt.S3CrtRetryConfiguration;
2526
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
2627
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
2728
import software.amazon.awssdk.utils.Validate;
@@ -161,6 +162,14 @@ public interface S3CrtAsyncClientBuilder extends SdkBuilder<S3CrtAsyncClientBuil
161162
*/
162163
S3CrtAsyncClientBuilder httpConfiguration(S3CrtHttpConfiguration configuration);
163164

165+
/**
166+
* Sets the Retry configuration to use for this client.
167+
*
168+
* @param retryConfiguration The retry configurations to be used.
169+
* @return The builder of the method chaining.
170+
*/
171+
S3CrtAsyncClientBuilder retryConfiguration(S3CrtRetryConfiguration retryConfiguration);
172+
164173
/**
165174
* A convenience method that creates an instance of the {@link S3CrtHttpConfiguration} builder, avoiding the
166175
* need to create one manually via {@link S3CrtHttpConfiguration#builder()}.
@@ -177,6 +186,25 @@ default S3CrtAsyncClientBuilder httpConfiguration(Consumer<S3CrtHttpConfiguratio
177186
}
178187

179188

189+
/**
190+
* A convenience method that creates an instance of the {@link S3CrtRetryConfiguration} builder, avoiding the
191+
* need to create one manually via {@link S3CrtRetryConfiguration#builder()}.
192+
*
193+
* @param retryConfigurationBuilder The retry config builder to use
194+
* @return The builder of the method chaining.
195+
* @see #retryConfiguration(S3CrtRetryConfiguration)
196+
*/
197+
default S3CrtAsyncClientBuilder retryConfiguration(Consumer<S3CrtRetryConfiguration.Builder> retryConfigurationBuilder) {
198+
Validate.paramNotNull(retryConfigurationBuilder, "configurationBuilder");
199+
return retryConfiguration(S3CrtRetryConfiguration.builder()
200+
.applyMutation(retryConfigurationBuilder)
201+
.build());
202+
}
203+
204+
205+
206+
207+
180208
@Override
181209
S3AsyncClient build();
182210
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.services.s3.crt;
17+
18+
import java.util.Objects;
19+
import software.amazon.awssdk.annotations.Immutable;
20+
import software.amazon.awssdk.annotations.SdkPublicApi;
21+
import software.amazon.awssdk.annotations.ThreadSafe;
22+
import software.amazon.awssdk.services.s3.S3CrtAsyncClientBuilder;
23+
import software.amazon.awssdk.utils.Validate;
24+
import software.amazon.awssdk.utils.builder.CopyableBuilder;
25+
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
26+
27+
/**
28+
* Retry option configuration for AWS CRT-based S3 client.
29+
*
30+
* @see S3CrtAsyncClientBuilder#retryConfiguration
31+
*/
32+
@SdkPublicApi
33+
@Immutable
34+
@ThreadSafe
35+
public final class S3CrtRetryConfiguration implements ToCopyableBuilder<S3CrtRetryConfiguration.Builder,
36+
S3CrtRetryConfiguration> {
37+
private final Integer numRetries;
38+
39+
private S3CrtRetryConfiguration(DefaultBuilder builder) {
40+
Validate.isPositiveOrNull(builder.numRetries, "numRetries");
41+
this.numRetries = builder.numRetries;
42+
}
43+
44+
/**
45+
* Creates a default builder for {@link S3CrtRetryConfiguration}.
46+
*/
47+
public static Builder builder() {
48+
return new S3CrtRetryConfiguration.DefaultBuilder();
49+
}
50+
51+
/**
52+
* Return the amount of time to wait when initially establishing a connection before giving up and timing out.
53+
*/
54+
public Integer numRetries() {
55+
return numRetries;
56+
}
57+
58+
@Override
59+
public boolean equals(Object o) {
60+
if (this == o) {
61+
return true;
62+
}
63+
if (o == null || getClass() != o.getClass()) {
64+
return false;
65+
}
66+
S3CrtRetryConfiguration that = (S3CrtRetryConfiguration) o;
67+
return Objects.equals(numRetries, that.numRetries);
68+
}
69+
70+
@Override
71+
public int hashCode() {
72+
return numRetries != null ? numRetries.hashCode() : 0;
73+
}
74+
75+
@Override
76+
public Builder toBuilder() {
77+
return new S3CrtRetryConfiguration.DefaultBuilder(this);
78+
}
79+
80+
public interface Builder extends CopyableBuilder<S3CrtRetryConfiguration.Builder, S3CrtRetryConfiguration> {
81+
82+
/**
83+
* Configure the maximum number of times that a single request should be retried.
84+
* @param numRetries
85+
* @return The builder of the method chaining.
86+
*/
87+
Builder numRetries(Integer numRetries);
88+
89+
}
90+
91+
private static final class DefaultBuilder implements Builder {
92+
private Integer numRetries;
93+
94+
private DefaultBuilder() {
95+
}
96+
97+
private DefaultBuilder(S3CrtRetryConfiguration crtRetryConfiguration) {
98+
this.numRetries = crtRetryConfiguration.numRetries;
99+
}
100+
101+
@Override
102+
public Builder numRetries(Integer numRetries) {
103+
this.numRetries = numRetries;
104+
return this;
105+
}
106+
107+
@Override
108+
public S3CrtRetryConfiguration build() {
109+
return new S3CrtRetryConfiguration(this);
110+
}
111+
}
112+
}

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,16 @@
3737
import software.amazon.awssdk.core.internal.util.ClassLoaderHelper;
3838
import software.amazon.awssdk.core.retry.RetryPolicy;
3939
import software.amazon.awssdk.core.signer.NoOpSigner;
40+
import software.amazon.awssdk.crt.io.ExponentialBackoffRetryOptions;
41+
import software.amazon.awssdk.crt.io.StandardRetryOptions;
4042
import software.amazon.awssdk.http.SdkHttpExecutionAttributes;
4143
import software.amazon.awssdk.regions.Region;
4244
import software.amazon.awssdk.services.s3.DelegatingS3AsyncClient;
4345
import software.amazon.awssdk.services.s3.S3AsyncClient;
4446
import software.amazon.awssdk.services.s3.S3Configuration;
4547
import software.amazon.awssdk.services.s3.S3CrtAsyncClientBuilder;
4648
import software.amazon.awssdk.services.s3.crt.S3CrtHttpConfiguration;
49+
import software.amazon.awssdk.services.s3.crt.S3CrtRetryConfiguration;
4750
import software.amazon.awssdk.services.s3.model.CopyObjectRequest;
4851
import software.amazon.awssdk.services.s3.model.CopyObjectResponse;
4952
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
@@ -96,21 +99,28 @@ private static S3CrtAsyncHttpClient.Builder initializeS3CrtAsyncHttpClient(Defau
9699
Validate.isPositiveOrNull(builder.targetThroughputInGbps, "targetThroughputInGbps");
97100
Validate.isPositiveOrNull(builder.minimalPartSizeInBytes, "minimalPartSizeInBytes");
98101

99-
S3NativeClientConfiguration s3NativeClientConfiguration =
102+
S3NativeClientConfiguration.Builder nativeClientBuilder =
100103
S3NativeClientConfiguration.builder()
101104
.checksumValidationEnabled(builder.checksumValidationEnabled)
102105
.targetThroughputInGbps(builder.targetThroughputInGbps)
103106
.partSizeInBytes(builder.minimalPartSizeInBytes)
104107
.maxConcurrency(builder.maxConcurrency)
105-
.signingRegion(builder.region == null ? null : builder.region.id())
108+
.signingRegion(builder.region == null ? null
109+
:
110+
builder.region.id())
106111
.endpointOverride(builder.endpointOverride)
107112
.credentialsProvider(builder.credentialsProvider)
108113
.readBufferSizeInBytes(builder.readBufferSizeInBytes)
109-
.httpConfiguration(builder.httpConfiguration)
110-
.build();
114+
.httpConfiguration(builder.httpConfiguration);
111115

116+
if (builder.retryConfiguration != null) {
117+
nativeClientBuilder.standardRetryOptions(
118+
new StandardRetryOptions()
119+
.withBackoffRetryOptions(new ExponentialBackoffRetryOptions()
120+
.withMaxRetries(builder.retryConfiguration.numRetries())));
121+
}
112122
return S3CrtAsyncHttpClient.builder()
113-
.s3ClientConfiguration(s3NativeClientConfiguration);
123+
.s3ClientConfiguration(nativeClientBuilder.build());
114124
}
115125

116126
public static final class DefaultS3CrtClientBuilder implements S3CrtAsyncClientBuilder {
@@ -123,6 +133,7 @@ public static final class DefaultS3CrtClientBuilder implements S3CrtAsyncClientB
123133
private URI endpointOverride;
124134
private Boolean checksumValidationEnabled;
125135
private S3CrtHttpConfiguration httpConfiguration;
136+
private S3CrtRetryConfiguration retryConfiguration;
126137

127138
public AwsCredentialsProvider credentialsProvider() {
128139
return credentialsProvider;
@@ -206,6 +217,12 @@ public S3CrtAsyncClientBuilder httpConfiguration(S3CrtHttpConfiguration configur
206217
return this;
207218
}
208219

220+
@Override
221+
public S3CrtAsyncClientBuilder retryConfiguration(S3CrtRetryConfiguration retryConfiguration) {
222+
this.retryConfiguration = retryConfiguration;
223+
return this;
224+
}
225+
209226
@Override
210227
public S3CrtAsyncClient build() {
211228
return new DefaultS3CrtAsyncClient(this);

0 commit comments

Comments
 (0)