Skip to content

Commit cd7358a

Browse files
authored
Support S3 endpoint providers (#3443)
This adds support for using the endpoint providers in the S3 client.
1 parent d69423f commit cd7358a

File tree

20 files changed

+16773
-1486
lines changed

20 files changed

+16773
-1486
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/poet/rules/RuleSetCreationSpec.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ public CodeBlock ruleSetCreationExpr() {
7070
CodeBlock.Builder b = CodeBlock.builder();
7171

7272
b.add("$T.builder()", EndpointRuleset.class)
73-
.add(".version($S)", ruleSetModel.getVersion())
74-
.add(".serviceId($S)", ruleSetModel.getServiceId())
73+
.add(".version($S)", ruleSetModel.getVersion())
74+
.add(".serviceId($S)", ruleSetModel.getServiceId())
7575
.add(".parameters($L)", parameters(ruleSetModel.getParameters()));
7676

7777
ruleSetModel.getRules().stream()

codegen/src/main/java/software/amazon/awssdk/codegen/poet/rules/TestGeneratorUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ private static CodeBlock authSchemeCreationExpr(TreeNode attrValue) {
139139
schemeExpr.add(".signingRegion($S)", ((JrsString) memberValue).getValue());
140140
break;
141141
case "disableDoubleEncoding":
142-
schemeExpr.add(".disableDoubleEncoding($S)", ((JrsBoolean) memberValue).booleanValue());
142+
schemeExpr.add(".disableDoubleEncoding($L)", ((JrsBoolean) memberValue).booleanValue());
143143
break;
144144
case "signingRegionSet": {
145145
JrsArray regions = (JrsArray) memberValue;

core/aws-core/src/main/java/software/amazon/awssdk/awscore/rules/AwsProviderUtils.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import software.amazon.awssdk.http.SdkHttpRequest;
3232
import software.amazon.awssdk.regions.Region;
3333
import software.amazon.awssdk.utils.Logger;
34+
import software.amazon.awssdk.utils.StringUtils;
3435

3536
@SdkInternalApi
3637
public final class AwsProviderUtils {
@@ -105,10 +106,12 @@ public static SdkHttpRequest setUri(SdkHttpRequest request, URI newUri) {
105106
String newPath = newUri.getRawPath();
106107
String existingPath = request.getUri().getRawPath();
107108

108-
if (newPath.endsWith("/") || existingPath.startsWith("/")) {
109-
newPath += existingPath;
110-
} else {
111-
newPath = newPath + "/" + existingPath;
109+
if (StringUtils.isNotBlank(existingPath)) {
110+
if (newPath.endsWith("/") || existingPath.startsWith("/")) {
111+
newPath += existingPath;
112+
} else {
113+
newPath = newPath + "/" + existingPath;
114+
}
112115
}
113116

114117
return request.toBuilder()

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ public boolean multiRegionEnabled() {
205205
public Builder toBuilder() {
206206
return builder()
207207
.dualstackEnabled(dualstackEnabled.valueOrNullIfDefault())
208+
.multiRegionEnabled(multiRegionEnabled.valueOrNullIfDefault())
208209
.accelerateModeEnabled(accelerateModeEnabled.valueOrNullIfDefault())
209210
.pathStyleAccessEnabled(pathStyleAccessEnabled.valueOrNullIfDefault())
210211
.checksumValidationEnabled(checksumValidationEnabled.valueOrNullIfDefault())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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.internal.endpoints;
17+
18+
import java.util.function.Supplier;
19+
import software.amazon.awssdk.annotations.SdkInternalApi;
20+
import software.amazon.awssdk.awscore.client.config.AwsClientOption;
21+
import software.amazon.awssdk.core.SdkSystemSetting;
22+
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
23+
import software.amazon.awssdk.core.client.config.SdkClientOption;
24+
import software.amazon.awssdk.profiles.ProfileFile;
25+
import software.amazon.awssdk.profiles.ProfileProperty;
26+
import software.amazon.awssdk.regions.Region;
27+
import software.amazon.awssdk.regions.ServiceMetadataAdvancedOption;
28+
import software.amazon.awssdk.utils.Lazy;
29+
import software.amazon.awssdk.utils.Logger;
30+
31+
/**
32+
* Note: Most of the logic is copied from EnhancedS3ServiceMetadata
33+
* // TODO: should probably refactor that class to reuse the same logic
34+
*/
35+
@SdkInternalApi
36+
public class UseGlobalEndpointResolver {
37+
private static final Logger LOG = Logger.loggerFor(UseGlobalEndpointResolver.class);
38+
private static final String REGIONAL_SETTING = "regional";
39+
private final Lazy<Boolean> useUsEast1RegionalEndpoint;
40+
private final SdkClientConfiguration sdkClientConfiguration;
41+
42+
public UseGlobalEndpointResolver(SdkClientConfiguration config) {
43+
sdkClientConfiguration = config;
44+
String defaultS3UsEast1RegionalEndpointFromSmartDefaults =
45+
config.option(ServiceMetadataAdvancedOption.DEFAULT_S3_US_EAST_1_REGIONAL_ENDPOINT);
46+
this.useUsEast1RegionalEndpoint =
47+
new Lazy<>(() -> useUsEast1RegionalEndpoint(() ->config.option(SdkClientOption.PROFILE_FILE),
48+
() -> config.option(SdkClientOption.PROFILE_NAME),
49+
defaultS3UsEast1RegionalEndpointFromSmartDefaults));
50+
}
51+
52+
public boolean resolve() {
53+
if (!Region.US_EAST_1.equals(sdkClientConfiguration.option(AwsClientOption.AWS_REGION))) {
54+
return false;
55+
}
56+
57+
return !useUsEast1RegionalEndpoint.getValue();
58+
}
59+
60+
private boolean useUsEast1RegionalEndpoint(Supplier<ProfileFile> profileFile, Supplier<String> profileName,
61+
String defaultS3UsEast1RegionalEndpoint) {
62+
63+
String env = envVarSetting();
64+
65+
if (env != null) {
66+
return REGIONAL_SETTING.equalsIgnoreCase(env);
67+
}
68+
69+
String profile = profileFileSetting(profileFile, profileName);
70+
71+
if (profile != null) {
72+
return REGIONAL_SETTING.equalsIgnoreCase(profile);
73+
}
74+
75+
return REGIONAL_SETTING.equalsIgnoreCase(defaultS3UsEast1RegionalEndpoint);
76+
}
77+
78+
79+
private static String envVarSetting() {
80+
return SdkSystemSetting.AWS_S3_US_EAST_1_REGIONAL_ENDPOINT.getStringValue().orElse(null);
81+
}
82+
83+
private String profileFileSetting(Supplier<ProfileFile> profileFileSupplier, Supplier<String> profileNameSupplier) {
84+
try {
85+
ProfileFile profileFile = profileFileSupplier.get();
86+
String profileName = profileNameSupplier.get();
87+
if (profileFile == null || profileName == null) {
88+
return null;
89+
}
90+
return profileFile.profile(profileName)
91+
.flatMap(p -> p.property(ProfileProperty.S3_US_EAST_1_REGIONAL_ENDPOINT))
92+
.orElse(null);
93+
} catch (Exception t) {
94+
LOG.warn(() -> "Unable to load config file", t);
95+
return null;
96+
}
97+
}
98+
99+
}

services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/handlers/EndpointAddressInterceptor.java

Lines changed: 0 additions & 86 deletions
This file was deleted.
Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,27 @@
1515

1616
package software.amazon.awssdk.services.s3.internal.handlers;
1717

18-
import static software.amazon.awssdk.awscore.util.SignerOverrideUtils.overrideSignerIfNotOverridden;
19-
20-
import software.amazon.awssdk.annotations.SdkInternalApi;
21-
import software.amazon.awssdk.core.SdkRequest;
2218
import software.amazon.awssdk.core.interceptor.Context;
2319
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
2420
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
25-
import software.amazon.awssdk.services.s3.internal.signing.S3SigningUtils;
26-
import software.amazon.awssdk.services.s3.model.S3Request;
21+
import software.amazon.awssdk.http.SdkHttpRequest;
22+
import software.amazon.awssdk.utils.StringUtils;
23+
import software.amazon.awssdk.utils.http.SdkHttpUtils;
2724

28-
@SdkInternalApi
29-
public final class SignerOverrideInterceptor implements ExecutionInterceptor {
25+
public class RemoveBucketFromPathInterceptor implements ExecutionInterceptor {
3026

3127
@Override
32-
public SdkRequest modifyRequest(Context.ModifyRequest context, ExecutionAttributes executionAttributes) {
33-
return S3SigningUtils.internalSignerOverride((S3Request) context.request())
34-
.map(signer -> overrideSignerIfNotOverridden(context.request(), executionAttributes, signer))
35-
.orElseGet(context::request);
36-
}
28+
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
29+
String bucketName = context.request().getValueForField("Bucket", String.class).orElse(null);
30+
31+
if (bucketName == null) {
32+
return context.httpRequest();
33+
}
3734

35+
SdkHttpRequest.Builder mutableRequest = context.httpRequest().toBuilder();
36+
String encodedBucket = SdkHttpUtils.urlEncode(bucketName);
37+
String newPath = StringUtils.replaceOnce(mutableRequest.encodedPath(), "/" + encodedBucket, "");
38+
39+
return mutableRequest.encodedPath(newPath).build();
40+
}
3841
}

services/s3/src/main/resources/codegen-resources/customization.config

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,11 @@
127127
},
128128
"serviceConfig": {
129129
"className": "S3Configuration",
130-
"hasDualstackProperty": true
130+
"hasDualstackProperty": true,
131+
"hasUseArnRegionProperty": true,
132+
"hasMultiRegionEnabledProperty": true,
133+
"hasPathStyleAccessEnabledProperty":true,
134+
"hasAccelerateModeEnabledProperty":true
131135
},
132136
"attachPayloadTraitToMember": {
133137
"GetBucketLocationOutput": "LocationConstraint"
@@ -172,5 +176,7 @@
172176
"clientConfiguration"
173177
]
174178
},
175-
"delegateAsyncClientClass": true
179+
"delegateAsyncClientClass": true,
180+
"useGlobalEndpoint": true
181+
}
176182
}

0 commit comments

Comments
 (0)