Skip to content

Commit 1f46eac

Browse files
authored
chore(codegen): refactor S3 customizations to own class (#1656)
1 parent 9c1c245 commit 1f46eac

File tree

3 files changed

+103
-77
lines changed

3 files changed

+103
-77
lines changed

clients/client-s3/S3Client.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -593,8 +593,8 @@ export type S3ClientConfig = Partial<__SmithyConfiguration<__HttpHandlerOptions>
593593
AwsAuthInputConfig &
594594
RetryInputConfig &
595595
UserAgentInputConfig &
596-
BucketEndpointInputConfig &
597596
HostHeaderInputConfig &
597+
BucketEndpointInputConfig &
598598
EventStreamSerdeInputConfig;
599599

600600
export type S3ClientResolvedConfig = __SmithyResolvedConfiguration<__HttpHandlerOptions> &
@@ -604,8 +604,8 @@ export type S3ClientResolvedConfig = __SmithyResolvedConfiguration<__HttpHandler
604604
AwsAuthResolvedConfig &
605605
RetryResolvedConfig &
606606
UserAgentResolvedConfig &
607-
BucketEndpointResolvedConfig &
608607
HostHeaderResolvedConfig &
608+
BucketEndpointResolvedConfig &
609609
EventStreamSerdeResolvedConfig;
610610

611611
/**
@@ -629,20 +629,20 @@ export class S3Client extends __Client<
629629
let _config_3 = resolveAwsAuthConfig(_config_2);
630630
let _config_4 = resolveRetryConfig(_config_3);
631631
let _config_5 = resolveUserAgentConfig(_config_4);
632-
let _config_6 = resolveBucketEndpointConfig(_config_5);
633-
let _config_7 = resolveHostHeaderConfig(_config_6);
632+
let _config_6 = resolveHostHeaderConfig(_config_5);
633+
let _config_7 = resolveBucketEndpointConfig(_config_6);
634634
let _config_8 = resolveEventStreamSerdeConfig(_config_7);
635635
super(_config_8);
636636
this.config = _config_8;
637637
this.middlewareStack.use(getAwsAuthPlugin(this.config));
638638
this.middlewareStack.use(getRetryPlugin(this.config));
639639
this.middlewareStack.use(getUserAgentPlugin(this.config));
640640
this.middlewareStack.use(getContentLengthPlugin(this.config));
641+
this.middlewareStack.use(getHostHeaderPlugin(this.config));
642+
this.middlewareStack.use(getLoggerPlugin(this.config));
641643
this.middlewareStack.use(getValidateBucketNamePlugin(this.config));
642644
this.middlewareStack.use(getUseRegionalEndpointPlugin(this.config));
643645
this.middlewareStack.use(getAddExpectContinuePlugin(this.config));
644-
this.middlewareStack.use(getHostHeaderPlugin(this.config));
645-
this.middlewareStack.use(getLoggerPlugin(this.config));
646646
}
647647

648648
destroy(): void {

codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddBuiltinPlugins.java

-65
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
*/
4141
public class AddBuiltinPlugins implements TypeScriptIntegration {
4242

43-
private static final Set<String> SSEC_OPERATIONS = SetUtils.of("SSECustomerKey", "CopySourceSSECustomerKey");
44-
4543
private static final Set<String> ROUTE_53_ID_MEMBERS = SetUtils.of("DelegationSetId", "HostedZoneId", "Id");
4644

4745
private static final Set<String> RDS_PRESIGNED_URL_OPERATIONS = SetUtils.of(
@@ -51,22 +49,6 @@ public class AddBuiltinPlugins implements TypeScriptIntegration {
5149
"CopyDBClusterSnapshot"
5250
);
5351

54-
private static final Set<String> S3_MD5_OPERATIONS = SetUtils.of(
55-
"DeleteObjects",
56-
"PutBucketCors",
57-
"PutBucketLifecycle",
58-
"PutBucketLifecycleConfiguration",
59-
"PutBucketPolicy",
60-
"PutBucketTagging",
61-
"PutBucketReplication"
62-
);
63-
64-
private static final Set<String> NON_BUCKET_ENDPOINT_OPERATIONS = SetUtils.of(
65-
"CreateBucket",
66-
"DeleteBucket",
67-
"ListBuckets"
68-
);
69-
7052
@Override
7153
public List<RuntimeClientPlugin> getClientPlugins() {
7254
// Note that order is significant because configurations might
@@ -102,21 +84,6 @@ public List<RuntimeClientPlugin> getClientPlugins() {
10284
HAS_MIDDLEWARE)
10385
.servicePredicate((m, s) -> testServiceId(s, "API Gateway"))
10486
.build(),
105-
RuntimeClientPlugin.builder()
106-
.withConventions(AwsDependency.S3_MIDDLEWARE.dependency, "ValidateBucketName",
107-
HAS_MIDDLEWARE)
108-
.servicePredicate((m, s) -> testServiceId(s, "S3"))
109-
.build(),
110-
RuntimeClientPlugin.builder()
111-
.withConventions(AwsDependency.S3_MIDDLEWARE.dependency, "UseRegionalEndpoint",
112-
HAS_MIDDLEWARE)
113-
.servicePredicate((m, s) -> testServiceId(s, "S3"))
114-
.build(),
115-
RuntimeClientPlugin.builder()
116-
.withConventions(AwsDependency.ADD_EXPECT_CONTINUE.dependency, "AddExpectContinue",
117-
HAS_MIDDLEWARE)
118-
.servicePredicate((m, s) -> testServiceId(s, "S3"))
119-
.build(),
12087
RuntimeClientPlugin.builder()
12188
.withConventions(AwsDependency.GLACIER_MIDDLEWARE.dependency,
12289
"Glacier", HAS_MIDDLEWARE)
@@ -128,44 +95,12 @@ public List<RuntimeClientPlugin> getClientPlugins() {
12895
.operationPredicate((m, s, o) -> o.getId().getName().equals("CopySnapshot")
12996
&& testServiceId(s, "EC2"))
13097
.build(),
131-
RuntimeClientPlugin.builder()
132-
.withConventions(AwsDependency.SSEC_MIDDLEWARE.dependency, "Ssec", HAS_MIDDLEWARE)
133-
.operationPredicate((m, s, o) -> testInputContainsMember(m, o, SSEC_OPERATIONS)
134-
&& testServiceId(s, "S3"))
135-
.build(),
136-
RuntimeClientPlugin.builder()
137-
.withConventions(AwsDependency.LOCATION_CONSTRAINT.dependency, "LocationConstraint",
138-
HAS_MIDDLEWARE)
139-
.operationPredicate((m, s, o) -> o.getId().getName().equals("CreateBucket")
140-
&& testServiceId(s, "S3"))
141-
.build(),
14298
RuntimeClientPlugin.builder()
14399
.withConventions(AwsDependency.MACHINELEARNING_MIDDLEWARE.dependency, "PredictEndpoint",
144100
HAS_MIDDLEWARE)
145101
.operationPredicate((m, s, o) -> o.getId().getName().equals("Predict")
146102
&& testServiceId(s, "Machine Learning"))
147103
.build(),
148-
/**
149-
* BUCKET_ENDPOINT_MIDDLEWARE needs two separate plugins. The first resolves the config in the client.
150-
* The second applies the middleware to bucket endpoint operations.
151-
*/
152-
RuntimeClientPlugin.builder()
153-
.withConventions(AwsDependency.BUCKET_ENDPOINT_MIDDLEWARE.dependency, "BucketEndpoint",
154-
HAS_CONFIG)
155-
.servicePredicate((m, s) -> testServiceId(s, "S3"))
156-
.build(),
157-
RuntimeClientPlugin.builder()
158-
.withConventions(AwsDependency.BUCKET_ENDPOINT_MIDDLEWARE.dependency, "BucketEndpoint",
159-
HAS_MIDDLEWARE)
160-
.operationPredicate((m, s, o) -> !NON_BUCKET_ENDPOINT_OPERATIONS.contains(o.getId().getName())
161-
&& testServiceId(s, "S3"))
162-
.build(),
163-
RuntimeClientPlugin.builder()
164-
.withConventions(AwsDependency.BODY_CHECKSUM.dependency, "ApplyMd5BodyChecksum",
165-
HAS_MIDDLEWARE)
166-
.operationPredicate((m, s, o) -> S3_MD5_OPERATIONS.contains(o.getId().getName())
167-
&& testServiceId(s, "S3"))
168-
.build(),
169104
RuntimeClientPlugin.builder()
170105
.withConventions(AwsDependency.ROUTE53_MIDDLEWARE.dependency,
171106
"ChangeResourceRecordSets", HAS_MIDDLEWARE)

codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3Config.java

+97-6
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,58 @@
1515

1616
package software.amazon.smithy.aws.typescript.codegen;
1717

18+
import static software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin.Convention.HAS_CONFIG;
19+
import static software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin.Convention.HAS_MIDDLEWARE;
20+
1821
import java.util.Collections;
22+
import java.util.List;
1923
import java.util.Map;
24+
import java.util.Set;
2025
import java.util.function.Consumer;
2126

2227
import software.amazon.smithy.aws.traits.ServiceTrait;
2328
import software.amazon.smithy.codegen.core.SymbolProvider;
2429
import software.amazon.smithy.model.Model;
25-
import software.amazon.smithy.model.shapes.ServiceShape;
30+
import software.amazon.smithy.model.knowledge.OperationIndex;
31+
import software.amazon.smithy.model.shapes.OperationShape;
32+
import software.amazon.smithy.model.shapes.Shape;
2633
import software.amazon.smithy.typescript.codegen.LanguageTarget;
2734
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
2835
import software.amazon.smithy.typescript.codegen.TypeScriptSettings;
2936
import software.amazon.smithy.typescript.codegen.TypeScriptWriter;
37+
import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin;
3038
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
39+
import software.amazon.smithy.utils.ListUtils;
3140
import software.amazon.smithy.utils.MapUtils;
41+
import software.amazon.smithy.utils.SetUtils;
3242

3343
/**
3444
* AWS S3 client configuration.
3545
*/
3646
public final class AddS3Config implements TypeScriptIntegration {
3747

48+
private static final Set<String> S3_MD5_OPERATIONS = SetUtils.of(
49+
"DeleteObjects",
50+
"PutBucketCors",
51+
"PutBucketLifecycle",
52+
"PutBucketLifecycleConfiguration",
53+
"PutBucketPolicy",
54+
"PutBucketTagging",
55+
"PutBucketReplication"
56+
);
57+
58+
private static final Set<String> SSEC_OPERATIONS = SetUtils.of("SSECustomerKey", "CopySourceSSECustomerKey");
59+
60+
private static final Set<String> NON_BUCKET_ENDPOINT_OPERATIONS = SetUtils.of(
61+
"CreateBucket",
62+
"DeleteBucket",
63+
"ListBuckets"
64+
);
65+
3866
@Override
3967
public void addConfigInterfaceFields(TypeScriptSettings settings, Model model, SymbolProvider symbolProvider,
4068
TypeScriptWriter writer) {
41-
if (!needsS3Config(settings.getService(model))) {
69+
if (!testServiceId(settings.getService(model))) {
4270
return;
4371
}
4472
writer.writeDocs("Whether to escape request path when signing the request.")
@@ -53,7 +81,7 @@ public void addConfigInterfaceFields(TypeScriptSettings settings, Model model, S
5381
@Override
5482
public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(TypeScriptSettings settings, Model model,
5583
SymbolProvider symbolProvider, LanguageTarget target) {
56-
if (!needsS3Config(settings.getService(model))) {
84+
if (!testServiceId(settings.getService(model))) {
5785
return Collections.emptyMap();
5886
}
5987
switch (target) {
@@ -77,8 +105,71 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(TypeScrip
77105
}
78106
}
79107

80-
private static boolean needsS3Config(ServiceShape service) {
81-
String serviceId = service.getTrait(ServiceTrait.class).map(ServiceTrait::getSdkId).orElse("");
82-
return serviceId.equals("S3");
108+
@Override
109+
public List<RuntimeClientPlugin> getClientPlugins() {
110+
return ListUtils.of(
111+
RuntimeClientPlugin.builder()
112+
.withConventions(AwsDependency.S3_MIDDLEWARE.dependency, "ValidateBucketName",
113+
HAS_MIDDLEWARE)
114+
.servicePredicate((m, s) -> testServiceId(s))
115+
.build(),
116+
RuntimeClientPlugin.builder()
117+
.withConventions(AwsDependency.S3_MIDDLEWARE.dependency, "UseRegionalEndpoint",
118+
HAS_MIDDLEWARE)
119+
.servicePredicate((m, s) -> testServiceId(s))
120+
.build(),
121+
RuntimeClientPlugin.builder()
122+
.withConventions(AwsDependency.ADD_EXPECT_CONTINUE.dependency, "AddExpectContinue",
123+
HAS_MIDDLEWARE)
124+
.servicePredicate((m, s) -> testServiceId(s))
125+
.build(),
126+
RuntimeClientPlugin.builder()
127+
.withConventions(AwsDependency.SSEC_MIDDLEWARE.dependency, "Ssec", HAS_MIDDLEWARE)
128+
.operationPredicate((m, s, o) -> testInputContainsMember(m, o, SSEC_OPERATIONS)
129+
&& testServiceId(s))
130+
.build(),
131+
RuntimeClientPlugin.builder()
132+
.withConventions(AwsDependency.LOCATION_CONSTRAINT.dependency, "LocationConstraint",
133+
HAS_MIDDLEWARE)
134+
.operationPredicate((m, s, o) -> o.getId().getName().equals("CreateBucket")
135+
&& testServiceId(s))
136+
.build(),
137+
/**
138+
* BUCKET_ENDPOINT_MIDDLEWARE needs two separate plugins. The first resolves the config in the client.
139+
* The second applies the middleware to bucket endpoint operations.
140+
*/
141+
RuntimeClientPlugin.builder()
142+
.withConventions(AwsDependency.BUCKET_ENDPOINT_MIDDLEWARE.dependency, "BucketEndpoint",
143+
HAS_CONFIG)
144+
.servicePredicate((m, s) -> testServiceId(s))
145+
.build(),
146+
RuntimeClientPlugin.builder()
147+
.withConventions(AwsDependency.BUCKET_ENDPOINT_MIDDLEWARE.dependency, "BucketEndpoint",
148+
HAS_MIDDLEWARE)
149+
.operationPredicate((m, s, o) -> !NON_BUCKET_ENDPOINT_OPERATIONS.contains(o.getId().getName())
150+
&& testServiceId(s))
151+
.build(),
152+
RuntimeClientPlugin.builder()
153+
.withConventions(AwsDependency.BODY_CHECKSUM.dependency, "ApplyMd5BodyChecksum",
154+
HAS_MIDDLEWARE)
155+
.operationPredicate((m, s, o) -> S3_MD5_OPERATIONS.contains(o.getId().getName())
156+
&& testServiceId(s))
157+
.build()
158+
);
159+
}
160+
161+
private static boolean testInputContainsMember(
162+
Model model,
163+
OperationShape operationShape,
164+
Set<String> expectedMemberNames
165+
) {
166+
OperationIndex operationIndex = OperationIndex.of(model);
167+
return operationIndex.getInput(operationShape)
168+
.filter(input -> input.getMemberNames().stream().anyMatch(expectedMemberNames::contains))
169+
.isPresent();
170+
}
171+
172+
private static boolean testServiceId(Shape serviceShape) {
173+
return serviceShape.getTrait(ServiceTrait.class).map(ServiceTrait::getSdkId).orElse("").equals("S3");
83174
}
84175
}

0 commit comments

Comments
 (0)