Unverified Commit 275baef7 authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Add presigned request support for Polly (#735)

* Split out MakeOperationGenerator for HttpProtocolGenerator

* Clean up body metadata calculation

* Add debug instructions to readme

* Add example for Polly presigned requests

* Add ability to change payload signing type for query signing

* Generate special cased make operation functions for presigning

* Reorganize protocol generators

* Rename ProtocolConfig to CodegenContext and move to a central location

* Consolidate protocol classes in protocols package

* Make protocol generator names consistent

* Fully decompose ProtocolGenerator

* Add integration test for Polly presigning

* Add make_operation and presigned to reserved words

* Update presigning RFC

* Make Polly transforms reusable and add tests

* Fix RequestBindingGeneratorTest

* Update changelogs

* Remove `HttpBodySigningType`

* Perform model transformations up front

* Add checks to presigning transformers

* Fix `codegen-server` build
parent 9d3bad7e
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -2,6 +2,12 @@ vNext (Month Day, Year)
=======================
**Breaking changes**
- :warning: MSRV increased from 1.52.1 to 1.53.0 per our 3-behind MSRV policy.
- :warning: Several classes in the codegen module were renamed and/or refactored (smithy-rs#735):
  - `ProtocolConfig` became `CodegenContext` and moved to `software.amazon.smithy.rust.codegen.smithy`
  - `HttpProtocolGenerator` became `ProtocolGenerator` and was refactored
    to rely on composition instead of inheritance
  - `HttpProtocolTestGenerator` became `ProtocolTestGenerator`
  - `Protocol` moved into `software.amazon.smithy.rust.codegen.smithy.protocols`

**New this week**
- :bug: Fix an issue where `smithy-xml` may have generated invalid XML (smithy-rs#719)
+3 −1
Original line number Diff line number Diff line
vNext (Month Day, Year)
=======================

**Breaking changes**
- :warning: MSRV increased from 1.52.1 to 1.53.0 per our 3-behind MSRV policy.

@@ -8,7 +9,8 @@ vNext (Month Day, Year)

**New This Week**

- :tada: Add presigned request support and examples for S3 GetObject and PutObject (smithy-rs#731)
- :tada: Add presigned request support and examples for S3 GetObject and PutObject (smithy-rs#731, aws-sdk-rust#139)
- :tada: Add presigned request support and example for Polly SynthesizeSpeech (smithy-rs#735, aws-sdk-rust#139)
- :bug: Fix error when receiving `Cont` event from S3 SelectObjectContent (smithy-rs#736)
- :bug: Fix bug in event stream receiver that could cause the last events in the response stream to be lost when using S3 SelectObjectContent (smithy-rs#736)
- Updated Transcribe code example to take an audio file as a command-line option and added readme.
+13 −18
Original line number Diff line number Diff line
@@ -190,11 +190,7 @@ impl SigV4Signer {
        let (signing_instructions, signature) = {
            // A body that is already in memory can be signed directly. A body that is not in memory
            // (any sort of streaming body or presigned request) will be signed via UNSIGNED-PAYLOAD.
            let signable_body =
                if operation_config.signature_type == HttpSignatureType::HttpRequestQueryParams {
                    SignableBody::UnsignedPayload
                } else {
                    request_config
            let signable_body = request_config
                .payload_override
                // the payload_override is a cheap clone because it contains either a
                // reference or a short checksum (we're not cloning the entire body)
@@ -205,8 +201,7 @@ impl SigV4Signer {
                        .bytes()
                        .map(SignableBody::Bytes)
                        .unwrap_or(SignableBody::UnsignedPayload)
                        })
                };
                });

            let signable_request = SignableRequest::new(
                request.method(),
+13 −13
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.withBlock
import software.amazon.smithy.rust.codegen.rustlang.withBlockTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.customize.OperationCustomization
@@ -29,7 +30,6 @@ import software.amazon.smithy.rust.codegen.smithy.customize.OperationSection
import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsSection
import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig
import software.amazon.smithy.rust.codegen.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.smithy.generators.config.ServiceConfig
import software.amazon.smithy.rust.codegen.util.dq
@@ -46,31 +46,31 @@ class AwsEndpointDecorator : RustCodegenDecorator {
    }

    override fun configCustomizations(
        protocolConfig: ProtocolConfig,
        codegenContext: CodegenContext,
        baseCustomizations: List<ConfigCustomization>
    ): List<ConfigCustomization> {
        return baseCustomizations + EndpointConfigCustomization(protocolConfig, endpoints)
        return baseCustomizations + EndpointConfigCustomization(codegenContext, endpoints)
    }

    override fun operationCustomizations(
        protocolConfig: ProtocolConfig,
        codegenContext: CodegenContext,
        operation: OperationShape,
        baseCustomizations: List<OperationCustomization>
    ): List<OperationCustomization> {
        return baseCustomizations + EndpointResolverFeature(protocolConfig.runtimeConfig, operation)
        return baseCustomizations + EndpointResolverFeature(codegenContext.runtimeConfig, operation)
    }

    override fun libRsCustomizations(
        protocolConfig: ProtocolConfig,
        codegenContext: CodegenContext,
        baseCustomizations: List<LibRsCustomization>
    ): List<LibRsCustomization> {
        return baseCustomizations + PubUseEndpoint(protocolConfig.runtimeConfig)
        return baseCustomizations + PubUseEndpoint(codegenContext.runtimeConfig)
    }
}

class EndpointConfigCustomization(private val protocolConfig: ProtocolConfig, private val endpointData: ObjectNode) :
class EndpointConfigCustomization(private val codegenContext: CodegenContext, private val endpointData: ObjectNode) :
    ConfigCustomization() {
    private val runtimeConfig = protocolConfig.runtimeConfig
    private val runtimeConfig = codegenContext.runtimeConfig
    private val resolveAwsEndpoint = runtimeConfig.awsEndpointDependency().asType().copy(name = "ResolveAwsEndpoint")
    override fun section(section: ServiceConfig): Writable = writable {
        when (section) {
@@ -92,7 +92,7 @@ class EndpointConfigCustomization(private val protocolConfig: ProtocolConfig, pr
                    resolveAwsEndpoint
                )
            ServiceConfig.BuilderBuild -> {
                val resolverGenerator = EndpointResolverGenerator(protocolConfig, endpointData)
                val resolverGenerator = EndpointResolverGenerator(codegenContext, endpointData)
                rust(
                    """endpoint_resolver: self.endpoint_resolver.unwrap_or_else(||
                                ::std::sync::Arc::new(
@@ -140,9 +140,9 @@ class PubUseEndpoint(private val runtimeConfig: RuntimeConfig) : LibRsCustomizat
    }
}

class EndpointResolverGenerator(protocolConfig: ProtocolConfig, private val endpointData: ObjectNode) {
    private val runtimeConfig = protocolConfig.runtimeConfig
    private val endpointPrefix = protocolConfig.serviceShape.expectTrait<ServiceTrait>().endpointPrefix
class EndpointResolverGenerator(codegenContext: CodegenContext, private val endpointData: ObjectNode) {
    private val runtimeConfig = codegenContext.runtimeConfig
    private val endpointPrefix = codegenContext.serviceShape.expectTrait<ServiceTrait>().endpointPrefix
    private val awsEndpoint = runtimeConfig.awsEndpointDependency().asType()
    private val codegenScope =
        arrayOf(
+6 −6
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ import software.amazon.smithy.rust.codegen.rustlang.rust
import software.amazon.smithy.rust.codegen.rustlang.rustBlock
import software.amazon.smithy.rust.codegen.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.rustlang.writable
import software.amazon.smithy.rust.codegen.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.smithy.RustCrate
@@ -24,7 +25,6 @@ import software.amazon.smithy.rust.codegen.smithy.generators.ClientGenerics
import software.amazon.smithy.rust.codegen.smithy.generators.FluentClientGenerator
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsSection
import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig

private class Types(runtimeConfig: RuntimeConfig) {
    private val smithyClientDep = CargoDependency.SmithyClient(runtimeConfig).copy(optional = true)
@@ -44,12 +44,12 @@ class AwsFluentClientDecorator : RustCodegenDecorator {
    // Must run after the AwsPresigningDecorator so that the presignable trait is correctly added to operations
    override val order: Byte = (AwsPresigningDecorator.ORDER + 1).toByte()

    override fun extras(protocolConfig: ProtocolConfig, rustCrate: RustCrate) {
        val types = Types(protocolConfig.runtimeConfig)
    override fun extras(codegenContext: CodegenContext, rustCrate: RustCrate) {
        val types = Types(codegenContext.runtimeConfig)
        val module = RustMetadata(additionalAttributes = listOf(Attribute.Cfg.feature("client")), public = true)
        rustCrate.withModule(RustModule("client", module)) { writer ->
            FluentClientGenerator(
                protocolConfig,
                codegenContext,
                includeSmithyGenericClientDocs = false,
                generics = ClientGenerics(
                    connectorDefault = "#{AwsFluentClient_DynConnector}",
@@ -61,7 +61,7 @@ class AwsFluentClientDecorator : RustCodegenDecorator {
                        "AwsFluentClient_retry" to types.smithyClientRetry,
                    )
                ),
                customizations = listOf(AwsPresignedFluentBuilderMethod(protocolConfig.runtimeConfig))
                customizations = listOf(AwsPresignedFluentBuilderMethod(codegenContext.runtimeConfig))
            ).render(writer)
            AwsFluentClientExtensions(types).render(writer)
        }
@@ -72,7 +72,7 @@ class AwsFluentClientDecorator : RustCodegenDecorator {
    }

    override fun libRsCustomizations(
        protocolConfig: ProtocolConfig,
        codegenContext: CodegenContext,
        baseCustomizations: List<LibRsCustomization>
    ): List<LibRsCustomization> {
        return baseCustomizations + object : LibRsCustomization() {
Loading