Skip to content

Commit f387f6f

Browse files
authored
Use AWS_NEW_RETRIES_2026 during mode resolution (#6872)
* Use AWS_NEW_RETRIES_2026 during mode resolution * Review comments
1 parent fe4abb1 commit f387f6f

3 files changed

Lines changed: 201 additions & 3 deletions

File tree

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,6 @@ public static Resolver resolver() {
130130
* Allows customizing the variables used during determination of a {@link RetryMode}. Created via {@link #resolver()}.
131131
*/
132132
public static class Resolver {
133-
private static final RetryMode SDK_DEFAULT_RETRY_MODE = LEGACY;
134-
135133
private Supplier<ProfileFile> profileFile;
136134
private String profileName;
137135
private RetryMode defaultRetryMode;
@@ -204,7 +202,14 @@ private static Optional<RetryMode> fromString(String string) {
204202
}
205203

206204
private RetryMode fromDefaultMode() {
207-
return defaultRetryMode != null ? defaultRetryMode : SDK_DEFAULT_RETRY_MODE;
205+
return defaultRetryMode != null ? defaultRetryMode : sdkDefaultRetryMode();
206+
}
207+
208+
/**
209+
* Resolves the SDK default retry mode dynamically based on the {@code AWS_NEW_RETRIES_2026} gate.
210+
*/
211+
private static RetryMode sdkDefaultRetryMode() {
212+
return SdkSystemSetting.AWS_NEW_RETRIES_2026.getBooleanValue().orElse(false) ? STANDARD : LEGACY;
208213
}
209214
}
210215
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import org.junit.jupiter.api.AfterEach;
21+
import org.junit.jupiter.api.Test;
22+
import org.junit.jupiter.params.ParameterizedTest;
23+
import org.junit.jupiter.params.provider.CsvSource;
24+
import software.amazon.awssdk.testutils.EnvironmentVariableHelper;
25+
26+
/**
27+
* Tests for the {@link SdkSystemSetting#AWS_NEW_RETRIES_2026} system setting.
28+
*/
29+
class SdkSystemSettingNewRetriesTest {
30+
31+
@AfterEach
32+
void cleanup() {
33+
System.clearProperty(SdkSystemSetting.AWS_NEW_RETRIES_2026.property());
34+
}
35+
36+
@Test
37+
void defaultsToFalse_whenUnset() {
38+
assertThat(SdkSystemSetting.AWS_NEW_RETRIES_2026.getBooleanValue()).hasValue(false);
39+
}
40+
41+
@ParameterizedTest(name = "systemProperty=\"{0}\" -> {1}")
42+
@CsvSource({
43+
"false, false",
44+
"true, true"
45+
})
46+
void getBooleanValue_reflectsSystemProperty(String propertyValue, boolean expected) {
47+
System.setProperty(SdkSystemSetting.AWS_NEW_RETRIES_2026.property(), propertyValue);
48+
assertThat(SdkSystemSetting.AWS_NEW_RETRIES_2026.getBooleanValue()).hasValue(expected);
49+
}
50+
51+
@ParameterizedTest(name = "envVar=\"{0}\" -> {1}")
52+
@CsvSource({
53+
"false, false",
54+
"true, true"
55+
})
56+
void getBooleanValue_reflectsEnvVar(String envVarValue, boolean expected) {
57+
EnvironmentVariableHelper.run(helper -> {
58+
helper.set(SdkSystemSetting.AWS_NEW_RETRIES_2026, envVarValue);
59+
assertThat(SdkSystemSetting.AWS_NEW_RETRIES_2026.getBooleanValue()).hasValue(expected);
60+
});
61+
}
62+
63+
@Test
64+
void systemPropertyTakesPrecedenceOverEnvVar() {
65+
EnvironmentVariableHelper.run(helper -> {
66+
System.setProperty(SdkSystemSetting.AWS_NEW_RETRIES_2026.property(), "false");
67+
helper.set(SdkSystemSetting.AWS_NEW_RETRIES_2026, "true");
68+
assertThat(SdkSystemSetting.AWS_NEW_RETRIES_2026.getBooleanValue()).hasValue(false);
69+
});
70+
}
71+
72+
@Test
73+
void environmentVariable_isCorrectName() {
74+
assertThat(SdkSystemSetting.AWS_NEW_RETRIES_2026.environmentVariable())
75+
.isEqualTo("AWS_NEW_RETRIES_2026");
76+
}
77+
78+
@Test
79+
void systemProperty_isCorrectName() {
80+
assertThat(SdkSystemSetting.AWS_NEW_RETRIES_2026.property())
81+
.isEqualTo("aws.newRetries2026");
82+
}
83+
84+
@Test
85+
void defaultValue_isFalse() {
86+
assertThat(SdkSystemSetting.AWS_NEW_RETRIES_2026.defaultValue())
87+
.isEqualTo("false");
88+
}
89+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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 org.junit.jupiter.api.AfterEach;
22+
import org.junit.jupiter.api.BeforeEach;
23+
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.params.ParameterizedTest;
25+
import org.junit.jupiter.params.provider.CsvSource;
26+
import software.amazon.awssdk.core.SdkSystemSetting;
27+
import software.amazon.awssdk.testutils.EnvironmentVariableHelper;
28+
29+
/**
30+
* Tests for the gated default {@link RetryMode} behavior controlled by
31+
* {@link SdkSystemSetting#AWS_NEW_RETRIES_2026}.
32+
*/
33+
class RetryModeGatedDefaultTest {
34+
35+
@BeforeEach
36+
@AfterEach
37+
void cleanup() {
38+
System.clearProperty(SdkSystemSetting.AWS_NEW_RETRIES_2026.property());
39+
System.clearProperty(SdkSystemSetting.AWS_RETRY_MODE.property());
40+
}
41+
42+
@Test
43+
void defaultRetryMode_returnsLegacy_whenGateIsUnset() {
44+
assertThat(RetryMode.defaultRetryMode()).isEqualTo(RetryMode.LEGACY);
45+
}
46+
47+
@ParameterizedTest(name = "gate=\"{0}\" -> {1}")
48+
@CsvSource({
49+
"false, LEGACY",
50+
"true, STANDARD"
51+
})
52+
void defaultRetryMode_reflectsGate_whenSetViaSystemProperty(String gateValue, RetryMode expected) {
53+
System.setProperty(SdkSystemSetting.AWS_NEW_RETRIES_2026.property(), gateValue);
54+
assertThat(RetryMode.defaultRetryMode()).isEqualTo(expected);
55+
}
56+
57+
@ParameterizedTest(name = "gate=\"{0}\" -> {1}")
58+
@CsvSource({
59+
"false, LEGACY",
60+
"true, STANDARD"
61+
})
62+
void defaultRetryMode_reflectsGate_whenSetViaEnvVar(String gateValue, RetryMode expected) {
63+
EnvironmentVariableHelper.run(helper -> {
64+
helper.set(SdkSystemSetting.AWS_NEW_RETRIES_2026, gateValue);
65+
assertThat(RetryMode.defaultRetryMode()).isEqualTo(expected);
66+
});
67+
}
68+
69+
@Test
70+
void defaultRetryMode_changesDynamically_whenGateSystemPropertyChangesAtRuntime() {
71+
// Initially unset — should be LEGACY
72+
assertThat(RetryMode.defaultRetryMode()).isEqualTo(RetryMode.LEGACY);
73+
74+
// Enable gate — should switch to STANDARD
75+
System.setProperty(SdkSystemSetting.AWS_NEW_RETRIES_2026.property(), "true");
76+
assertThat(RetryMode.defaultRetryMode()).isEqualTo(RetryMode.STANDARD);
77+
78+
// Disable gate — should revert to LEGACY
79+
System.setProperty(SdkSystemSetting.AWS_NEW_RETRIES_2026.property(), "false");
80+
assertThat(RetryMode.defaultRetryMode()).isEqualTo(RetryMode.LEGACY);
81+
82+
// Clear gate — should fall back to default (LEGACY)
83+
System.clearProperty(SdkSystemSetting.AWS_NEW_RETRIES_2026.property());
84+
assertThat(RetryMode.defaultRetryMode()).isEqualTo(RetryMode.LEGACY);
85+
}
86+
87+
@ParameterizedTest(name = "gate=\"{0}\" retryMode=\"{1}\" -> {2}")
88+
@CsvSource({
89+
"true, legacy, LEGACY",
90+
"false, standard, STANDARD",
91+
"false, adaptive, ADAPTIVE_V2"
92+
})
93+
void resolve_honorsExplicitRetryMode_regardlessOfGate(String gateValue, String retryModeValue, RetryMode expected) {
94+
System.setProperty(SdkSystemSetting.AWS_NEW_RETRIES_2026.property(), gateValue);
95+
System.setProperty(SdkSystemSetting.AWS_RETRY_MODE.property(), retryModeValue);
96+
assertThat(RetryMode.defaultRetryMode()).isEqualTo(expected);
97+
}
98+
99+
@Test
100+
void resolve_throwsIllegalStateException_whenInvalidRetryModeConfigured() {
101+
System.setProperty(SdkSystemSetting.AWS_RETRY_MODE.property(), "invalid_mode");
102+
assertThatThrownBy(RetryMode::defaultRetryMode).isInstanceOf(IllegalStateException.class);
103+
}
104+
}

0 commit comments

Comments
 (0)