Skip to content

Commit 8dc8963

Browse files
authored
Configure orchestrator's key components in builder's build method (#2802)
## Motivation and Context Moves setting orchestrator components out of `ServiceRuntimePlugin` and puts it in service config builders' build method. ## Description This PR is the forth in a series of config refactoring. Here, we move pieces of code out of `ServiceRuntimePlugin::config` method so that key orchestrator components meant for the service-level config should only be constructed once when a service config is created, e.g. during builder's `build` method. Previously, those components were newly created every time an operation is invoked. Wherever `self.handle.conf...` is used, the PR has moved it from `ServiceRuntimePlugin::config` to the builders' `build` method. Note that there will be a separate PR to better handle auth resolver & identity resolver in the context of the ongoing config refactoring. ## Testing - [x] Passed tests in CI ---- _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: Yuki Saito <awsaito@amazon.com>
1 parent e6293b2 commit 8dc8963

File tree

18 files changed

+152
-115
lines changed

18 files changed

+152
-115
lines changed

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialCaches.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,11 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
145145
if (runtimeMode.defaultToOrchestrator) {
146146
rustTemplate(
147147
"""
148-
self.inner.store_put(
149-
self.inner.load::<#{CredentialsCache}>()
148+
layer.store_put(
149+
layer.load::<#{CredentialsCache}>()
150150
.cloned()
151151
.unwrap_or_else({
152-
let sleep = self.inner.load::<#{SharedAsyncSleep}>().cloned();
152+
let sleep = layer.load::<#{SharedAsyncSleep}>().cloned();
153153
|| match sleep {
154154
Some(sleep) => {
155155
#{CredentialsCache}::lazy_builder()
@@ -159,7 +159,7 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
159159
None => #{CredentialsCache}::lazy(),
160160
}
161161
})
162-
.create_cache(self.inner.load::<#{SharedCredentialsProvider}>().cloned().unwrap_or_else(|| {
162+
.create_cache(layer.load::<#{SharedCredentialsProvider}>().cloned().unwrap_or_else(|| {
163163
#{SharedCredentialsProvider}::new(#{DefaultProvider})
164164
}))
165165
);

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SigV4AuthDecorator.kt

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,6 @@ private class AuthServiceRuntimePluginCustomization(private val codegenContext:
7878
// enable the aws-runtime `sign-eventstream` feature
7979
addDependency(AwsCargoDependency.awsRuntime(runtimeConfig).withFeature("event-stream").toType().toSymbol())
8080
}
81-
section.putConfigValue(this) {
82-
rustTemplate("#{SigningService}::from_static(self.handle.conf.signing_service())", *codegenScope)
83-
}
84-
rustTemplate(
85-
"""
86-
if let Some(region) = self.handle.conf.region() {
87-
#{put_signing_region}
88-
}
89-
""",
90-
*codegenScope,
91-
"put_signing_region" to writable {
92-
section.putConfigValue(this) {
93-
rustTemplate("#{SigningRegion}::from(region.clone())", *codegenScope)
94-
}
95-
},
96-
)
9781
}
9882

9983
else -> {}

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SigV4SigningDecorator.kt

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import software.amazon.smithy.model.shapes.ServiceShape
1414
import software.amazon.smithy.model.shapes.ShapeId
1515
import software.amazon.smithy.model.traits.OptionalAuthTrait
1616
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
17+
import software.amazon.smithy.rust.codegen.client.smithy.SmithyRuntimeMode
1718
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
1819
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationCustomization
1920
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationSection
@@ -54,6 +55,7 @@ class SigV4SigningDecorator : ClientCodegenDecorator {
5455
return baseCustomizations.extendIf(applies(codegenContext)) {
5556
SigV4SigningConfig(
5657
codegenContext.runtimeConfig,
58+
codegenContext.smithyRuntimeMode,
5759
codegenContext.serviceShape.hasEventStreamOperations(codegenContext.model),
5860
codegenContext.serviceShape.expectTrait(),
5961
)
@@ -78,26 +80,48 @@ class SigV4SigningDecorator : ClientCodegenDecorator {
7880

7981
class SigV4SigningConfig(
8082
private val runtimeConfig: RuntimeConfig,
83+
private val runtimeMode: SmithyRuntimeMode,
8184
private val serviceHasEventStream: Boolean,
8285
private val sigV4Trait: SigV4Trait,
8386
) : ConfigCustomization() {
87+
private val codegenScope = arrayOf(
88+
"Region" to AwsRuntimeType.awsTypes(runtimeConfig).resolve("region::Region"),
89+
"SigningService" to AwsRuntimeType.awsTypes(runtimeConfig).resolve("SigningService"),
90+
"SigningRegion" to AwsRuntimeType.awsTypes(runtimeConfig).resolve("region::SigningRegion"),
91+
)
92+
8493
override fun section(section: ServiceConfig): Writable = writable {
85-
if (section is ServiceConfig.ConfigImpl) {
86-
if (serviceHasEventStream) {
87-
// enable the aws-sig-auth `sign-eventstream` feature
88-
addDependency(AwsRuntimeType.awsSigAuthEventStream(runtimeConfig).toSymbol())
94+
when (section) {
95+
ServiceConfig.ConfigImpl -> {
96+
if (serviceHasEventStream) {
97+
// enable the aws-sig-auth `sign-eventstream` feature
98+
addDependency(AwsRuntimeType.awsSigAuthEventStream(runtimeConfig).toSymbol())
99+
}
100+
rust(
101+
"""
102+
/// The signature version 4 service signing name to use in the credential scope when signing requests.
103+
///
104+
/// The signing service may be overridden by the `Endpoint`, or by specifying a custom
105+
/// [`SigningService`](aws_types::SigningService) during operation construction
106+
pub fn signing_service(&self) -> &'static str {
107+
${sigV4Trait.name.dq()}
108+
}
109+
""",
110+
)
89111
}
90-
rust(
91-
"""
92-
/// The signature version 4 service signing name to use in the credential scope when signing requests.
93-
///
94-
/// The signing service may be overridden by the `Endpoint`, or by specifying a custom
95-
/// [`SigningService`](aws_types::SigningService) during operation construction
96-
pub fn signing_service(&self) -> &'static str {
97-
${sigV4Trait.name.dq()}
112+
ServiceConfig.BuilderBuild -> {
113+
if (runtimeMode.defaultToOrchestrator) {
114+
rustTemplate(
115+
"""
116+
layer.put(#{SigningService}::from_static(${sigV4Trait.name.dq()}));
117+
layer.load::<#{Region}>().cloned().map(|r| layer.put(#{SigningRegion}::from(r)));
118+
""",
119+
*codegenScope,
120+
)
98121
}
99-
""",
100-
)
122+
}
123+
124+
else -> emptySection
101125
}
102126
}
103127
}

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/UserAgentDecorator.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,6 @@ class UserAgentDecorator : ClientCodegenDecorator {
104104

105105
override fun section(section: ServiceRuntimePluginSection): Writable = writable {
106106
when (section) {
107-
is ServiceRuntimePluginSection.AdditionalConfig -> {
108-
section.putConfigValue(this) {
109-
rust("#T.clone()", ClientRustModule.Meta.toType().resolve("API_METADATA"))
110-
}
111-
}
112-
113107
is ServiceRuntimePluginSection.RegisterInterceptor -> {
114108
section.registerInterceptor(runtimeConfig, this) {
115109
rust("#T::new()", awsRuntime.resolve("user_agent::UserAgentInterceptor"))
@@ -212,7 +206,9 @@ class UserAgentDecorator : ClientCodegenDecorator {
212206
}
213207

214208
is ServiceConfig.BuilderBuild -> writable {
215-
if (runtimeMode.defaultToMiddleware) {
209+
if (runtimeMode.defaultToOrchestrator) {
210+
rust("layer.put(#T.clone());", ClientRustModule.Meta.toType().resolve("API_METADATA"))
211+
} else {
216212
rust("app_name: self.app_name,")
217213
}
218214
}

aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/SigV4SigningDecoratorTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ internal class SigV4SigningDecoratorTest {
3030
codegenContext,
3131
SigV4SigningConfig(
3232
codegenContext.runtimeConfig,
33+
codegenContext.smithyRuntimeMode,
3334
true,
3435
SigV4Trait.builder().name("test-service").build(),
3536
),

codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/HttpConnectorConfigDecorator.kt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ private class HttpConnectorConfigCustomization(
3838
private val moduleUseName = codegenContext.moduleUseName()
3939
private val codegenScope = arrayOf(
4040
*preludeScope,
41+
"Connection" to RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::orchestrator::Connection"),
42+
"ConnectorSettings" to RuntimeType.smithyClient(runtimeConfig).resolve("http_connector::ConnectorSettings"),
43+
"DynConnectorAdapter" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::connections::adapter::DynConnectorAdapter"),
4144
"HttpConnector" to RuntimeType.smithyClient(runtimeConfig).resolve("http_connector::HttpConnector"),
45+
"SharedAsyncSleep" to RuntimeType.smithyAsync(runtimeConfig).resolve("rt::sleep::SharedAsyncSleep"),
46+
"TimeoutConfig" to RuntimeType.smithyTypes(runtimeConfig).resolve("timeout::TimeoutConfig"),
4247
)
4348

4449
override fun section(section: ServiceConfig): Writable {
@@ -183,7 +188,29 @@ private class HttpConnectorConfigCustomization(
183188
}
184189

185190
is ServiceConfig.BuilderBuild -> writable {
186-
if (runtimeMode.defaultToMiddleware) {
191+
if (runtimeMode.defaultToOrchestrator) {
192+
rustTemplate(
193+
"""
194+
let sleep_impl = layer.load::<#{SharedAsyncSleep}>().cloned();
195+
let timeout_config = layer.load::<#{TimeoutConfig}>().cloned().unwrap_or_else(#{TimeoutConfig}::disabled);
196+
197+
let connector_settings = #{ConnectorSettings}::from_timeout_config(&timeout_config);
198+
199+
if let Some(connection) = layer.load::<#{HttpConnector}>()
200+
.and_then(|c| c.connector(&connector_settings, sleep_impl.clone()))
201+
.or_else(|| #{default_connector}(&connector_settings, sleep_impl)) {
202+
let connection: #{Box}<dyn #{Connection}> = #{Box}::new(#{DynConnectorAdapter}::new(
203+
// TODO(enableNewSmithyRuntimeCleanup): Replace the tower-based DynConnector and remove DynConnectorAdapter when deleting the middleware implementation
204+
connection
205+
)) as _;
206+
layer.set_connection(connection);
207+
}
208+
209+
""",
210+
*codegenScope,
211+
"default_connector" to RuntimeType.smithyClient(runtimeConfig).resolve("conns::default_connector"),
212+
)
213+
} else {
187214
rust("http_connector: self.http_connector,")
188215
}
189216
}

codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/ResiliencyConfigCustomization.kt

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@ package software.amazon.smithy.rust.codegen.client.smithy.customizations
77

88
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
99
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
10-
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
11-
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginSection
1210
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
1311
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
14-
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
1512
import software.amazon.smithy.rust.codegen.core.rustlang.rust
1613
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
1714
import software.amazon.smithy.rust.codegen.core.rustlang.writable
@@ -32,6 +29,7 @@ class ResiliencyConfigCustomization(codegenContext: ClientCodegenContext) : Conf
3229
"RetryConfig" to retryConfig.resolve("RetryConfig"),
3330
"SharedAsyncSleep" to sleepModule.resolve("SharedAsyncSleep"),
3431
"Sleep" to sleepModule.resolve("Sleep"),
32+
"StandardRetryStrategy" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::retries::strategy::StandardRetryStrategy"),
3533
"TimeoutConfig" to timeoutModule.resolve("TimeoutConfig"),
3634
)
3735

@@ -316,7 +314,15 @@ class ResiliencyConfigCustomization(codegenContext: ClientCodegenContext) : Conf
316314
}
317315

318316
ServiceConfig.BuilderBuild -> {
319-
if (runtimeMode.defaultToMiddleware) {
317+
if (runtimeMode.defaultToOrchestrator) {
318+
rustTemplate(
319+
"""
320+
let retry_config = layer.load::<#{RetryConfig}>().cloned().unwrap_or_else(#{RetryConfig}::disabled);
321+
layer.set_retry_strategy(#{StandardRetryStrategy}::new(&retry_config));
322+
""",
323+
*codegenScope,
324+
)
325+
} else {
320326
rustTemplate(
321327
// We call clone on sleep_impl because the field is used by
322328
// initializing the credentials_cache field later in the build
@@ -363,28 +369,3 @@ class ResiliencyReExportCustomization(private val runtimeConfig: RuntimeConfig)
363369
}
364370
}
365371
}
366-
367-
class ResiliencyServiceRuntimePluginCustomization(
368-
private val codegenContext: ClientCodegenContext,
369-
) : ServiceRuntimePluginCustomization() {
370-
override fun section(section: ServiceRuntimePluginSection): Writable = writable {
371-
if (section is ServiceRuntimePluginSection.AdditionalConfig) {
372-
rustTemplate(
373-
"""
374-
if let Some(sleep_impl) = self.handle.conf.sleep_impl() {
375-
${section.newLayerName}.put(sleep_impl);
376-
}
377-
if let Some(timeout_config) = self.handle.conf.timeout_config() {
378-
${section.newLayerName}.put(timeout_config.clone());
379-
}
380-
${section.newLayerName}.put(self.handle.conf.time_source()#{maybe_clone});
381-
""",
382-
"maybe_clone" to writable {
383-
if (codegenContext.smithyRuntimeMode.defaultToMiddleware) {
384-
rust(".clone()")
385-
}
386-
},
387-
)
388-
}
389-
}
390-
}

codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customizations/TimeSourceCustomization.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ class TimeSourceCustomization(codegenContext: ClientCodegenContext) : ConfigCust
114114
ServiceConfig.BuilderBuild -> {
115115
if (runtimeMode.defaultToOrchestrator) {
116116
rustTemplate(
117-
"self.inner.store_put(self.inner.load::<#{SharedTimeSource}>().cloned().unwrap_or_default());",
117+
"layer.store_put(layer.load::<#{SharedTimeSource}>().cloned().unwrap_or_default());",
118118
*codegenScope,
119119
)
120120
} else {

codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customize/RequiredCustomizations.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@ import software.amazon.smithy.rust.codegen.client.smithy.customizations.Idempote
1515
import software.amazon.smithy.rust.codegen.client.smithy.customizations.InterceptorConfigCustomization
1616
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyConfigCustomization
1717
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyReExportCustomization
18-
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyServiceRuntimePluginCustomization
1918
import software.amazon.smithy.rust.codegen.client.smithy.customizations.TimeSourceCustomization
2019
import software.amazon.smithy.rust.codegen.client.smithy.customizations.TimeSourceOperationCustomization
2120
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationCustomization
22-
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
2321
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
2422
import software.amazon.smithy.rust.codegen.core.rustlang.Feature
2523
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
@@ -92,10 +90,4 @@ class RequiredCustomizations : ClientCodegenDecorator {
9290
}
9391
}
9492
}
95-
96-
override fun serviceRuntimePluginCustomizations(
97-
codegenContext: ClientCodegenContext,
98-
baseCustomizations: List<ServiceRuntimePluginCustomization>,
99-
): List<ServiceRuntimePluginCustomization> =
100-
baseCustomizations + listOf(ResiliencyServiceRuntimePluginCustomization(codegenContext))
10193
}

codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/endpoint/EndpointConfigCustomization.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ internal class EndpointConfigCustomization(
3434
val resolverTrait = "#{SmithyResolver}<#{Params}>"
3535
val codegenScope = arrayOf(
3636
*preludeScope,
37+
"DefaultEndpointResolver" to RuntimeType.smithyRuntime(runtimeConfig).resolve("client::orchestrator::endpoints::DefaultEndpointResolver"),
3738
"SharedEndpointResolver" to types.sharedEndpointResolver,
3839
"SmithyResolver" to types.resolveEndpoint,
3940
"Params" to typesGenerator.paramsStruct(),
@@ -165,9 +166,11 @@ internal class EndpointConfigCustomization(
165166
if (runtimeMode.defaultToOrchestrator) {
166167
rustTemplate(
167168
"""
168-
self.inner.store_put(self.inner.load::<$sharedEndpointResolver>().cloned().unwrap_or_else(||
169+
let endpoint_resolver = #{DefaultEndpointResolver}::<#{Params}>::new(
170+
layer.load::<$sharedEndpointResolver>().cloned().unwrap_or_else(||
169171
#{SharedEndpointResolver}::new(#{DefaultResolver}::new())
170172
));
173+
layer.set_endpoint_resolver(endpoint_resolver);
171174
""",
172175
*codegenScope,
173176
"DefaultResolver" to defaultResolver,
@@ -206,7 +209,11 @@ internal class EndpointConfigCustomization(
206209
if (runtimeMode.defaultToOrchestrator) {
207210
rustTemplate(
208211
"""
209-
self.inner.store_put(self.inner.load::<$sharedEndpointResolver>().cloned().unwrap_or_else(||#{SharedEndpointResolver}::new(#{FailingResolver})));
212+
let endpoint_resolver = #{DefaultEndpointResolver}::<#{Params}>::new(
213+
layer.load::<$sharedEndpointResolver>().cloned().unwrap_or_else(||
214+
#{SharedEndpointResolver}::new(#{FailingResolver})
215+
).clone());
216+
layer.set_endpoint_resolver(endpoint_resolver);
210217
""",
211218
*codegenScope,
212219
"FailingResolver" to alwaysFailsResolver,

0 commit comments

Comments
 (0)