Unverified Commit 3ee5dcbd authored by Landon James's avatar Landon James Committed by GitHub
Browse files

Adding minimal support for accountId related endpoint rules built-ins (#3792)

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here -->
This change adds minimal support for the `AWS::Auth::AccountId` and
`AWS::Auth::AccountIdEndpointMode` endpoint built-ins. Endpoint rules
containing these builtins will generate correct code, but we do not
support user setting of these values (or any other features defined in
the spec for account id based endpoint resolution).

## Description
<!--- Describe your changes in detail -->
* Add option to endpoint builtins decorator to skip the `SdkConfig`
related codegen
* Add `AccountId` and `AccountIdEndpointMode` built-ins to the list of
generated ones
* Update the test input generator to add a `us-east-1` region if the
test provides built-ins but does not specify a region
* Add the documentation string from the test definition to the generated
test code
* Update tests for `EndpointBulitInsDecorator` to include the two new
bulit-ins

## Testing
<!--- Please describe in detail how you tested your changes -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
* Update tests for `EndpointBulitInsDecorator` to include the two new
bulit-ins
* Ran our CI against this change with the updated DDB endpoints rules
and all tests passed.
https://github.com/smithy-lang/smithy-rs/actions/runs/10423338690



## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it
rather than leaving it unchecked -->
- [x] For changes to the smithy-rs codegen or runtime crates, I have
created a changelog entry Markdown file in the `.changelog` directory,
specifying "client," "server," or both in the `applies_to` key.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._

---------

Co-authored-by: default avatarysaito1001 <awsaito@amazon.com>
parent 3f3c874c
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
---
applies_to: ["aws-sdk-rust"]
authors: ["landonxjames"]
references: ["smithy-rs#3792"]
breaking: false
new_feature: false
bug_fix: false
---

Add minimal support for `AWS::Auth::AccountId` and `AWS::Auth::AccountIdEndpointMode` endpoint built-ins
+17 −4
Original line number Diff line number Diff line
@@ -127,11 +127,14 @@ fun Model.sdkConfigSetter(

/**
 * Create a client codegen decorator that creates bindings for a builtIn parameter. Optionally, you can provide
 * [clientParam.Builder] which allows control over the config parameter that will be generated.
 * [clientParam.Builder] which allows control over the config parameter that will be generated. You can also opt
 * to exclude including the extra sections that set the builtIn value on the SdkConfig. This is useful for builtIns
 * that are only minimally supported, like accountId and accountIdEndpointMode.
 */
fun decoratorForBuiltIn(
    builtIn: Parameter,
    clientParamBuilder: ConfigParam.Builder? = null,
    includeSdkConfigSetter: Boolean = true,
): ClientCodegenDecorator {
    val nameOverride = clientParamBuilder?.name
    val name = nameOverride ?: builtIn.name.rustName()
@@ -143,9 +146,17 @@ fun decoratorForBuiltIn(
            codegenContext.getBuiltIn(builtIn) != null

        override fun extraSections(codegenContext: ClientCodegenContext): List<AdHocCustomization> {
            if (includeSdkConfigSetter) {
                return listOfNotNull(
                codegenContext.model.sdkConfigSetter(codegenContext.serviceShape.id, builtIn, clientParamBuilder?.name),
                    codegenContext.model.sdkConfigSetter(
                        codegenContext.serviceShape.id,
                        builtIn,
                        clientParamBuilder?.name,
                    ),
                )
            } else {
                return listOf()
            }
        }

        override fun configCustomizations(
@@ -236,4 +247,6 @@ val PromotedBuiltInsDecorators =
                .type(RuntimeType.String.toSymbol())
                .setterDocs(endpointUrlDocs),
        ),
        decoratorForBuiltIn(AwsBuiltIns.ACCOUNT_ID_ENDPOINT_MODE, null, false),
        decoratorForBuiltIn(AwsBuiltIns.ACCOUNT_ID, null, false),
    ).toTypedArray()
+5 −0
Original line number Diff line number Diff line
@@ -132,6 +132,7 @@ class OperationInputTestGenerator(_ctx: ClientCodegenContext, private val test:
            tokioTest(safeName("operation_input_test_$operationName")) {
                rustTemplate(
                    """
                    /* documentation: ${test.documentation.orElse("No docs :(")} */
                    /* builtIns: ${escape(Node.prettyPrintJson(testOperationInput.builtInParams))} */
                    /* clientParams: ${escape(Node.prettyPrintJson(testOperationInput.clientParams))} */
                    let (http_client, rcvr) = #{capture_request}(None);
@@ -211,6 +212,10 @@ class OperationInputTestGenerator(_ctx: ClientCodegenContext, private val test:
                        Logger.getLogger("OperationTestGenerator").warning("No provider for ${builtIn.value}")
                    }
                }
                // If the test contains Endpoint built-ins and does not contain an AWS::Region then we set one
                if (!operationInput.builtInParams.isEmpty && !operationInput.builtInParams.containsMember("AWS::Region")) {
                    rust("let builder = builder.region(::aws_types::region::Region::new(\"us-east-1\"));")
                }
                rust("builder.build()")
            }
        }
+21 −1
Original line number Diff line number Diff line
@@ -21,23 +21,38 @@ class EndpointBuiltInsDecoratorTest {
        use aws.auth#sigv4
        use aws.protocols#restJson1
        use smithy.rules#endpointRuleSet
        use smithy.rules#staticContextParams

        @service(sdkId: "dontcare")
        @restJson1
        @sigv4(name: "dontcare")
        @auth([sigv4])
        @suppress(["RuleSetAwsBuiltIn.AWS::Auth::AccountId", "RuleSetAwsBuiltIn.AWS::Auth::AccountIdEndpointMode"])
        @endpointRuleSet({
            "version": "1.0"
            "parameters": {
                "endpoint": { "required": false, "type": "string", "builtIn": "SDK::Endpoint" },
                "region": { "required": false, "type": "String", "builtIn": "AWS::Region" },
                "accountId": { "required": false, "type": "String", "builtIn": "AWS::Auth::AccountId" },
                "accountIdEndpointMode": { "required": false, "type": "String", "builtIn": "AWS::Auth::AccountIdEndpointMode" },
            }
            "rules": [
                {
                    "type": "endpoint"
                    "conditions": [
                        {"fn": "isSet", "argv": [{"ref": "endpoint"}]},
                        {"fn": "isSet", "argv": [{"ref": "region"}]}
                        {"fn": "isSet", "argv": [{"ref": "region"}]},
                        {
                            "fn": "not",
                            "argv": [
                                {
                                    "fn": "isSet",
                                    "argv": [
                                        {"ref": "accountId"}
                                    ]
                                }
                            ]
                        }
                    ],
                    "endpoint": {
                        "url": "{endpoint}"
@@ -72,6 +87,11 @@ class EndpointBuiltInsDecoratorTest {

        @http(uri: "/SomeOperation", method: "GET")
        @optionalAuth
        @staticContextParams(
            accountIdEndpointMode: {
                value: "some value"
            }
        )
        operation SomeOperation {
            output: SomeOutput
        }