Skip to content

Commit 5bf58cb

Browse files
authored
Add missing support for AWS_MAX_ATTEMPTS in retry strategies (#5379)
* Add missing support for AWS_MAX_ATTEMPTS in retry strategies * Add changelog
1 parent 8765214 commit 5bf58cb

File tree

3 files changed

+161
-0
lines changed

3 files changed

+161
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "AWS SDK for Java v2",
3+
"contributor": "",
4+
"type": "bugfix",
5+
"description": "Update way we build retry strategies to honor the `AWS_MAX_ATTEMPTS` system setting."
6+
}

core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/retry/SdkDefaultRetryStrategy.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package software.amazon.awssdk.core.internal.retry;
1717

1818
import software.amazon.awssdk.annotations.SdkPublicApi;
19+
import software.amazon.awssdk.core.SdkSystemSetting;
1920
import software.amazon.awssdk.core.exception.SdkException;
2021
import software.amazon.awssdk.core.exception.SdkServiceException;
2122
import software.amazon.awssdk.core.retry.RetryMode;
@@ -160,6 +161,10 @@ public static AdaptiveRetryStrategy.Builder adaptiveRetryStrategyBuilder() {
160161
.retryOnException(SdkDefaultRetryStrategy::retryOnThrottlingCondition);
161162
SdkDefaultRetrySetting.RETRYABLE_EXCEPTIONS.forEach(builder::retryOnExceptionOrCauseInstanceOf);
162163
builder.treatAsThrottling(SdkDefaultRetryStrategy::treatAsThrottling);
164+
Integer maxAttempts = SdkSystemSetting.AWS_MAX_ATTEMPTS.getIntegerValue().orElse(null);
165+
if (maxAttempts != null) {
166+
builder.maxAttempts(maxAttempts);
167+
}
163168
return builder;
164169
}
165170

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
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.core.retry;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
20+
21+
import java.nio.file.Files;
22+
import java.nio.file.Paths;
23+
import java.util.Arrays;
24+
import java.util.Collection;
25+
import org.junit.After;
26+
import org.junit.Before;
27+
import org.junit.BeforeClass;
28+
import org.junit.Test;
29+
import org.junit.runner.RunWith;
30+
import org.junit.runners.Parameterized;
31+
import software.amazon.awssdk.core.SdkSystemSetting;
32+
import software.amazon.awssdk.core.internal.retry.SdkDefaultRetryStrategy;
33+
import software.amazon.awssdk.profiles.ProfileFileSystemSetting;
34+
import software.amazon.awssdk.testutils.EnvironmentVariableHelper;
35+
import software.amazon.awssdk.utils.Validate;
36+
37+
38+
@RunWith(Parameterized.class)
39+
public class RetryStrategyMaxRetriesTest {
40+
private static final EnvironmentVariableHelper ENVIRONMENT_VARIABLE_HELPER = new EnvironmentVariableHelper();
41+
42+
@Parameterized.Parameter
43+
public TestData testData;
44+
45+
@Parameterized.Parameters
46+
public static Collection<Object> data() {
47+
return Arrays.asList(new Object[] {
48+
// Test defaults
49+
new TestData(null, null, null, null, null, 4),
50+
new TestData(null, null, null, null, "PropertyNotSet", 4),
51+
52+
// Test precedence
53+
new TestData("9", "2", "standard", "standard",
54+
"PropertySetToStandard", 9),
55+
new TestData(null, "9", "standard", "standard",
56+
"PropertySetToStandard", 9),
57+
new TestData(null, null, "standard", "standard",
58+
"PropertySetToStandard", 3),
59+
new TestData(null, null, null, "standard",
60+
"PropertySetToStandard", 3),
61+
new TestData(null, null, null, null,
62+
"PropertySetToStandard", 3),
63+
64+
// Test invalid values
65+
new TestData("wrongValue", null, null, null, null, null),
66+
new TestData(null, "wrongValue", null, null, null, null),
67+
new TestData(null, null, "wrongValue", null, null, null),
68+
new TestData(null, null, null, "wrongValue", null, null),
69+
new TestData(null, null, null, null,
70+
"PropertySetToUnsupportedValue", null),
71+
});
72+
}
73+
74+
@BeforeClass
75+
public static void classSetup() {
76+
// If this caches any values, make sure it's cached with the default (non-modified) configuration.
77+
SdkDefaultRetryStrategy.defaultRetryStrategy();
78+
}
79+
80+
@Before
81+
@After
82+
public void methodSetup() {
83+
ENVIRONMENT_VARIABLE_HELPER.reset();
84+
System.clearProperty(SdkSystemSetting.AWS_MAX_ATTEMPTS.property());
85+
System.clearProperty(SdkSystemSetting.AWS_RETRY_MODE.property());
86+
System.clearProperty(ProfileFileSystemSetting.AWS_PROFILE.property());
87+
System.clearProperty(ProfileFileSystemSetting.AWS_CONFIG_FILE.property());
88+
}
89+
90+
@Test
91+
public void differentCombinationOfConfigs_shouldResolveCorrectly() {
92+
if (testData.attemptCountEnvVarValue != null) {
93+
ENVIRONMENT_VARIABLE_HELPER.set(SdkSystemSetting.AWS_MAX_ATTEMPTS.environmentVariable(),
94+
testData.attemptCountEnvVarValue);
95+
}
96+
97+
if (testData.attemptCountSystemProperty != null) {
98+
System.setProperty(SdkSystemSetting.AWS_MAX_ATTEMPTS.property(), testData.attemptCountSystemProperty);
99+
}
100+
101+
if (testData.envVarValue != null) {
102+
ENVIRONMENT_VARIABLE_HELPER.set(SdkSystemSetting.AWS_RETRY_MODE.environmentVariable(), testData.envVarValue);
103+
}
104+
105+
if (testData.systemProperty != null) {
106+
System.setProperty(SdkSystemSetting.AWS_RETRY_MODE.property(), testData.systemProperty);
107+
}
108+
109+
if (testData.configFile != null) {
110+
String diskLocationForFile = diskLocationForConfig(testData.configFile);
111+
Validate.isTrue(Files.isReadable(Paths.get(diskLocationForFile)), diskLocationForFile + " is not readable.");
112+
System.setProperty(ProfileFileSystemSetting.AWS_PROFILE.property(), "default");
113+
System.setProperty(ProfileFileSystemSetting.AWS_CONFIG_FILE.property(), diskLocationForFile);
114+
}
115+
116+
if (testData.expected == null) {
117+
assertThatThrownBy(() -> SdkDefaultRetryStrategy.forRetryMode(RetryMode.defaultRetryMode())).isInstanceOf(RuntimeException.class);
118+
} else {
119+
assertThat(SdkDefaultRetryStrategy.forRetryMode(RetryMode.defaultRetryMode()).maxAttempts()).isEqualTo(testData.expected);
120+
}
121+
}
122+
123+
private String diskLocationForConfig(String configFileName) {
124+
return getClass().getResource(configFileName).getFile();
125+
}
126+
127+
private static class TestData {
128+
private final String attemptCountSystemProperty;
129+
private final String attemptCountEnvVarValue;
130+
private final String envVarValue;
131+
private final String systemProperty;
132+
private final String configFile;
133+
private final Integer expected;
134+
135+
TestData(String attemptCountSystemProperty,
136+
String attemptCountEnvVarValue,
137+
String retryModeSystemProperty,
138+
String retryModeEnvVarValue,
139+
String configFile,
140+
Integer expected) {
141+
this.attemptCountSystemProperty = attemptCountSystemProperty;
142+
this.attemptCountEnvVarValue = attemptCountEnvVarValue;
143+
this.envVarValue = retryModeEnvVarValue;
144+
this.systemProperty = retryModeSystemProperty;
145+
this.configFile = configFile;
146+
this.expected = expected;
147+
}
148+
}
149+
}
150+

0 commit comments

Comments
 (0)