Skip to content

Commit 040b7fd

Browse files
committed
Add s3 regional setting
1 parent 28ef24b commit 040b7fd

File tree

13 files changed

+247
-67
lines changed

13 files changed

+247
-67
lines changed

codegen-lite/src/main/java/software/amazon/awssdk/codegen/lite/defaultsmode/DefaultsModeConfigurationGenerator.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public class DefaultsModeConfigurationGenerator implements PoetClass {
5151
private static final Map<String, OptionMetadata> HTTP_CONFIGURATION_MAPPING = new HashMap<>();
5252
private static final String CONNECT_TIMEOUT_IN_MILLIS = "connectTimeoutInMillis";
5353
private static final String TLS_NEGOTIATION_TIMEOUT_IN_MILLIS = "tlsNegotiationTimeoutInMillis";
54+
private static final String S3_US_EAST_1_REGIONAL_ENDPOINTS = "s3UsEast1RegionalEndpoints";
5455

5556
private final String basePackage;
5657
private final String defaultsModeBase;
@@ -68,6 +69,12 @@ public class DefaultsModeConfigurationGenerator implements PoetClass {
6869
"TLS_NEGOTIATION_TIMEOUT")));
6970
CONFIGURATION_MAPPING.put("retryMode", new OptionMetadata(ClassName.get("software.amazon.awssdk.core.retry", "RetryMode"
7071
), ClassName.get("software.amazon.awssdk.core.client.config", "SdkClientOption", "DEFAULT_RETRY_MODE")));
72+
73+
CONFIGURATION_MAPPING.put(S3_US_EAST_1_REGIONAL_ENDPOINTS,
74+
new OptionMetadata(ClassName.get(String.class),
75+
ClassName.get("software.amazon.awssdk.regions",
76+
"ServiceMetadataAdvancedOption",
77+
"S3_US_EAST_1_REGIONAL_ENDPOINT")));
7178
}
7279

