Skip to content

Commit

Permalink
Make service config builder contain CloneableLayer (#2795)
Browse files Browse the repository at this point in the history
## Motivation and Context
This PR will reduce fields in service config builders to contain only
`CloneableLayer` (except for `interceptors` and `identity_resolvers`).

## Description
This is the third PR in a series of config refactoring in the
orchestrator mode. Just like #2762, this PR reduces fields in service
config builders to contain `CloneableLayer`.

The code changes follow a straightforward pattern where builders'
setters are implemented via a config layer.

## Testing
Relies on the existing 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 <[email protected]>
Co-authored-by: Zelda Hessler <[email protected]>
  • Loading branch information
3 people authored Jun 21, 2023
1 parent 47718f9 commit df62f5c
Show file tree
Hide file tree
Showing 16 changed files with 510 additions and 202 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,25 @@ class AwsFluentClientDecorator : ClientCodegenDecorator {
baseGenerator.protocolSupport,
baseGenerator.operationShape,
renderClientCreation = { params ->
rust("let mut ${params.configBuilderName} = ${params.configBuilderName};")
if (codegenContext.smithyRuntimeMode.defaultToOrchestrator) {
// TODO(enableNewSmithyRuntimeLaunch): A builder field could not be accessed directly in the orchestrator
// mode when this code change was made. smithy-rs#2792 will enable us to use getters in builders.
// Make this `set_region` conditional by checking if `config_builder.region().is_none()` once the PR
// has been merged to main.
rust("""${params.configBuilderName}.set_region(Some(crate::config::Region::new("us-east-1")));""")
} else {
rust(
"""
// If the test case was missing endpoint parameters, default a region so it doesn't fail
if ${params.configBuilderName}.region.is_none() {
${params.configBuilderName}.set_region(Some(crate::config::Region::new("us-east-1")));
}
""",
)
}
rustTemplate(
"""
// If the test case was missing endpoint parameters, default a region so it doesn't fail
let mut ${params.configBuilderName} = ${params.configBuilderName};
if ${params.configBuilderName}.region.is_none() {
${params.configBuilderName}.set_region(Some(crate::config::Region::new("us-east-1")));
}
let config = ${params.configBuilderName}.http_connector(${params.connectorName}).build();
let ${params.clientName} = #{Client}::from_conf(config);
""",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
import software.amazon.smithy.rust.codegen.core.smithy.customize.adhocCustomization

Expand Down Expand Up @@ -53,8 +55,10 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
private val runtimeConfig = codegenContext.runtimeConfig
private val runtimeMode = codegenContext.smithyRuntimeMode
private val codegenScope = arrayOf(
*preludeScope,
"CredentialsCache" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("cache::CredentialsCache"),
"DefaultProvider" to defaultProvider(),
"SharedAsyncSleep" to RuntimeType.smithyAsync(runtimeConfig).resolve("rt::sleep::SharedAsyncSleep"),
"SharedCredentialsCache" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("cache::SharedCredentialsCache"),
"SharedCredentialsProvider" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("provider::SharedCredentialsProvider"),
)
Expand Down Expand Up @@ -95,35 +99,57 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
}

ServiceConfig.BuilderStruct ->
rustTemplate("credentials_cache: Option<#{CredentialsCache}>,", *codegenScope)
if (runtimeMode.defaultToMiddleware) {
rustTemplate("credentials_cache: #{Option}<#{CredentialsCache}>,", *codegenScope)
}

ServiceConfig.BuilderImpl -> {
rustTemplate(
"""
/// Sets the credentials cache for this service
pub fn credentials_cache(mut self, credentials_cache: #{CredentialsCache}) -> Self {
self.set_credentials_cache(Some(credentials_cache));
self.set_credentials_cache(#{Some}(credentials_cache));
self
}
/// Sets the credentials cache for this service
pub fn set_credentials_cache(&mut self, credentials_cache: Option<#{CredentialsCache}>) -> &mut Self {
self.credentials_cache = credentials_cache;
self
}
""",
*codegenScope,
)

if (runtimeMode.defaultToOrchestrator) {
rustTemplate(
"""
/// Sets the credentials cache for this service
pub fn set_credentials_cache(&mut self, credentials_cache: #{Option}<#{CredentialsCache}>) -> &mut Self {
self.inner.store_or_unset(credentials_cache);
self
}
""",
*codegenScope,
)
} else {
rustTemplate(
"""
/// Sets the credentials cache for this service
pub fn set_credentials_cache(&mut self, credentials_cache: Option<#{CredentialsCache}>) -> &mut Self {
self.credentials_cache = credentials_cache;
self
}
""",
*codegenScope,
)
}
}

ServiceConfig.BuilderBuild -> {
if (runtimeMode.defaultToOrchestrator) {
rustTemplate(
"""
layer.store_put(
self.credentials_cache
self.inner.store_put(
self.inner.load::<#{CredentialsCache}>()
.cloned()
.unwrap_or_else({
let sleep = self.sleep_impl.clone();
let sleep = self.inner.load::<#{SharedAsyncSleep}>().cloned();
|| match sleep {
Some(sleep) => {
#{CredentialsCache}::lazy_builder()
Expand All @@ -133,9 +159,9 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
None => #{CredentialsCache}::lazy(),
}
})
.create_cache(self.credentials_provider.unwrap_or_else(|| {
.create_cache(self.inner.load::<#{SharedCredentialsProvider}>().cloned().unwrap_or_else(|| {
#{SharedCredentialsProvider}::new(#{DefaultProvider})
})),
}))
);
""",
*codegenScope,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import software.amazon.smithy.rust.codegen.core.rustlang.Writable
import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
import software.amazon.smithy.rust.codegen.core.smithy.customize.adhocCustomization
Expand All @@ -40,7 +40,7 @@ class CredentialsProviderDecorator : ClientCodegenDecorator {
codegenContext: ClientCodegenContext,
baseCustomizations: List<ConfigCustomization>,
): List<ConfigCustomization> {
return baseCustomizations + CredentialProviderConfig(codegenContext.runtimeConfig)
return baseCustomizations + CredentialProviderConfig(codegenContext)
}

override fun extraSections(codegenContext: ClientCodegenContext): List<AdHocCustomization> =
Expand All @@ -65,38 +65,63 @@ class CredentialsProviderDecorator : ClientCodegenDecorator {
/**
* Add a `.credentials_provider` field and builder to the `Config` for a given service
*/
class CredentialProviderConfig(runtimeConfig: RuntimeConfig) : ConfigCustomization() {
class CredentialProviderConfig(codegenContext: ClientCodegenContext) : ConfigCustomization() {
private val smithyRuntimeMode = codegenContext.smithyRuntimeMode
private val runtimeConfig = codegenContext.runtimeConfig
private val codegenScope = arrayOf(
"provider" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("provider"),
*preludeScope,
"Credentials" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("Credentials"),
"ProvideCredentials" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("provider::ProvideCredentials"),
"SharedCredentialsProvider" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("provider::SharedCredentialsProvider"),
"TestCredentials" to AwsRuntimeType.awsCredentialTypesTestUtil(runtimeConfig).resolve("Credentials"),
)

override fun section(section: ServiceConfig) = writable {
when (section) {
ServiceConfig.BuilderStruct ->
rustTemplate("credentials_provider: Option<#{provider}::SharedCredentialsProvider>,", *codegenScope)
ServiceConfig.BuilderStruct -> {
if (smithyRuntimeMode.defaultToMiddleware) {
rustTemplate("credentials_provider: #{Option}<#{SharedCredentialsProvider}>,", *codegenScope)
}
}
ServiceConfig.BuilderImpl -> {
rustTemplate(
"""
/// Sets the credentials provider for this service
pub fn credentials_provider(mut self, credentials_provider: impl #{provider}::ProvideCredentials + 'static) -> Self {
self.set_credentials_provider(Some(#{provider}::SharedCredentialsProvider::new(credentials_provider)));
self
}
/// Sets the credentials provider for this service
pub fn set_credentials_provider(&mut self, credentials_provider: Option<#{provider}::SharedCredentialsProvider>) -> &mut Self {
self.credentials_provider = credentials_provider;
pub fn credentials_provider(mut self, credentials_provider: impl #{ProvideCredentials} + 'static) -> Self {
self.set_credentials_provider(#{Some}(#{SharedCredentialsProvider}::new(credentials_provider)));
self
}
""",
*codegenScope,
)

if (smithyRuntimeMode.defaultToOrchestrator) {
rustTemplate(
"""
/// Sets the credentials provider for this service
pub fn set_credentials_provider(&mut self, credentials_provider: #{Option}<#{SharedCredentialsProvider}>) -> &mut Self {
self.inner.store_or_unset(credentials_provider);
self
}
""",
*codegenScope,
)
} else {
rustTemplate(
"""
/// Sets the credentials provider for this service
pub fn set_credentials_provider(&mut self, credentials_provider: #{Option}<#{SharedCredentialsProvider}>) -> &mut Self {
self.credentials_provider = credentials_provider;
self
}
""",
*codegenScope,
)
}
}

is ServiceConfig.DefaultForTests -> rustTemplate(
"${section.configBuilderRef}.set_credentials_provider(Some(#{provider}::SharedCredentialsProvider::new(#{TestCredentials}::for_tests())));",
"${section.configBuilderRef}.set_credentials_provider(Some(#{SharedCredentialsProvider}::new(#{TestCredentials}::for_tests())));",
*codegenScope,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
import software.amazon.smithy.rust.codegen.core.util.letIf

// TODO(enableNewSmithyRuntimeCleanup): Delete this decorator since it's now in `codegen-client`
Expand All @@ -37,6 +38,7 @@ class HttpConnectorConfigCustomization(
private val runtimeMode = codegenContext.smithyRuntimeMode
private val moduleUseName = codegenContext.moduleUseName()
private val codegenScope = arrayOf(
*preludeScope,
"HttpConnector" to RuntimeType.smithyClient(runtimeConfig).resolve("http_connector::HttpConnector"),
)

Expand Down Expand Up @@ -71,7 +73,9 @@ class HttpConnectorConfigCustomization(
}
}
is ServiceConfig.BuilderStruct -> writable {
rustTemplate("http_connector: Option<#{HttpConnector}>,", *codegenScope)
if (runtimeMode.defaultToMiddleware) {
rustTemplate("http_connector: Option<#{HttpConnector}>,", *codegenScope)
}
}
ServiceConfig.BuilderImpl -> writable {
rustTemplate(
Expand Down Expand Up @@ -108,7 +112,7 @@ class HttpConnectorConfigCustomization(
/// ## }
/// ```
pub fn http_connector(mut self, http_connector: impl Into<#{HttpConnector}>) -> Self {
self.http_connector = Some(http_connector.into());
self.set_http_connector(#{Some}(http_connector));
self
}
Expand Down Expand Up @@ -150,18 +154,33 @@ class HttpConnectorConfigCustomization(
/// ## }
/// ## }
/// ```
pub fn set_http_connector(&mut self, http_connector: Option<impl Into<#{HttpConnector}>>) -> &mut Self {
self.http_connector = http_connector.map(|inner| inner.into());
self
}
""",
*codegenScope,
)
}
is ServiceConfig.BuilderBuild -> writable {
if (runtimeMode.defaultToOrchestrator) {
rust("layer.store_or_unset(self.http_connector);")
rustTemplate(
"""
pub fn set_http_connector(&mut self, http_connector: #{Option}<impl #{Into}<#{HttpConnector}>>) -> &mut Self {
http_connector.map(|c| self.inner.store_put(c.into()));
self
}
""",
*codegenScope,
)
} else {
rustTemplate(
"""
pub fn set_http_connector(&mut self, http_connector: #{Option}<impl #{Into}<#{HttpConnector}>>) -> &mut Self {
self.http_connector = http_connector.map(|inner| inner.into());
self
}
""",
*codegenScope,
)
}
}
is ServiceConfig.BuilderBuild -> writable {
if (runtimeMode.defaultToMiddleware) {
rust("http_connector: self.http_connector,")
}
}
Expand Down
Loading

0 comments on commit df62f5c

Please sign in to comment.