From 12338ad54e99de525e2d6b979f79716d23c7100f Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Fri, 28 Apr 2023 14:31:04 -0700 Subject: [PATCH] Change the orchestrator feature gate into a quad state (#2657) ## Motivation and Context So far we have been testing with the orchestrator on or off, with "on" meaning that both the middleware and orchestrator implementations exist, and you have to opt into the orchestrator via a `send_v2` function call (instead of `send`). This approach makes it difficult to test against the orchestrator exclusively, and also test the existing integration tests with the orchestrator implementation. This PR changes `enableNewSmithyRuntime` into a quad-state with: - middleware - both middleware and orchestrator, defaulting to middleware - both middleware and orchestrator, defaulting to orchestrator - orchestrator This allows for generating a client with the orchestrator exclusively, or generating both and defaulting to the orchestrator, to reduce testing friction. ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._ --- aws/sdk-adhoc-test/build.gradle.kts | 2 - .../smithy/rustsdk/CredentialProviders.kt | 2 +- .../HttpConnectorConfigCustomization.kt | 2 +- .../rustsdk/HttpRequestChecksumDecorator.kt | 2 +- .../rustsdk/HttpResponseChecksumDecorator.kt | 2 +- .../rustsdk/IntegrationTestDependencies.kt | 2 +- .../smithy/rustsdk/InvocationIdDecorator.kt | 2 +- .../rustsdk/RecursionDetectionDecorator.kt | 2 +- .../smithy/rustsdk/SigV4AuthDecorator.kt | 4 +- .../smithy/rustsdk/UserAgentDecorator.kt | 2 +- aws/sdk/build.gradle.kts | 3 +- aws/sra-test/build.gradle.kts | 3 +- .../benches/middleware_vs_orchestrator.rs | 2 +- .../aws-sdk-s3/tests/sra_test.rs | 2 +- .../client/smithy/ClientCodegenContext.kt | 4 +- .../client/smithy/ClientRustSettings.kt | 45 +++++- .../customizations/ApiKeyAuthDecorator.kt | 2 +- .../customizations/EndpointPrefixGenerator.kt | 2 +- .../customizations/HttpAuthDecorator.kt | 10 +- .../HttpConnectorConfigDecorator.kt | 2 +- .../endpoint/EndpointParamsDecorator.kt | 2 +- .../EndpointParamsInterceptorGenerator.kt | 2 +- .../EndpointTraitBindingGenerator.kt | 5 +- .../smithy/generators/ServiceGenerator.kt | 2 +- .../client/FluentClientDecorator.kt | 2 +- .../client/FluentClientGenerator.kt | 147 +++++++++++------- .../protocol/ClientProtocolGenerator.kt | 2 +- .../customizations/HttpAuthDecoratorTest.kt | 16 +- .../generators/EndpointTraitBindingsTest.kt | 8 +- 29 files changed, 180 insertions(+), 103 deletions(-) diff --git a/aws/sdk-adhoc-test/build.gradle.kts b/aws/sdk-adhoc-test/build.gradle.kts index 98ad95310..fbd40ae1c 100644 --- a/aws/sdk-adhoc-test/build.gradle.kts +++ b/aws/sdk-adhoc-test/build.gradle.kts @@ -46,7 +46,6 @@ val allCodegenTests = listOf( , "codegen": { "includeFluentClient": false, - "enableNewCrateOrganizationScheme": true }, "customizationConfig": { "awsSdk": { @@ -63,7 +62,6 @@ val allCodegenTests = listOf( , "codegen": { "includeFluentClient": false, - "enableNewCrateOrganizationScheme": true }, "customizationConfig": { "awsSdk": { diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt index 84d644a43..eb0321213 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt @@ -32,7 +32,7 @@ class CredentialsProviderDecorator : ClientCodegenDecorator { codegenContext: ClientCodegenContext, baseCustomizations: List, ): List = - baseCustomizations.letIf(codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + baseCustomizations.letIf(codegenContext.smithyRuntimeMode.generateOrchestrator) { it + listOf(CredentialsIdentityResolverRegistration(codegenContext)) } diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpConnectorConfigCustomization.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpConnectorConfigCustomization.kt index 75c252d0f..d64ddea9b 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpConnectorConfigCustomization.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpConnectorConfigCustomization.kt @@ -26,7 +26,7 @@ class HttpConnectorDecorator : ClientCodegenDecorator { codegenContext: ClientCodegenContext, baseCustomizations: List, ): List = - baseCustomizations.letIf(!codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + baseCustomizations.letIf(codegenContext.smithyRuntimeMode.exclusivelyGenerateMiddleware) { it + HttpConnectorConfigCustomization(codegenContext) } } diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpRequestChecksumDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpRequestChecksumDecorator.kt index f2913a1aa..b72293b1f 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpRequestChecksumDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpRequestChecksumDecorator.kt @@ -44,7 +44,7 @@ class HttpRequestChecksumDecorator : ClientCodegenDecorator { // TODO(enableNewSmithyRuntime): Implement checksumming via interceptor and delete this decorator private fun applies(codegenContext: ClientCodegenContext): Boolean = - !codegenContext.settings.codegenConfig.enableNewSmithyRuntime + codegenContext.smithyRuntimeMode.exclusivelyGenerateMiddleware override fun operationCustomizations( codegenContext: ClientCodegenContext, diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpResponseChecksumDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpResponseChecksumDecorator.kt index 832ab7e07..cebc4e5cb 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpResponseChecksumDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/HttpResponseChecksumDecorator.kt @@ -35,7 +35,7 @@ class HttpResponseChecksumDecorator : ClientCodegenDecorator { // TODO(enableNewSmithyRuntime): Implement checksumming via interceptor and delete this decorator private fun applies(codegenContext: ClientCodegenContext, operationShape: OperationShape): Boolean = - !codegenContext.settings.codegenConfig.enableNewSmithyRuntime && operationShape.outputShape != ShapeId.from("com.amazonaws.s3#GetObjectOutput") + codegenContext.smithyRuntimeMode.generateMiddleware && operationShape.outputShape != ShapeId.from("com.amazonaws.s3#GetObjectOutput") override fun operationCustomizations( codegenContext: ClientCodegenContext, diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/IntegrationTestDependencies.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/IntegrationTestDependencies.kt index 6eedc44a8..556e71d2b 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/IntegrationTestDependencies.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/IntegrationTestDependencies.kt @@ -126,7 +126,7 @@ class S3TestDependencies(private val codegenContext: ClientCodegenContext) : Lib // TODO(enableNewSmithyRuntime): These additional dependencies may not be needed anymore when removing this flag // depending on if the sra-test is kept around or not. - if (codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + if (codegenContext.smithyRuntimeMode.generateOrchestrator) { addDependency(CargoDependency.smithyRuntime(codegenContext.runtimeConfig).toDevDependency()) addDependency(CargoDependency.smithyRuntimeApi(codegenContext.runtimeConfig).toDevDependency()) } diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/InvocationIdDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/InvocationIdDecorator.kt index abf317570..c608f1c57 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/InvocationIdDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/InvocationIdDecorator.kt @@ -21,7 +21,7 @@ class InvocationIdDecorator : ClientCodegenDecorator { codegenContext: ClientCodegenContext, baseCustomizations: List, ): List = - baseCustomizations.letIf(codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + baseCustomizations.letIf(codegenContext.smithyRuntimeMode.generateOrchestrator) { it + listOf(InvocationIdRuntimePluginCustomization(codegenContext)) } } diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RecursionDetectionDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RecursionDetectionDecorator.kt index 09e6a3074..4685acad7 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RecursionDetectionDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RecursionDetectionDecorator.kt @@ -22,7 +22,7 @@ class RecursionDetectionDecorator : ClientCodegenDecorator { codegenContext: ClientCodegenContext, baseCustomizations: List, ): List = - baseCustomizations.letIf(codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + baseCustomizations.letIf(codegenContext.smithyRuntimeMode.generateOrchestrator) { it + listOf(RecursionDetectionRuntimePluginCustomization(codegenContext)) } } diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SigV4AuthDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SigV4AuthDecorator.kt index f4973330c..6131e50c7 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SigV4AuthDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SigV4AuthDecorator.kt @@ -33,7 +33,7 @@ class SigV4AuthDecorator : ClientCodegenDecorator { codegenContext: ClientCodegenContext, baseCustomizations: List, ): List = - baseCustomizations.letIf(codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + baseCustomizations.letIf(codegenContext.smithyRuntimeMode.generateOrchestrator) { it + listOf(AuthServiceRuntimePluginCustomization(codegenContext)) } @@ -42,7 +42,7 @@ class SigV4AuthDecorator : ClientCodegenDecorator { operation: OperationShape, baseCustomizations: List, ): List = - baseCustomizations.letIf(codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + baseCustomizations.letIf(codegenContext.smithyRuntimeMode.generateOrchestrator) { it + listOf(AuthOperationRuntimePluginCustomization(codegenContext)) } } diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/UserAgentDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/UserAgentDecorator.kt index 0e83d2c99..90183fbf9 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/UserAgentDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/UserAgentDecorator.kt @@ -55,7 +55,7 @@ class UserAgentDecorator : ClientCodegenDecorator { codegenContext: ClientCodegenContext, baseCustomizations: List, ): List = - baseCustomizations.letIf(codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + baseCustomizations.letIf(codegenContext.smithyRuntimeMode.generateOrchestrator) { it + listOf(AddApiMetadataIntoConfigBag(codegenContext)) } diff --git a/aws/sdk/build.gradle.kts b/aws/sdk/build.gradle.kts index 06355aaab..1f92a77b7 100644 --- a/aws/sdk/build.gradle.kts +++ b/aws/sdk/build.gradle.kts @@ -102,8 +102,7 @@ fun generateSmithyBuild(services: AwsServices): String { "renameErrors": false, "debugMode": $debugMode, "eventStreamAllowList": [$eventStreamAllowListMembers], - "enableNewCrateOrganizationScheme": true, - "enableNewSmithyRuntime": false + "enableNewSmithyRuntime": "middleware" }, "service": "${service.service}", "module": "$moduleName", diff --git a/aws/sra-test/build.gradle.kts b/aws/sra-test/build.gradle.kts index 7344916af..669f23174 100644 --- a/aws/sra-test/build.gradle.kts +++ b/aws/sra-test/build.gradle.kts @@ -65,7 +65,8 @@ val allCodegenTests = servicesToGenerate.map { , "codegen": { "includeFluentClient": false, - "enableNewSmithyRuntime": true + ${ ""/* "enableNewSmithyRuntime": "both_default_middleware" */ } + "enableNewSmithyRuntime": "orchestrator" }, "customizationConfig": { "awsSdk": { diff --git a/aws/sra-test/integration-tests/aws-sdk-s3/benches/middleware_vs_orchestrator.rs b/aws/sra-test/integration-tests/aws-sdk-s3/benches/middleware_vs_orchestrator.rs index ba9d003aa..622cdaca4 100644 --- a/aws/sra-test/integration-tests/aws-sdk-s3/benches/middleware_vs_orchestrator.rs +++ b/aws/sra-test/integration-tests/aws-sdk-s3/benches/middleware_vs_orchestrator.rs @@ -107,7 +107,7 @@ async fn orchestrator(client: &s3::Client) { .list_objects_v2() .bucket("test-bucket") .prefix("prefix~") - .send_v2_with_plugin(Some(FixupPlugin { + .send_orchestrator_with_plugin(Some(FixupPlugin { region: client .conf() .region() diff --git a/aws/sra-test/integration-tests/aws-sdk-s3/tests/sra_test.rs b/aws/sra-test/integration-tests/aws-sdk-s3/tests/sra_test.rs index 464c815d6..3fe7e6373 100644 --- a/aws/sra-test/integration-tests/aws-sdk-s3/tests/sra_test.rs +++ b/aws/sra-test/integration-tests/aws-sdk-s3/tests/sra_test.rs @@ -41,7 +41,7 @@ async fn sra_test() { .config_override(aws_sdk_s3::Config::builder().force_path_style(false)) .bucket("test-bucket") .prefix("prefix~") - .send_v2_with_plugin(Some(fixup)) + .send_orchestrator_with_plugin(Some(fixup)) .await ); // To regenerate the test: diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientCodegenContext.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientCodegenContext.kt index e0ec0afb6..92a8a9f8c 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientCodegenContext.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientCodegenContext.kt @@ -32,4 +32,6 @@ data class ClientCodegenContext( val rootDecorator: ClientCodegenDecorator, ) : CodegenContext( model, symbolProvider, moduleDocProvider, serviceShape, protocol, settings, CodegenTarget.CLIENT, -) +) { + val smithyRuntimeMode: SmithyRuntimeMode get() = settings.codegenConfig.enableNewSmithyRuntime +} diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustSettings.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustSettings.kt index e6680d3e0..d7246cf98 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustSettings.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustSettings.kt @@ -72,6 +72,43 @@ data class ClientRustSettings( } } +// TODO(enableNewSmithyRuntime): Remove this mode after switching to the orchestrator +enum class SmithyRuntimeMode { + Middleware, + BothDefaultMiddleware, + BothDefaultOrchestrator, + Orchestrator, + ; + + val exclusivelyGenerateMiddleware: Boolean get() = generateMiddleware && !generateOrchestrator + + val generateMiddleware: Boolean get() = when (this) { + Middleware, BothDefaultMiddleware, BothDefaultOrchestrator -> true + else -> false + } + + val generateOrchestrator: Boolean get() = when (this) { + Orchestrator, BothDefaultMiddleware, BothDefaultOrchestrator -> true + else -> false + } + + val defaultToMiddleware: Boolean get() = when (this) { + Middleware, BothDefaultMiddleware -> true + else -> false + } + val defaultToOrchestrator: Boolean get() = !defaultToMiddleware + + companion object { + fun fromString(value: String): SmithyRuntimeMode = when (value) { + "middleware" -> Middleware + "orchestrator" -> Orchestrator + "both_default_middleware" -> BothDefaultMiddleware + "both_default_orchestrator" -> BothDefaultOrchestrator + else -> throw IllegalArgumentException("unknown runtime mode: $value") + } + } +} + /** * [renameExceptions]: Rename `Exception` to `Error` in the generated SDK * [includeFluentClient]: Generate a `client` module in the generated SDK (currently the AWS SDK sets this to `false` @@ -87,7 +124,7 @@ data class ClientCodegenConfig( // TODO(EventStream): [CLEANUP] Remove this property when turning on Event Stream for all services val eventStreamAllowList: Set = defaultEventStreamAllowList, // TODO(SmithyRuntime): Remove this once we commit to switch to aws-smithy-runtime and aws-smithy-runtime-api - val enableNewSmithyRuntime: Boolean = defaultEnableNewSmithyRuntime, + val enableNewSmithyRuntime: SmithyRuntimeMode = defaultEnableNewSmithyRuntime, ) : CoreCodegenConfig( formatTimeoutSeconds, debugMode, ) { @@ -96,7 +133,7 @@ data class ClientCodegenConfig( private const val defaultIncludeFluentClient = true private const val defaultAddMessageToErrors = true private val defaultEventStreamAllowList: Set = emptySet() - private const val defaultEnableNewSmithyRuntime = false + private val defaultEnableNewSmithyRuntime = SmithyRuntimeMode.Middleware fun fromCodegenConfigAndNode(coreCodegenConfig: CoreCodegenConfig, node: Optional) = if (node.isPresent) { @@ -109,7 +146,9 @@ data class ClientCodegenConfig( renameExceptions = node.get().getBooleanMemberOrDefault("renameErrors", defaultRenameExceptions), includeFluentClient = node.get().getBooleanMemberOrDefault("includeFluentClient", defaultIncludeFluentClient), addMessageToErrors = node.get().getBooleanMemberOrDefault("addMessageToErrors", defaultAddMessageToErrors), - enableNewSmithyRuntime = node.get().getBooleanMemberOrDefault("enableNewSmithyRuntime", defaultEnableNewSmithyRuntime), + enableNewSmithyRuntime = SmithyRuntimeMode.fromString( + node.get().getStringMemberOrDefault("enableNewSmithyRuntime", "middleware"), + ), ) } else { ClientCodegenConfig( diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ApiKeyAuthDecorator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ApiKeyAuthDecorator.kt index 58fd14e6a..14fe1fd1c 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ApiKeyAuthDecorator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ApiKeyAuthDecorator.kt @@ -38,7 +38,7 @@ class ApiKeyAuthDecorator : ClientCodegenDecorator { override val order: Byte = 10 private fun applies(codegenContext: ClientCodegenContext) = - !codegenContext.settings.codegenConfig.enableNewSmithyRuntime && + codegenContext.smithyRuntimeMode.generateMiddleware && isSupportedApiKeyAuth(codegenContext) override fun configCustomizations( diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/EndpointPrefixGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/EndpointPrefixGenerator.kt index 2fe90239d..190aac368 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/EndpointPrefixGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/EndpointPrefixGenerator.kt @@ -32,7 +32,7 @@ class EndpointPrefixGenerator(private val codegenContext: ClientCodegenContext, endpointTraitBindings.render( this, "self", - codegenContext.settings.codegenConfig.enableNewSmithyRuntime, + codegenContext.smithyRuntimeMode, ) } rust("request.properties_mut().insert(endpoint_prefix);") diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecorator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecorator.kt index 53aa5ee2a..5b0eba15d 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecorator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecorator.kt @@ -68,12 +68,12 @@ private data class HttpAuthSchemes( companion object { fun from(codegenContext: ClientCodegenContext): HttpAuthSchemes { val authSchemes = ServiceIndex.of(codegenContext.model).getAuthSchemes(codegenContext.serviceShape).keys - val newRuntimeEnabled = codegenContext.settings.codegenConfig.enableNewSmithyRuntime + val generateOrchestrator = codegenContext.smithyRuntimeMode.generateOrchestrator return HttpAuthSchemes( - apiKey = newRuntimeEnabled && authSchemes.contains(HttpApiKeyAuthTrait.ID), - basic = newRuntimeEnabled && authSchemes.contains(HttpBasicAuthTrait.ID), - bearer = newRuntimeEnabled && authSchemes.contains(HttpBearerAuthTrait.ID), - digest = newRuntimeEnabled && authSchemes.contains(HttpDigestAuthTrait.ID), + apiKey = generateOrchestrator && authSchemes.contains(HttpApiKeyAuthTrait.ID), + basic = generateOrchestrator && authSchemes.contains(HttpBasicAuthTrait.ID), + bearer = generateOrchestrator && authSchemes.contains(HttpBearerAuthTrait.ID), + digest = generateOrchestrator && authSchemes.contains(HttpDigestAuthTrait.ID), ) } } diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpConnectorConfigDecorator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpConnectorConfigDecorator.kt index 102c50e71..d5ecd078b 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpConnectorConfigDecorator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpConnectorConfigDecorator.kt @@ -25,7 +25,7 @@ class HttpConnectorConfigDecorator : ClientCodegenDecorator { codegenContext: ClientCodegenContext, baseCustomizations: List, ): List = - baseCustomizations.letIf(codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + baseCustomizations.letIf(codegenContext.smithyRuntimeMode.generateOrchestrator) { it + HttpConnectorConfigCustomization(codegenContext) } } diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/EndpointParamsDecorator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/EndpointParamsDecorator.kt index ba728bcdf..f35becb55 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/EndpointParamsDecorator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/EndpointParamsDecorator.kt @@ -31,7 +31,7 @@ class EndpointParamsDecorator : ClientCodegenDecorator { operation: OperationShape, baseCustomizations: List, ): List = - baseCustomizations.letIf(codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + baseCustomizations.letIf(codegenContext.smithyRuntimeMode.generateOrchestrator) { it + listOf(EndpointParametersRuntimePluginCustomization(codegenContext, operation)) } } diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/generators/EndpointParamsInterceptorGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/generators/EndpointParamsInterceptorGenerator.kt index b00a02050..2dc2f2e1e 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/generators/EndpointParamsInterceptorGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/generators/EndpointParamsInterceptorGenerator.kt @@ -118,7 +118,7 @@ class EndpointParamsInterceptorGenerator( endpointTraitBindings.render( this, "_input", - codegenContext.settings.codegenConfig.enableNewSmithyRuntime, + codegenContext.smithyRuntimeMode, ) } rust("cfg.put(endpoint_prefix);") diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/EndpointTraitBindingGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/EndpointTraitBindingGenerator.kt index 4cc4b9334..f02cb5cde 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/EndpointTraitBindingGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/EndpointTraitBindingGenerator.kt @@ -8,6 +8,7 @@ package software.amazon.smithy.rust.codegen.client.smithy.generators import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.traits.EndpointTrait +import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode import software.amazon.smithy.rust.codegen.client.smithy.generators.http.rustFormatString import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter import software.amazon.smithy.rust.codegen.core.rustlang.rust @@ -44,7 +45,7 @@ class EndpointTraitBindings( * * The returned expression is a `Result` */ - fun render(writer: RustWriter, input: String, enableNewSmithyRuntime: Boolean) { + fun render(writer: RustWriter, input: String, smithyRuntimeMode: SmithyRuntimeMode) { // the Rust format pattern to make the endpoint prefix e.g. "{}.foo" val formatLiteral = endpointTrait.prefixFormatString() if (endpointTrait.hostPrefix.labels.isEmpty()) { @@ -67,7 +68,7 @@ class EndpointTraitBindings( // NOTE: this is dead code until we start respecting @required rust("let $field = &$input.$field;") } - val contents = if (enableNewSmithyRuntime) { + val contents = if (smithyRuntimeMode.generateOrchestrator) { // TODO(enableNewSmithyRuntime): Remove the allow attribute once all places need .into method """ if $field.is_empty() { diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ServiceGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ServiceGenerator.kt index 764efb35d..050e12437 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ServiceGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ServiceGenerator.kt @@ -47,7 +47,7 @@ class ServiceGenerator( ) serviceConfigGenerator.render(this) - if (codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + if (codegenContext.smithyRuntimeMode.generateOrchestrator) { // Enable users to opt in to the test-utils in the runtime crate rustCrate.mergeFeature(TestUtilFeature.copy(deps = listOf("aws-smithy-runtime/test-util"))) diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/client/FluentClientDecorator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/client/FluentClientDecorator.kt index e5e2760ce..7fb225fa4 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/client/FluentClientDecorator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/client/FluentClientDecorator.kt @@ -36,7 +36,7 @@ class FluentClientDecorator : ClientCodegenDecorator { return } - val generics = if (codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + val generics = if (codegenContext.smithyRuntimeMode.generateOrchestrator) { NoClientGenerics(codegenContext.runtimeConfig) } else { FlexibleClientGenerics( diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/client/FluentClientGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/client/FluentClientGenerator.kt index 6c085fd67..f10de15ee 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/client/FluentClientGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/client/FluentClientGenerator.kt @@ -78,7 +78,7 @@ class FluentClientGenerator( private val model = codegenContext.model private val runtimeConfig = codegenContext.runtimeConfig private val core = FluentClientCore(model) - private val enableNewSmithyRuntime = codegenContext.settings.codegenConfig.enableNewSmithyRuntime + private val smithyRuntimeMode = codegenContext.smithyRuntimeMode fun render(crate: RustCrate) { renderFluentClient(crate) @@ -255,7 +255,7 @@ class FluentClientGenerator( "Inner" to symbolProvider.symbolForBuilder(input), "generics" to generics.decl, ) - if (enableNewSmithyRuntime) { + if (smithyRuntimeMode.generateOrchestrator) { rust("config_override: std::option::Option,") } } @@ -279,11 +279,26 @@ class FluentClientGenerator( "}", ) { rust("handle, inner: Default::default(),") - if (enableNewSmithyRuntime) { + if (smithyRuntimeMode.generateOrchestrator) { rust("config_override: None,") } } } + val middlewareScope = arrayOf( + "CustomizableOperation" to ClientRustModule.Client.customize.toType() + .resolve("CustomizableOperation"), + "ClassifyRetry" to RuntimeType.classifyRetry(runtimeConfig), + "OperationError" to errorType, + "OperationOutput" to outputType, + "SdkError" to RuntimeType.sdkError(runtimeConfig), + "SdkSuccess" to RuntimeType.sdkSuccess(runtimeConfig), + "send_bounds" to generics.sendBounds(operationSymbol, outputType, errorType, retryClassifier), + "customizable_op_type_params" to rustTypeParameters( + symbolProvider.toSymbol(operation), + retryClassifier, + generics.toRustGenerics(), + ), + ) rustTemplate( """ /// Consume this builder, creating a customizable operation that can be modified before being @@ -300,15 +315,9 @@ class FluentClientGenerator( Ok(#{CustomizableOperation} { handle, operation }) } - /// Sends the request and returns the response. - /// - /// If an error occurs, an `SdkError` will be returned with additional details that - /// can be matched against. - /// - /// By default, any retryable failures will be retried twice. Retry behavior - /// is configurable with the [RetryConfig](aws_smithy_types::retry::RetryConfig), which can be - /// set when configuring the client. - pub async fn send(self) -> std::result::Result<#{OperationOutput}, #{SdkError}<#{OperationError}>> + // This function will go away in the near future. Do not rely on it. + ##[doc(hidden)] + pub async fn send_middleware(self) -> std::result::Result<#{OperationOutput}, #{SdkError}<#{OperationError}>> #{send_bounds:W} { let op = self.inner.build().map_err(#{SdkError}::construction_failure)? .make_operation(&self.handle.conf) @@ -317,24 +326,11 @@ class FluentClientGenerator( self.handle.client.call(op).await } """, - "CustomizableOperation" to ClientRustModule.Client.customize.toType() - .resolve("CustomizableOperation"), - "ClassifyRetry" to RuntimeType.classifyRetry(runtimeConfig), - "OperationError" to errorType, - "OperationOutput" to outputType, - "SdkError" to RuntimeType.sdkError(runtimeConfig), - "SdkSuccess" to RuntimeType.sdkSuccess(runtimeConfig), - "send_bounds" to generics.sendBounds(operationSymbol, outputType, errorType, retryClassifier), - "customizable_op_type_params" to rustTypeParameters( - symbolProvider.toSymbol(operation), - retryClassifier, - generics.toRustGenerics(), - ), + *middlewareScope, ) - if (enableNewSmithyRuntime) { + if (smithyRuntimeMode.defaultToMiddleware) { rustTemplate( """ - // TODO(enableNewSmithyRuntime): Replace `send` with `send_v2` /// Sends the request and returns the response. /// /// If an error occurs, an `SdkError` will be returned with additional details that @@ -343,13 +339,40 @@ class FluentClientGenerator( /// By default, any retryable failures will be retried twice. Retry behavior /// is configurable with the [RetryConfig](aws_smithy_types::retry::RetryConfig), which can be /// set when configuring the client. - pub async fn send_v2(self) -> std::result::Result<#{OperationOutput}, #{SdkError}<#{OperationError}, #{HttpResponse}>> { - self.send_v2_with_plugin(Option::>::None).await + pub async fn send(self) -> std::result::Result<#{OperationOutput}, #{SdkError}<#{OperationError}>> + #{send_bounds:W} { + self.send_middleware().await } + """, + *middlewareScope, + ) + } + if (smithyRuntimeMode.generateOrchestrator) { + val orchestratorScope = arrayOf( + "HttpResponse" to RuntimeType.smithyRuntimeApi(runtimeConfig) + .resolve("client::orchestrator::HttpResponse"), + "OperationError" to errorType, + "Operation" to symbolProvider.toSymbol(operation), + "OperationOutput" to outputType, + "RuntimePlugin" to RuntimeType.runtimePlugin(runtimeConfig), + "RuntimePlugins" to RuntimeType.smithyRuntimeApi(runtimeConfig) + .resolve("client::runtime_plugin::RuntimePlugins"), + "SdkError" to RuntimeType.sdkError(runtimeConfig), + "TypedBox" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("type_erasure::TypedBox"), + "invoke" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::orchestrator::invoke"), + ) + rustTemplate( + """ + ##[doc(hidden)] + pub async fn send_orchestrator(self) -> std::result::Result<#{OperationOutput}, #{SdkError}<#{OperationError}, #{HttpResponse}>> { + self.send_orchestrator_with_plugin(Option::>::None).await + } + + ##[doc(hidden)] // TODO(enableNewSmithyRuntime): Delete when unused - /// Equivalent to [`Self::send_v2`] but adds a final runtime plugin to shim missing behavior - pub async fn send_v2_with_plugin(self, final_plugin: Option) -> std::result::Result<#{OperationOutput}, #{SdkError}<#{OperationError}, #{HttpResponse}>> { + /// Equivalent to [`Self::send_orchestrator`] but adds a final runtime plugin to shim missing behavior + pub async fn send_orchestrator_with_plugin(self, final_plugin: Option) -> std::result::Result<#{OperationOutput}, #{SdkError}<#{OperationError}, #{HttpResponse}>> { let mut runtime_plugins = #{RuntimePlugins}::new() .with_client_plugin(crate::config::ServiceRuntimePlugin::new(self.handle.clone())); if let Some(config_override) = self.config_override { @@ -373,18 +396,26 @@ class FluentClientGenerator( Ok(#{TypedBox}::<#{OperationOutput}>::assume_from(output).expect("correct output type").unwrap()) } """, - "HttpResponse" to RuntimeType.smithyRuntimeApi(runtimeConfig) - .resolve("client::orchestrator::HttpResponse"), - "OperationError" to errorType, - "Operation" to symbolProvider.toSymbol(operation), - "OperationOutput" to outputType, - "RuntimePlugin" to RuntimeType.runtimePlugin(runtimeConfig), - "RuntimePlugins" to RuntimeType.smithyRuntimeApi(runtimeConfig) - .resolve("client::runtime_plugin::RuntimePlugins"), - "SdkError" to RuntimeType.sdkError(runtimeConfig), - "TypedBox" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("type_erasure::TypedBox"), - "invoke" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::orchestrator::invoke"), + *orchestratorScope, ) + if (smithyRuntimeMode.defaultToOrchestrator) { + rustTemplate( + """ + /// Sends the request and returns the response. + /// + /// If an error occurs, an `SdkError` will be returned with additional details that + /// can be matched against. + /// + /// By default, any retryable failures will be retried twice. Retry behavior + /// is configurable with the [RetryConfig](aws_smithy_types::retry::RetryConfig), which can be + /// set when configuring the client. + pub async fn send(self) -> std::result::Result<#{OperationOutput}, #{SdkError}<#{OperationError}, #{HttpResponse}>> { + self.send_orchestrator().await + } + """, + *orchestratorScope, + ) + } rustTemplate( """ @@ -426,20 +457,24 @@ class FluentClientGenerator( """, ) } - PaginatorGenerator.paginatorType(codegenContext, generics, operation, retryClassifier) - ?.also { paginatorType -> - rustTemplate( - """ - /// Create a paginator for this request - /// - /// Paginators are used by calling [`send().await`](#{Paginator}::send) which returns a `Stream`. - pub fn into_paginator(self) -> #{Paginator}${generics.inst} { - #{Paginator}::new(self.handle, self.inner) - } - """, - "Paginator" to paginatorType, - ) - } + + // TODO(enableNewSmithyRuntime): Port paginators to the orchestrator + if (smithyRuntimeMode.generateMiddleware) { + PaginatorGenerator.paginatorType(codegenContext, generics, operation, retryClassifier) + ?.also { paginatorType -> + rustTemplate( + """ + /// Create a paginator for this request + /// + /// Paginators are used by calling [`send().await`](#{Paginator}::send) which returns a `Stream`. + pub fn into_paginator(self) -> #{Paginator}${generics.inst} { + #{Paginator}::new(self.handle, self.inner) + } + """, + "Paginator" to paginatorType, + ) + } + } writeCustomizations( customizations, FluentClientSection.FluentBuilderImpl( diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/ClientProtocolGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/ClientProtocolGenerator.kt index 3c8fc7c97..85dcb206d 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/ClientProtocolGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/ClientProtocolGenerator.kt @@ -97,7 +97,7 @@ open class ClientProtocolGenerator( } traitGenerator.generateTraitImpls(operationWriter, operationShape, operationCustomizations) - if (codegenContext.settings.codegenConfig.enableNewSmithyRuntime) { + if (codegenContext.smithyRuntimeMode.generateOrchestrator) { OperationRuntimePluginGenerator(codegenContext).render( operationWriter, operationShape, diff --git a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecoratorTest.kt b/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecoratorTest.kt index 29c3b2e85..bcb5ec2f4 100644 --- a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecoratorTest.kt +++ b/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpAuthDecoratorTest.kt @@ -6,8 +6,8 @@ package software.amazon.smithy.rust.codegen.client.smithy.customizations import org.junit.jupiter.api.Test -import software.amazon.smithy.model.node.BooleanNode import software.amazon.smithy.model.node.ObjectNode +import software.amazon.smithy.model.node.StringNode import software.amazon.smithy.rust.codegen.client.testutil.clientIntegrationTest import software.amazon.smithy.rust.codegen.core.rustlang.Attribute import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency @@ -22,7 +22,7 @@ private fun additionalSettings(): ObjectNode = ObjectNode.objectNodeBuilder() .withMember( "codegen", ObjectNode.objectNodeBuilder() - .withMember("enableNewSmithyRuntime", BooleanNode.from(true)).build(), + .withMember("enableNewSmithyRuntime", StringNode.from("orchestrator")).build(), ) .build() @@ -67,7 +67,7 @@ class HttpAuthDecoratorTest { .build_dyn(); let client = $moduleName::Client::with_config(smithy_client, config); let _ = client.some_operation() - .send_v2() + .send_orchestrator() .await .expect("success"); connector.assert_requests_match(&[]); @@ -101,7 +101,7 @@ class HttpAuthDecoratorTest { .build_dyn(); let client = $moduleName::Client::with_config(smithy_client, config); let _ = client.some_operation() - .send_v2() + .send_orchestrator() .await .expect("success"); connector.assert_requests_match(&[]); @@ -146,7 +146,7 @@ class HttpAuthDecoratorTest { .build_dyn(); let client = $moduleName::Client::with_config(smithy_client, config); let _ = client.some_operation() - .send_v2() + .send_orchestrator() .await .expect("success"); connector.assert_requests_match(&[]); @@ -192,7 +192,7 @@ class HttpAuthDecoratorTest { .build_dyn(); let client = $moduleName::Client::with_config(smithy_client, config); let _ = client.some_operation() - .send_v2() + .send_orchestrator() .await .expect("success"); connector.assert_requests_match(&[]); @@ -238,7 +238,7 @@ class HttpAuthDecoratorTest { .build_dyn(); let client = $moduleName::Client::with_config(smithy_client, config); let _ = client.some_operation() - .send_v2() + .send_orchestrator() .await .expect("success"); connector.assert_requests_match(&[]); @@ -284,7 +284,7 @@ class HttpAuthDecoratorTest { .build_dyn(); let client = $moduleName::Client::with_config(smithy_client, config); let _ = client.some_operation() - .send_v2() + .send_orchestrator() .await .expect("success"); connector.assert_requests_match(&[]); diff --git a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/EndpointTraitBindingsTest.kt b/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/EndpointTraitBindingsTest.kt index 6fe1328bb..34225e8df 100644 --- a/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/EndpointTraitBindingsTest.kt +++ b/codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/EndpointTraitBindingsTest.kt @@ -11,6 +11,7 @@ import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ValueSource import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.traits.EndpointTrait +import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode import software.amazon.smithy.rust.codegen.client.testutil.clientIntegrationTest import software.amazon.smithy.rust.codegen.client.testutil.testSymbolProvider import software.amazon.smithy.rust.codegen.core.rustlang.Attribute @@ -37,8 +38,9 @@ internal class EndpointTraitBindingsTest { } @ParameterizedTest - @ValueSource(booleans = [true, false]) - fun `generate endpoint prefixes`(enableNewSmithyRuntime: Boolean) { + @ValueSource(strings = ["middleware", "orchestrator"]) + fun `generate endpoint prefixes`(smithyRuntimeModeStr: String) { + val smithyRuntimeMode = SmithyRuntimeMode.fromString(smithyRuntimeModeStr) val model = """ namespace test @readonly @@ -76,7 +78,7 @@ internal class EndpointTraitBindingsTest { RuntimeType.smithyHttp(TestRuntimeConfig), TestRuntimeConfig.operationBuildError(), ) { - endpointBindingGenerator.render(this, "self", enableNewSmithyRuntime) + endpointBindingGenerator.render(this, "self", smithyRuntimeMode) } } unitTest( -- GitLab