From 3ee5dcbdc0f9fc7edaa980fadb88a070bf6bb28d Mon Sep 17 00:00:00 2001 From: Landon James Date: Mon, 19 Aug 2024 11:56:12 -0700 Subject: [PATCH] Adding minimal support for accountId related endpoint rules built-ins (#3792) ## Motivation and Context 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 * 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 * 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 - [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: ysaito1001 --- .changelog/account-id-endpoint-built-ins.md | 10 +++++++++ .../rustsdk/EndpointBuiltInsDecorator.kt | 21 ++++++++++++++---- .../endpoints/OperationInputTestGenerator.kt | 5 +++++ .../rustsdk/EndpointBuiltInsDecoratorTest.kt | 22 ++++++++++++++++++- 4 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 .changelog/account-id-endpoint-built-ins.md diff --git a/.changelog/account-id-endpoint-built-ins.md b/.changelog/account-id-endpoint-built-ins.md new file mode 100644 index 000000000..855b4755e --- /dev/null +++ b/.changelog/account-id-endpoint-built-ins.md @@ -0,0 +1,10 @@ +--- +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 diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/EndpointBuiltInsDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/EndpointBuiltInsDecorator.kt index b2407859b..c23e2a6b8 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/EndpointBuiltInsDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/EndpointBuiltInsDecorator.kt @@ -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 { - return listOfNotNull( - codegenContext.model.sdkConfigSetter(codegenContext.serviceShape.id, builtIn, clientParamBuilder?.name), - ) + if (includeSdkConfigSetter) { + return listOfNotNull( + 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() diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/endpoints/OperationInputTestGenerator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/endpoints/OperationInputTestGenerator.kt index 5bcc870ae..489aef1d4 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/endpoints/OperationInputTestGenerator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/endpoints/OperationInputTestGenerator.kt @@ -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()") } } diff --git a/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/EndpointBuiltInsDecoratorTest.kt b/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/EndpointBuiltInsDecoratorTest.kt index c5dd55816..61e831791 100644 --- a/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/EndpointBuiltInsDecoratorTest.kt +++ b/aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/EndpointBuiltInsDecoratorTest.kt @@ -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 }