diff --git a/clients/client-s3/S3Client.ts b/clients/client-s3/S3Client.ts index 0b408bae235f..f8f073ef8c81 100644 --- a/clients/client-s3/S3Client.ts +++ b/clients/client-s3/S3Client.ts @@ -593,8 +593,8 @@ export type S3ClientConfig = Partial<__SmithyConfiguration<__HttpHandlerOptions> AwsAuthInputConfig & RetryInputConfig & UserAgentInputConfig & - BucketEndpointInputConfig & HostHeaderInputConfig & + BucketEndpointInputConfig & EventStreamSerdeInputConfig; export type S3ClientResolvedConfig = __SmithyResolvedConfiguration<__HttpHandlerOptions> & @@ -604,8 +604,8 @@ export type S3ClientResolvedConfig = __SmithyResolvedConfiguration<__HttpHandler AwsAuthResolvedConfig & RetryResolvedConfig & UserAgentResolvedConfig & - BucketEndpointResolvedConfig & HostHeaderResolvedConfig & + BucketEndpointResolvedConfig & EventStreamSerdeResolvedConfig; /** @@ -629,8 +629,8 @@ export class S3Client extends __Client< let _config_3 = resolveAwsAuthConfig(_config_2); let _config_4 = resolveRetryConfig(_config_3); let _config_5 = resolveUserAgentConfig(_config_4); - let _config_6 = resolveBucketEndpointConfig(_config_5); - let _config_7 = resolveHostHeaderConfig(_config_6); + let _config_6 = resolveHostHeaderConfig(_config_5); + let _config_7 = resolveBucketEndpointConfig(_config_6); let _config_8 = resolveEventStreamSerdeConfig(_config_7); super(_config_8); this.config = _config_8; @@ -638,11 +638,11 @@ export class S3Client extends __Client< this.middlewareStack.use(getRetryPlugin(this.config)); this.middlewareStack.use(getUserAgentPlugin(this.config)); this.middlewareStack.use(getContentLengthPlugin(this.config)); + this.middlewareStack.use(getHostHeaderPlugin(this.config)); + this.middlewareStack.use(getLoggerPlugin(this.config)); this.middlewareStack.use(getValidateBucketNamePlugin(this.config)); this.middlewareStack.use(getUseRegionalEndpointPlugin(this.config)); this.middlewareStack.use(getAddExpectContinuePlugin(this.config)); - this.middlewareStack.use(getHostHeaderPlugin(this.config)); - this.middlewareStack.use(getLoggerPlugin(this.config)); } destroy(): void { diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddBuiltinPlugins.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddBuiltinPlugins.java index 1b84ec0911fc..e75164def5e9 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddBuiltinPlugins.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddBuiltinPlugins.java @@ -40,8 +40,6 @@ */ public class AddBuiltinPlugins implements TypeScriptIntegration { - private static final Set SSEC_OPERATIONS = SetUtils.of("SSECustomerKey", "CopySourceSSECustomerKey"); - private static final Set ROUTE_53_ID_MEMBERS = SetUtils.of("DelegationSetId", "HostedZoneId", "Id"); private static final Set RDS_PRESIGNED_URL_OPERATIONS = SetUtils.of( @@ -51,22 +49,6 @@ public class AddBuiltinPlugins implements TypeScriptIntegration { "CopyDBClusterSnapshot" ); - private static final Set S3_MD5_OPERATIONS = SetUtils.of( - "DeleteObjects", - "PutBucketCors", - "PutBucketLifecycle", - "PutBucketLifecycleConfiguration", - "PutBucketPolicy", - "PutBucketTagging", - "PutBucketReplication" - ); - - private static final Set NON_BUCKET_ENDPOINT_OPERATIONS = SetUtils.of( - "CreateBucket", - "DeleteBucket", - "ListBuckets" - ); - @Override public List getClientPlugins() { // Note that order is significant because configurations might @@ -102,21 +84,6 @@ public List getClientPlugins() { HAS_MIDDLEWARE) .servicePredicate((m, s) -> testServiceId(s, "API Gateway")) .build(), - RuntimeClientPlugin.builder() - .withConventions(AwsDependency.S3_MIDDLEWARE.dependency, "ValidateBucketName", - HAS_MIDDLEWARE) - .servicePredicate((m, s) -> testServiceId(s, "S3")) - .build(), - RuntimeClientPlugin.builder() - .withConventions(AwsDependency.S3_MIDDLEWARE.dependency, "UseRegionalEndpoint", - HAS_MIDDLEWARE) - .servicePredicate((m, s) -> testServiceId(s, "S3")) - .build(), - RuntimeClientPlugin.builder() - .withConventions(AwsDependency.ADD_EXPECT_CONTINUE.dependency, "AddExpectContinue", - HAS_MIDDLEWARE) - .servicePredicate((m, s) -> testServiceId(s, "S3")) - .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.GLACIER_MIDDLEWARE.dependency, "Glacier", HAS_MIDDLEWARE) @@ -128,44 +95,12 @@ public List getClientPlugins() { .operationPredicate((m, s, o) -> o.getId().getName().equals("CopySnapshot") && testServiceId(s, "EC2")) .build(), - RuntimeClientPlugin.builder() - .withConventions(AwsDependency.SSEC_MIDDLEWARE.dependency, "Ssec", HAS_MIDDLEWARE) - .operationPredicate((m, s, o) -> testInputContainsMember(m, o, SSEC_OPERATIONS) - && testServiceId(s, "S3")) - .build(), - RuntimeClientPlugin.builder() - .withConventions(AwsDependency.LOCATION_CONSTRAINT.dependency, "LocationConstraint", - HAS_MIDDLEWARE) - .operationPredicate((m, s, o) -> o.getId().getName().equals("CreateBucket") - && testServiceId(s, "S3")) - .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.MACHINELEARNING_MIDDLEWARE.dependency, "PredictEndpoint", HAS_MIDDLEWARE) .operationPredicate((m, s, o) -> o.getId().getName().equals("Predict") && testServiceId(s, "Machine Learning")) .build(), - /** - * BUCKET_ENDPOINT_MIDDLEWARE needs two separate plugins. The first resolves the config in the client. - * The second applies the middleware to bucket endpoint operations. - */ - RuntimeClientPlugin.builder() - .withConventions(AwsDependency.BUCKET_ENDPOINT_MIDDLEWARE.dependency, "BucketEndpoint", - HAS_CONFIG) - .servicePredicate((m, s) -> testServiceId(s, "S3")) - .build(), - RuntimeClientPlugin.builder() - .withConventions(AwsDependency.BUCKET_ENDPOINT_MIDDLEWARE.dependency, "BucketEndpoint", - HAS_MIDDLEWARE) - .operationPredicate((m, s, o) -> !NON_BUCKET_ENDPOINT_OPERATIONS.contains(o.getId().getName()) - && testServiceId(s, "S3")) - .build(), - RuntimeClientPlugin.builder() - .withConventions(AwsDependency.BODY_CHECKSUM.dependency, "ApplyMd5BodyChecksum", - HAS_MIDDLEWARE) - .operationPredicate((m, s, o) -> S3_MD5_OPERATIONS.contains(o.getId().getName()) - && testServiceId(s, "S3")) - .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.ROUTE53_MIDDLEWARE.dependency, "ChangeResourceRecordSets", HAS_MIDDLEWARE) diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3Config.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3Config.java index 083f853b7dea..d81af213f89c 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3Config.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3Config.java @@ -15,30 +15,58 @@ package software.amazon.smithy.aws.typescript.codegen; +import static software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin.Convention.HAS_CONFIG; +import static software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin.Convention.HAS_MIDDLEWARE; + import java.util.Collections; +import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Consumer; import software.amazon.smithy.aws.traits.ServiceTrait; import software.amazon.smithy.codegen.core.SymbolProvider; import software.amazon.smithy.model.Model; -import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.knowledge.OperationIndex; +import software.amazon.smithy.model.shapes.OperationShape; +import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.typescript.codegen.LanguageTarget; import software.amazon.smithy.typescript.codegen.TypeScriptDependency; import software.amazon.smithy.typescript.codegen.TypeScriptSettings; import software.amazon.smithy.typescript.codegen.TypeScriptWriter; +import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin; import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration; +import software.amazon.smithy.utils.ListUtils; import software.amazon.smithy.utils.MapUtils; +import software.amazon.smithy.utils.SetUtils; /** * AWS S3 client configuration. */ public final class AddS3Config implements TypeScriptIntegration { + private static final Set S3_MD5_OPERATIONS = SetUtils.of( + "DeleteObjects", + "PutBucketCors", + "PutBucketLifecycle", + "PutBucketLifecycleConfiguration", + "PutBucketPolicy", + "PutBucketTagging", + "PutBucketReplication" + ); + + private static final Set SSEC_OPERATIONS = SetUtils.of("SSECustomerKey", "CopySourceSSECustomerKey"); + + private static final Set NON_BUCKET_ENDPOINT_OPERATIONS = SetUtils.of( + "CreateBucket", + "DeleteBucket", + "ListBuckets" + ); + @Override public void addConfigInterfaceFields(TypeScriptSettings settings, Model model, SymbolProvider symbolProvider, TypeScriptWriter writer) { - if (!needsS3Config(settings.getService(model))) { + if (!testServiceId(settings.getService(model))) { return; } writer.writeDocs("Whether to escape request path when signing the request.") @@ -53,7 +81,7 @@ public void addConfigInterfaceFields(TypeScriptSettings settings, Model model, S @Override public Map> getRuntimeConfigWriters(TypeScriptSettings settings, Model model, SymbolProvider symbolProvider, LanguageTarget target) { - if (!needsS3Config(settings.getService(model))) { + if (!testServiceId(settings.getService(model))) { return Collections.emptyMap(); } switch (target) { @@ -77,8 +105,71 @@ public Map> getRuntimeConfigWriters(TypeScrip } } - private static boolean needsS3Config(ServiceShape service) { - String serviceId = service.getTrait(ServiceTrait.class).map(ServiceTrait::getSdkId).orElse(""); - return serviceId.equals("S3"); + @Override + public List getClientPlugins() { + return ListUtils.of( + RuntimeClientPlugin.builder() + .withConventions(AwsDependency.S3_MIDDLEWARE.dependency, "ValidateBucketName", + HAS_MIDDLEWARE) + .servicePredicate((m, s) -> testServiceId(s)) + .build(), + RuntimeClientPlugin.builder() + .withConventions(AwsDependency.S3_MIDDLEWARE.dependency, "UseRegionalEndpoint", + HAS_MIDDLEWARE) + .servicePredicate((m, s) -> testServiceId(s)) + .build(), + RuntimeClientPlugin.builder() + .withConventions(AwsDependency.ADD_EXPECT_CONTINUE.dependency, "AddExpectContinue", + HAS_MIDDLEWARE) + .servicePredicate((m, s) -> testServiceId(s)) + .build(), + RuntimeClientPlugin.builder() + .withConventions(AwsDependency.SSEC_MIDDLEWARE.dependency, "Ssec", HAS_MIDDLEWARE) + .operationPredicate((m, s, o) -> testInputContainsMember(m, o, SSEC_OPERATIONS) + && testServiceId(s)) + .build(), + RuntimeClientPlugin.builder() + .withConventions(AwsDependency.LOCATION_CONSTRAINT.dependency, "LocationConstraint", + HAS_MIDDLEWARE) + .operationPredicate((m, s, o) -> o.getId().getName().equals("CreateBucket") + && testServiceId(s)) + .build(), + /** + * BUCKET_ENDPOINT_MIDDLEWARE needs two separate plugins. The first resolves the config in the client. + * The second applies the middleware to bucket endpoint operations. + */ + RuntimeClientPlugin.builder() + .withConventions(AwsDependency.BUCKET_ENDPOINT_MIDDLEWARE.dependency, "BucketEndpoint", + HAS_CONFIG) + .servicePredicate((m, s) -> testServiceId(s)) + .build(), + RuntimeClientPlugin.builder() + .withConventions(AwsDependency.BUCKET_ENDPOINT_MIDDLEWARE.dependency, "BucketEndpoint", + HAS_MIDDLEWARE) + .operationPredicate((m, s, o) -> !NON_BUCKET_ENDPOINT_OPERATIONS.contains(o.getId().getName()) + && testServiceId(s)) + .build(), + RuntimeClientPlugin.builder() + .withConventions(AwsDependency.BODY_CHECKSUM.dependency, "ApplyMd5BodyChecksum", + HAS_MIDDLEWARE) + .operationPredicate((m, s, o) -> S3_MD5_OPERATIONS.contains(o.getId().getName()) + && testServiceId(s)) + .build() + ); + } + + private static boolean testInputContainsMember( + Model model, + OperationShape operationShape, + Set expectedMemberNames + ) { + OperationIndex operationIndex = OperationIndex.of(model); + return operationIndex.getInput(operationShape) + .filter(input -> input.getMemberNames().stream().anyMatch(expectedMemberNames::contains)) + .isPresent(); + } + + private static boolean testServiceId(Shape serviceShape) { + return serviceShape.getTrait(ServiceTrait.class).map(ServiceTrait::getSdkId).orElse("").equals("S3"); } }