7380
public DefaultsModeConfigurationGenerator(String basePackage, String defaultsModeBase, DefaultConfiguration configuration) {
@@ -121,8 +128,8 @@ private void addStaticEnumMapBlock(TypeSpec.Builder builder) {
121128

122129
private void addEnumMapField(TypeSpec.Builder builder, String name) {
123130
ParameterizedTypeName map = ParameterizedTypeName.get(ClassName.get(Map.class),
124-
defaultsModeClassName(),
125-
ClassName.get(AttributeMap.class));
131+
defaultsModeClassName(),
132+
ClassName.get(AttributeMap.class));
126133
FieldSpec field = FieldSpec.builder(map, name, PRIVATE, STATIC, FINAL)
127134
.initializer("new $T<>(DefaultsMode.class)", EnumMap.class).build();
128135
builder.addField(field);
@@ -179,6 +186,9 @@ private void attributeMapBuilder(String option, String value, CodeBlock.Builder
179186
attributeBuilder.add(".put($T, $T.$N)", optionMetadata.attribute, optionMetadata.type,
180187
value.toUpperCase(Locale.US));
181188
break;
189+
case S3_US_EAST_1_REGIONAL_ENDPOINTS:
190+
attributeBuilder.add(".put($T, $S)", optionMetadata.attribute, value);
191+
break;
182192
default:
183193
throw new IllegalStateException("Unsupported option " + option);
184194
}

codegen-lite/src/test/resources/software/amazon/awssdk/codegen/lite/defaultsmode/defaults-mode-configuration.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import software.amazon.awssdk.core.client.config.SdkClientOption;
99
import software.amazon.awssdk.core.retry.RetryMode;
1010
import software.amazon.awssdk.http.SdkHttpConfigurationOption;
11+
import software.amazon.awssdk.regions.ServiceMetadataAdvancedOption;
1112
import software.amazon.awssdk.utils.AttributeMap;
1213

1314
/**
@@ -17,28 +18,32 @@
1718
@Generated("software.amazon.awssdk:codegen")
1819
public final class DefaultsModeConfiguration {
1920
private static final AttributeMap STANDARD_DEFAULTS = AttributeMap.builder()
20-
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.STANDARD).build();
21+
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.STANDARD)
22+
.put(ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT, "regional").build();
2123

2224
private static final AttributeMap STANDARD_HTTP_DEFAULTS = AttributeMap.builder()
2325
.put(SdkHttpConfigurationOption.CONNECTION_TIMEOUT, Duration.ofMillis(2000))
2426
.put(SdkHttpConfigurationOption.TLS_NEGOTIATION_TIMEOUT, Duration.ofMillis(2000)).build();
2527

2628
private static final AttributeMap MOBILE_DEFAULTS = AttributeMap.builder()
27-
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.ADAPTIVE).build();
29+
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.ADAPTIVE)
30+
.put(ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT, "regional").build();
2831

2932
private static final AttributeMap MOBILE_HTTP_DEFAULTS = AttributeMap.builder()
3033
.put(SdkHttpConfigurationOption.CONNECTION_TIMEOUT, Duration.ofMillis(10000))
3134
.put(SdkHttpConfigurationOption.TLS_NEGOTIATION_TIMEOUT, Duration.ofMillis(11000)).build();
3235

3336
private static final AttributeMap CROSS_REGION_DEFAULTS = AttributeMap.builder()
34-
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.STANDARD).build();
37+
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.STANDARD)
38+
.put(ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT, "regional").build();
3539

3640
private static final AttributeMap CROSS_REGION_HTTP_DEFAULTS = AttributeMap.builder()
3741
.put(SdkHttpConfigurationOption.CONNECTION_TIMEOUT, Duration.ofMillis(2800))
3842
.put(SdkHttpConfigurationOption.TLS_NEGOTIATION_TIMEOUT, Duration.ofMillis(2800)).build();
3943

4044
private static final AttributeMap IN_REGION_DEFAULTS = AttributeMap.builder()
41-
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.STANDARD).build();
45+
.put(SdkClientOption.DEFAULT_RETRY_MODE, RetryMode.STANDARD)
46+
.put(ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT, "regional").build();
4247

4348
private static final AttributeMap IN_REGION_HTTP_DEFAULTS = AttributeMap.builder()
4449
.put(SdkHttpConfigurationOption.CONNECTION_TIMEOUT, Duration.ofMillis(1000))

core/aws-core/src/main/java/software/amazon/awssdk/awscore/client/builder/AwsDefaultClientBuilder.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import software.amazon.awssdk.profiles.ProfileFile;
4848
import software.amazon.awssdk.regions.Region;
4949
import software.amazon.awssdk.regions.ServiceMetadata;
50+
import software.amazon.awssdk.regions.ServiceMetadataAdvancedOption;
5051
import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain;
5152
import software.amazon.awssdk.utils.AttributeMap;
5253
import software.amazon.awssdk.utils.CollectionUtils;
@@ -188,12 +189,15 @@ protected final SdkClientConfiguration finalizeChildConfiguration(SdkClientConfi
188189

189190
private SdkClientConfiguration mergeSmartDefaults(SdkClientConfiguration configuration) {
190191
DefaultsMode defaultsMode = resolveDefaultsMode(configuration);
191-
RetryMode retryMode = DefaultsModeConfiguration.defaultConfig(defaultsMode).get(SdkClientOption.DEFAULT_RETRY_MODE);
192-
192+
AttributeMap defaultConfig = DefaultsModeConfiguration.defaultConfig(defaultsMode);
193193
return configuration.toBuilder()
194194
.option(DEFAULTS_MODE, defaultsMode)
195195
.build()
196-
.merge(c -> c.option(SdkClientOption.DEFAULT_RETRY_MODE, retryMode));
196+
.merge(c -> c.option(SdkClientOption.DEFAULT_RETRY_MODE,
197+
defaultConfig.get(SdkClientOption.DEFAULT_RETRY_MODE))
198+
.option(ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT,
199+
defaultConfig.get(
200+
ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT)));
197201
}
198202

199203
/**
@@ -232,6 +236,8 @@ private URI endpointFromConfig(SdkClientConfiguration config) {
232236
.withRegion(config.option(AwsClientOption.AWS_REGION))
233237
.withProfileFile(config.option(SdkClientOption.PROFILE_FILE))
234238
.withProfileName(config.option(SdkClientOption.PROFILE_NAME))
239+
.putAdvancedOption(ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT,
240+
config.option(ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT))
235241
.getServiceEndpoint();
236242
}
237243

core/aws-core/src/main/java/software/amazon/awssdk/awscore/endpoint/DefaultServiceEndpointBuilder.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717

1818
import java.net.URI;
1919
import java.net.URISyntaxException;
20+
import java.util.HashMap;
2021
import java.util.List;
22+
import java.util.Map;
2123
import software.amazon.awssdk.annotations.NotThreadSafe;
2224
import software.amazon.awssdk.annotations.SdkProtectedApi;
2325
import software.amazon.awssdk.core.exception.SdkClientException;
2426
import software.amazon.awssdk.profiles.ProfileFile;
2527
import software.amazon.awssdk.regions.Region;
2628
import software.amazon.awssdk.regions.ServiceMetadata;
29+
import software.amazon.awssdk.regions.ServiceMetadataAdvancedOption;
2730
import software.amazon.awssdk.utils.Validate;
2831

2932
/**
@@ -40,6 +43,7 @@ public final class DefaultServiceEndpointBuilder {
4043
private Region region;
4144
private ProfileFile profileFile;
4245
private String profileName;
46+
private final Map<ServiceMetadataAdvancedOption<?>, Object> advancedOptions = new HashMap<>();
4347

4448
public DefaultServiceEndpointBuilder(String serviceName, String protocol) {
4549
this.serviceName = Validate.paramNotNull(serviceName, "serviceName");
@@ -64,10 +68,16 @@ public DefaultServiceEndpointBuilder withProfileName(String profileName) {
6468
return this;
6569
}
6670

71+
public <T> DefaultServiceEndpointBuilder putAdvancedOption(ServiceMetadataAdvancedOption<T> option, T value) {
72+
advancedOptions.put(option, value);
73+
return this;
74+
}
75+
6776
public URI getServiceEndpoint() {
6877
ServiceMetadata serviceMetadata = ServiceMetadata.of(serviceName)
6978
.reconfigure(c -> c.profileFile(() -> profileFile)
70-
.profileName(profileName));
79+
.profileName(profileName)
80+
.advancedOptions(advancedOptions));
7181
URI endpoint = addProtocolToServiceEndpoint(serviceMetadata.endpointFor(region));
7282

7383
if (endpoint.getHost() == null) {

core/aws-core/src/test/java/software/amazon/awssdk/awscore/client/builder/DefaultsModeTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static software.amazon.awssdk.awscore.client.config.AwsClientOption.DEFAULTS_MODE;
2424
import static software.amazon.awssdk.core.client.config.SdkClientOption.DEFAULT_RETRY_MODE;
2525
import static software.amazon.awssdk.core.client.config.SdkClientOption.RETRY_POLICY;
26+
import static software.amazon.awssdk.regions.ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT;
2627

2728
import java.time.Duration;
2829
import org.junit.Test;
@@ -75,6 +76,7 @@ public void defaultClient_shouldUseLegacyModeWithExistingDefaults() {
7576

7677
assertThat(client.clientConfiguration.option(DEFAULTS_MODE)).isEqualTo(DefaultsMode.LEGACY);
7778
assertThat(client.clientConfiguration.option(RETRY_POLICY).retryMode()).isEqualTo(RetryMode.defaultRetryMode());
79+
assertThat(client.clientConfiguration.option(S3_US_EAST_1_REGIONAL_ENDPOINT)).isNull();
7880
}
7981

8082
@Test
@@ -96,6 +98,7 @@ public void nonLegacyDefaultsMode_shouldApplySdkDefaultsAndHttpDefaults() {
9698
AttributeMap attributes = DefaultsModeConfiguration.defaultConfig(targetMode);
9799

98100
assertThat(client.clientConfiguration.option(RETRY_POLICY).retryMode()).isEqualTo(attributes.get(DEFAULT_RETRY_MODE));
101+
assertThat(client.clientConfiguration.option(S3_US_EAST_1_REGIONAL_ENDPOINT)).isEqualTo("regional");
99102
}
100103

101104
@Test

core/aws-core/src/test/java/software/amazon/awssdk/awscore/client/endpoint/DefaultServiceEndpointBuilderTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.junit.Test;
2121
import software.amazon.awssdk.awscore.endpoint.DefaultServiceEndpointBuilder;
2222
import software.amazon.awssdk.regions.Region;
23+
import software.amazon.awssdk.regions.ServiceMetadataAdvancedOption;
2324

2425
public class DefaultServiceEndpointBuilderTest {
2526

@@ -43,4 +44,12 @@ public void getServiceEndpoint_S3NonStandardRegion_HttpProtocol() throws Excepti
4344
.withRegion(Region.EU_CENTRAL_1);
4445
assertEquals("http://s3.eu-central-1.amazonaws.com", endpointBuilder.getServiceEndpoint().toString());
4546
}
47+
48+
@Test
49+
public void getServiceEndpoint_regionalOption_shouldUseRegionalEndpoint() throws Exception {
50+
DefaultServiceEndpointBuilder endpointBuilder = new DefaultServiceEndpointBuilder("s3", "http")
51+
.withRegion(Region.US_EAST_1).putAdvancedOption(ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT,
52+
"regional");
53+
assertEquals("http://s3.us-east-1.amazonaws.com", endpointBuilder.getServiceEndpoint().toString());
54+
}
4655
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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.regions;
17+
18+
import software.amazon.awssdk.annotations.SdkPublicApi;
19+
import software.amazon.awssdk.core.client.config.ClientOption;
20+
21+
22+
/**
23+
* A collection of advanced options that can be configured on a {@link ServiceMetadata} via
24+
* {@link ServiceMetadataConfiguration.Builder#putAdvancedOption(ServiceMetadataAdvancedOption, Object)}.
25+
*
26+
* @param <T> The type of value associated with the option.
27+
*/
28+
@SdkPublicApi
29+
public class ServiceMetadataAdvancedOption<T> extends ClientOption<T> {
30+
31+
/**
32+
* The S3 regional endpoint setting for the {@code us-east-1} region. Setting the value to {@code regional} causes
33+
* the SDK to use the {@code s3.us-east-1.amazonaws.com} endpoint when using the {@link Region#US_EAST_1} region instead of
34+
* the global {@code s3.amazonaws.com}. Using the regional endpoint is disabled by default.
35+
*/
36+
public static final ServiceMetadataAdvancedOption<String> S3_US_EAST_1_REGIONAL_ENDPOINT =
37+
new ServiceMetadataAdvancedOption<>(String.class);
38+
39+
protected ServiceMetadataAdvancedOption(Class<T> valueClass) {
40+
super(valueClass);
41+
}
42+
}

core/regions/src/main/java/software/amazon/awssdk/regions/ServiceMetadataConfiguration.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515

1616
package software.amazon.awssdk.regions;
1717

18+
import java.util.Map;
19+
import java.util.Optional;
1820
import java.util.function.Supplier;
1921
import software.amazon.awssdk.annotations.SdkPublicApi;
2022
import software.amazon.awssdk.profiles.ProfileFile;
2123
import software.amazon.awssdk.profiles.ProfileFileSystemSetting;
24+
import software.amazon.awssdk.utils.AttributeMap;
2225

2326
/**
2427
* Configuration for a {@link ServiceMetadata}. This allows modifying the values used by default when a metadata instance is
@@ -30,10 +33,12 @@
3033
public final class ServiceMetadataConfiguration {
3134
private final Supplier<ProfileFile> profileFile;
3235
private final String profileName;
36+
private final AttributeMap advancedOptions;
3337

3438
private ServiceMetadataConfiguration(Builder builder) {
3539
this.profileFile = builder.profileFile;
3640
this.profileName = builder.profileName;
41+
this.advancedOptions = builder.advancedOptions.build();
3742
}
3843

3944
/**
@@ -57,9 +62,19 @@ public String profileName() {
5762
return profileName;
5863
}
5964

65+
/**
66+
* Load the optional requested advanced option that was configured on the service metadata builder.
67+
*
68+
* @see ServiceMetadataConfiguration.Builder#putAdvancedOption(ServiceMetadataAdvancedOption, Object)
69+
*/
70+
public <T> Optional<T> advancedOption(ServiceMetadataAdvancedOption<T> option) {
71+
return Optional.ofNullable(advancedOptions.get(option));
72+
}
73+
6074
public static final class Builder {
6175
private Supplier<ProfileFile> profileFile;
6276
private String profileName;
77+
private AttributeMap.Builder advancedOptions = AttributeMap.builder();
6378

6479
private Builder() {
6580
}
@@ -85,6 +100,24 @@ public Builder profileName(String profileName) {
85100
return this;
86101
}
87102

103+
/**
104+
* Configure the map of advanced override options. This will override all values currently configured. The values in the
105+
* map must match the key type of the map, or a runtime exception will be raised.
106+
*/
107+
public <T> Builder putAdvancedOption(ServiceMetadataAdvancedOption<T> option, T value) {
108+
this.advancedOptions.put(option, value);
109+
return this;
110+
}
111+
112+
/**
113+
* Configure an advanced override option.
114+
* @see ServiceMetadataAdvancedOption
115+
*/
116+
public Builder advancedOptions(Map<ServiceMetadataAdvancedOption<?>, ?> advancedOptions) {
117+
this.advancedOptions.putAll(advancedOptions);
118+
return this;
119+
}
120+
88121
/**
89122
* Build the {@link ServiceMetadata} instance with the updated configuration.
90123
*/

core/regions/src/main/java/software/amazon/awssdk/regions/servicemetadata/EnhancedS3ServiceMetadata.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import software.amazon.awssdk.profiles.ProfileProperty;
2626
import software.amazon.awssdk.regions.Region;
2727
import software.amazon.awssdk.regions.ServiceMetadata;
28+
import software.amazon.awssdk.regions.ServiceMetadataAdvancedOption;
2829
import software.amazon.awssdk.regions.ServiceMetadataConfiguration;
2930
import software.amazon.awssdk.regions.ServicePartitionMetadata;
3031
import software.amazon.awssdk.utils.Lazy;
@@ -53,7 +54,7 @@ private EnhancedS3ServiceMetadata(ServiceMetadataConfiguration config) {
5354
Supplier<String> profileName = config.profileName() != null ? () -> config.profileName()
5455
: ProfileFileSystemSetting.AWS_PROFILE::getStringValueOrThrow;
5556

56-
this.useUsEast1RegionalEndpoint = new Lazy<>(() -> useUsEast1RegionalEndpoint(profileFile, profileName));
57+
this.useUsEast1RegionalEndpoint = new Lazy<>(() -> useUsEast1RegionalEndpoint(profileFile, profileName, config));
5758
this.s3ServiceMetadata = new S3ServiceMetadata().reconfigure(config);
5859
}
5960

@@ -80,7 +81,8 @@ public List<ServicePartitionMetadata> servicePartitions() {
8081
return s3ServiceMetadata.servicePartitions();
8182
}
8283

83-
private boolean useUsEast1RegionalEndpoint(Supplier<ProfileFile> profileFile, Supplier<String> profileName) {
84+
private boolean useUsEast1RegionalEndpoint(Supplier<ProfileFile> profileFile, Supplier<String> profileName,
85+
ServiceMetadataConfiguration config) {
8486
String env = envVarSetting();
8587

8688
if (env != null) {
@@ -93,7 +95,8 @@ private boolean useUsEast1RegionalEndpoint(Supplier<ProfileFile> profileFile, Su
9395
return REGIONAL_SETTING.equalsIgnoreCase(profile);
9496
}
9597

96-
return false;
98+
return config.advancedOption(ServiceMetadataAdvancedOption.S3_US_EAST_1_REGIONAL_ENDPOINT)
99+
.filter(REGIONAL_SETTING::equalsIgnoreCase).isPresent();
97100
}
98101

99102
private static String envVarSetting() {

0 commit comments

Comments
 (0)