Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rcoh committed Nov 14, 2023
1 parent d7736a8 commit d6a5881
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ async fn test_clients_from_service_config() {
}

#[tokio::test]
#[should_panic(expected = "Invalid client configuration: A behavior major version must be set.")]
#[should_panic(expected = "Invalid client configuration: A behavior major version must be set")]
async fn test_missing_behavior_major_version() {
use aws_sdk_s3::config::Region;
let http_client =
Expand Down Expand Up @@ -95,6 +95,7 @@ async fn test_missing_async_sleep_time_source_retries() {
.credentials_provider(Credentials::for_tests())
.retry_config(RetryConfig::standard())
.timeout_config(TimeoutConfig::disabled())
.behavior_major_version(BehaviorMajorVersion::latest())
.build();

// should panic with a validation error
Expand All @@ -115,6 +116,7 @@ async fn test_missing_async_sleep_time_source_timeouts() {
.region(Region::new("us-east-1"))
.credentials_provider(Credentials::for_tests())
.retry_config(RetryConfig::disabled())
.behavior_major_version(BehaviorMajorVersion::latest())
.timeout_config(
TimeoutConfig::builder()
.operation_timeout(Duration::from_secs(5))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
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
Expand All @@ -26,67 +25,5 @@ class BehaviorMajorVersionDecorator(codegenContext: ClientCodegenContext) : Conf
}

override fun section(section: ServiceConfig): Writable = writable {
when (section) {
is ServiceConfig.BuilderImpl -> {
val docs = """
/// Sets the [`behavior major version`](crate::config::BehaviorMajorVersion).
///
/// Over time, new best-practice behaviors are introduced. However, these behaviors might not be backwards
/// compatible. For example, a change which introduces new default timeouts or a new retry-mode for
/// all operations might be the ideal behavior but could break existing applications.
///
/// ## Examples
///
/// Set the behavior major version to `latest`. This is equivalent to enabling the `behavior-version-latest` cargo feature.
/// ```no_run
/// use $moduleUseName::config::BehaviorMajorVersion;
///
/// let config = $moduleUseName::Config::builder()
/// .behavior_major_version(BehaviorMajorVersion::latest())
/// // ...
/// .build();
/// let client = $moduleUseName::Client::from_conf(config);
/// ```
///
/// Customizing behavior major version:
/// ```no_run
/// use $moduleUseName::config::BehaviorMajorVersion;
///
/// let config = $moduleUseName::Config::builder()
/// .behavior_major_version(BehaviorMajorVersion::v2023_11_09())
/// // ...
/// .build();
/// let client = $moduleUseName::Client::from_conf(config);
/// ```
"""
rustTemplate(
"""
$docs
pub fn behavior_major_version(mut self, behavior_major_version: crate::config::BehaviorMajorVersion) -> Self {
self.set_behavior_major_version(Some(behavior_major_version));
self
}
$docs
pub fn set_behavior_major_version(&mut self, behavior_major_version: Option<crate::config::BehaviorMajorVersion>) -> &mut Self {
self.runtime_components.set_behavior_major_version(behavior_major_version);
self
}
""",
*codegenScope,
)
}
is ServiceConfig.DefaultForTests -> {
rustTemplate("${section.configBuilderRef}.set_behavior_major_version(Some(crate::config::BehaviorMajorVersion::latest()));")
}

is ServiceConfig.BuilderStruct -> {
rustTemplate("builder_mv: #{Option}<#{BehaviorMajorVersion}>", *codegenScope)
}
is ServiceConfig.ConfigStruct -> {
rustTemplate("builder_mv: #{Option}<#{BehaviorMajorVersion}>", *codegenScope)
}
else -> { }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,12 @@ class ClientRuntimeTypesReExportGenerator(
pub use #{ConfigBag};
pub use #{RuntimeComponents};
pub use #{IdentityCache};
pub use #{BehaviorMajorVersion};
""",
"ConfigBag" to RuntimeType.configBag(rc),
"Intercept" to RuntimeType.intercept(rc),
"RuntimeComponents" to RuntimeType.runtimeComponents(rc),
"SharedInterceptor" to RuntimeType.sharedInterceptor(rc),
"IdentityCache" to RuntimeType.smithyRuntime(rc).resolve("client::identity::IdentityCache"),
"BehaviorMajorVersion" to RuntimeType.smithyRuntimeApi(rc).resolve("client::behavior_version::BehaviorMajorVersion"),
)
}
rustCrate.withModule(ClientRustModule.Config.endpoint) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,19 +458,26 @@ private fun baseClientRuntimePluginsFn(codegenContext: ClientCodegenContext): Ru
RuntimeType.forInlineFun("base_client_runtime_plugins", ClientRustModule.config) {
val api = RuntimeType.smithyRuntimeApiClient(rc)
val rt = RuntimeType.smithyRuntime(rc)
val behaviorVersionError = "Invalid client configuration: A behavior major version must be set when sending a " +
"request or constructing a client. You must set it during client construction or by enabling the " +
"`${BehaviorVersionLatest.name}` cargo feature."
rustTemplate(
"""
pub(crate) fn base_client_runtime_plugins(
mut config: crate::Config,
) -> #{RuntimePlugins} {
let mut configured_plugins = #{Vec}::new();
::std::mem::swap(&mut config.runtime_plugins, &mut configured_plugins);
##[allow(unused_mut)]
let mut behavior_major_version = config.behavior_major_version.clone();
#{update_bmv}
let mut plugins = #{RuntimePlugins}::new()
// defaults
.with_client_plugins(#{default_plugins}(
#{DefaultPluginParams}::new()
.with_retry_partition_name(${codegenContext.serviceShape.sdkId().dq()})
.with_behavior_major_version(behavior_major_version.expect(${behaviorVersionError.dq()}))
))
// user config
.with_client_plugin(
Expand All @@ -482,7 +489,6 @@ private fun baseClientRuntimePluginsFn(codegenContext: ClientCodegenContext): Ru
.with_client_plugin(crate::config::ServiceRuntimePlugin::new(config))
.with_client_plugin(#{NoAuthRuntimePlugin}::new());
#{behavior_major_version}
for plugin in configured_plugins {
plugins = plugins.with_client_plugin(plugin);
}
Expand All @@ -495,12 +501,15 @@ private fun baseClientRuntimePluginsFn(codegenContext: ClientCodegenContext): Ru
"NoAuthRuntimePlugin" to rt.resolve("client::auth::no_auth::NoAuthRuntimePlugin"),
"RuntimePlugins" to RuntimeType.runtimePlugins(rc),
"StaticRuntimePlugin" to api.resolve("client::runtime_plugin::StaticRuntimePlugin"),
"behavior_major_version" to featureGatedBlock(BehaviorVersionLatest) {
"update_bmv" to featureGatedBlock(BehaviorVersionLatest) {
rustTemplate(
"""
plugins = plugins.with_client_plugin(#{BehaviorVersionLatestRuntimePlugin}::new());
if behavior_major_version.is_none() {
behavior_major_version = Some(#{BehaviorMajorVersion}::latest());
}
""",
"BehaviorVersionLatestRuntimePlugin" to api.resolve("client::behavior_version::LatestBehaviorVersionRuntimePlugin"),
"BehaviorMajorVersion" to api.resolve("client::behavior_version::BehaviorMajorVersion"),
)
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,37 +189,38 @@ fun loadFromConfigBag(innerTypeName: String, newtype: RuntimeType): Writable = w
* 2. convenience setter (non-optional)
* 3. standard setter (&mut self)
*/
fun standardConfigParam(param: ConfigParam, codegenContext: ClientCodegenContext): ConfigCustomization = object : ConfigCustomization() {
override fun section(section: ServiceConfig): Writable {
return when (section) {
ServiceConfig.BuilderImpl -> writable {
docsOrFallback(param.setterDocs)
rust(
"""
pub fn ${param.name}(mut self, ${param.name}: impl Into<#T>) -> Self {
self.set_${param.name}(Some(${param.name}.into()));
self
fun standardConfigParam(param: ConfigParam, codegenContext: ClientCodegenContext): ConfigCustomization =
object : ConfigCustomization() {
override fun section(section: ServiceConfig): Writable {
return when (section) {
ServiceConfig.BuilderImpl -> writable {
docsOrFallback(param.setterDocs)
rust(
"""
pub fn ${param.name}(mut self, ${param.name}: impl Into<#T>) -> Self {
self.set_${param.name}(Some(${param.name}.into()));
self
}""",
param.type,
)
param.type,
)

docsOrFallback(param.setterDocs)
rustTemplate(
"""
pub fn set_${param.name}(&mut self, ${param.name}: Option<#{T}>) -> &mut Self {
self.config.store_or_unset(${param.name}.map(#{newtype}));
self
}
""",
"T" to param.type,
"newtype" to param.newtype!!,
)
}
docsOrFallback(param.setterDocs)
rustTemplate(
"""
pub fn set_${param.name}(&mut self, ${param.name}: Option<#{T}>) -> &mut Self {
self.config.store_or_unset(${param.name}.map(#{newtype}));
self
}
""",
"T" to param.type,
"newtype" to param.newtype!!,
)
}

else -> emptySection
else -> emptySection
}
}
}
}

fun ServiceShape.needsIdempotencyToken(model: Model): Boolean {
val operationIndex = OperationIndex.of(model)
Expand Down Expand Up @@ -279,8 +280,69 @@ class ServiceConfigGenerator(
"RuntimePlugin" to configReexport(RuntimeType.runtimePlugin(runtimeConfig)),
"SharedRuntimePlugin" to configReexport(RuntimeType.sharedRuntimePlugin(runtimeConfig)),
"runtime_plugin" to RuntimeType.smithyRuntimeApiClient(runtimeConfig).resolve("client::runtime_plugin"),
"BehaviorMajorVersion" to configReexport(
RuntimeType.smithyRuntimeApi(runtimeConfig).resolve("client::behavior_version::BehaviorMajorVersion"),
),
)

private fun behaviorMv() = writable {
val docs = """
/// Sets the [`behavior major version`](crate::config::BehaviorMajorVersion).
///
/// Over time, new best-practice behaviors are introduced. However, these behaviors might not be backwards
/// compatible. For example, a change which introduces new default timeouts or a new retry-mode for
/// all operations might be the ideal behavior but could break existing applications.
///
/// ## Examples
///
/// Set the behavior major version to `latest`. This is equivalent to enabling the `behavior-version-latest` cargo feature.
/// ```no_run
/// use $moduleUseName::config::BehaviorMajorVersion;
///
/// let config = $moduleUseName::Config::builder()
/// .behavior_major_version(BehaviorMajorVersion::latest())
/// // ...
/// .build();
/// let client = $moduleUseName::Client::from_conf(config);
/// ```
///
/// Customizing behavior major version:
/// ```no_run
/// use $moduleUseName::config::BehaviorMajorVersion;
///
/// let config = $moduleUseName::Config::builder()
/// .behavior_major_version(BehaviorMajorVersion::v2023_11_09())
/// // ...
/// .build();
/// let client = $moduleUseName::Client::from_conf(config);
/// ```
"""
rustTemplate(
"""
$docs
pub fn behavior_major_version(mut self, behavior_major_version: crate::config::BehaviorMajorVersion) -> Self {
self.set_behavior_major_version(Some(behavior_major_version));
self
}
$docs
pub fn set_behavior_major_version(&mut self, behavior_major_version: Option<crate::config::BehaviorMajorVersion>) -> &mut Self {
self.behavior_major_version = behavior_major_version;
self
}
/// Convenience method to set the latest behavior major version
///
/// This is equivalent to enabling the `behavior-version-latest` Cargo feature
pub fn behavior_major_version_latest(mut self) -> Self {
self.set_behavior_major_version(Some(crate::config::BehaviorMajorVersion::latest()));
self
}
""",
*codegenScope,
)
}

fun render(writer: RustWriter) {
writer.docs("Configuration for a $moduleUseName service client.\n")
customizations.forEach {
Expand All @@ -297,6 +359,7 @@ class ServiceConfigGenerator(
cloneable: #{CloneableLayer},
pub(crate) runtime_components: #{RuntimeComponentsBuilder},
pub(crate) runtime_plugins: #{Vec}<#{SharedRuntimePlugin}>,
behavior_major_version: #{Option}<#{BehaviorMajorVersion}>,
""",
*codegenScope,
)
Expand All @@ -320,6 +383,7 @@ class ServiceConfigGenerator(
config: self.cloneable.clone(),
runtime_components: self.runtime_components.clone(),
runtime_plugins: self.runtime_plugins.clone(),
behavior_major_version: self.behavior_major_version.clone(),
}
}
""",
Expand All @@ -337,6 +401,7 @@ class ServiceConfigGenerator(
pub(crate) config: #{CloneableLayer},
pub(crate) runtime_components: #{RuntimeComponentsBuilder},
pub(crate) runtime_plugins: #{Vec}<#{SharedRuntimePlugin}>,
pub(crate) behavior_major_version: #{Option}<#{BehaviorMajorVersion}>,
""",
*codegenScope,
)
Expand All @@ -354,6 +419,7 @@ class ServiceConfigGenerator(
config: #{Default}::default(),
runtime_components: #{RuntimeComponentsBuilder}::new("service config"),
runtime_plugins: #{Default}::default(),
behavior_major_version: #{Default}::default(),
}
}
""",
Expand All @@ -367,11 +433,18 @@ class ServiceConfigGenerator(
customizations.forEach {
it.section(ServiceConfig.BuilderImpl)(this)
}
behaviorMv()(this)

val visibility = if (enableUserConfigurableRuntimePlugins) { "pub" } else { "pub(crate)" }
val visibility = if (enableUserConfigurableRuntimePlugins) {
"pub"
} else {
"pub(crate)"
}

docs("Adds a runtime plugin to the config.")
if (!enableUserConfigurableRuntimePlugins) { Attribute.AllowUnused.render(this) }
if (!enableUserConfigurableRuntimePlugins) {
Attribute.AllowUnused.render(this)
}
rustTemplate(
"""
$visibility fn runtime_plugin(mut self, plugin: impl #{RuntimePlugin} + 'static) -> Self {
Expand All @@ -382,7 +455,9 @@ class ServiceConfigGenerator(
*codegenScope,
)
docs("Adds a runtime plugin to the config.")
if (!enableUserConfigurableRuntimePlugins) { Attribute.AllowUnused.render(this) }
if (!enableUserConfigurableRuntimePlugins) {
Attribute.AllowUnused.render(this)
}
rustTemplate(
"""
$visibility fn push_runtime_plugin(&mut self, plugin: #{SharedRuntimePlugin}) -> &mut Self {
Expand Down Expand Up @@ -433,6 +508,7 @@ class ServiceConfigGenerator(
cloneable: layer,
runtime_components: self.runtime_components,
runtime_plugins: self.runtime_plugins,
behavior_major_version: self.behavior_major_version,
""",
*codegenScope,
)
Expand Down
Loading

0 comments on commit d6a5881

Please sign in to comment.