Skip to content

Commit e8449bd

Browse files
aajtoddjdisantiysaito1001
authored
behavior version 2024-03-28 (#3617)
## Motivation and Context This PR is the combination of two previously reviewed PRs that both enable new behaviors behind a new Behavior Major Version (BMV): * #3527 * #3578 ## Description * Enables stalled stream protection by default on latest behavior version. * Enables creation of a default identity cache. ## Testing All testing done on prior PRs. See for details. ## Checklist <!--- If a checkbox below is not applicable, then please DELETE it rather than leaving it unchecked --> - [x] I have updated `CHANGELOG.next.toml` if I made changes to the smithy-rs codegen or runtime crates - [x] I have updated `CHANGELOG.next.toml` if I made changes to the AWS SDK, generated SDK code, or SDK runtime crates ---- _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: John DiSanti <jdisanti@amazon.com> Co-authored-by: ysaito1001 <awsaito@amazon.com>
1 parent 6aec38f commit e8449bd

File tree

17 files changed

+197
-88
lines changed

17 files changed

+197
-88
lines changed

CHANGELOG.next.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,28 @@
1010
# references = ["smithy-rs#920"]
1111
# meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client | server | all"}
1212
# author = "rcoh"
13+
[[aws-sdk-rust]]
14+
message = """
15+
`aws-config::loader::ConfigLoader` now creates an `IdentityCache` by default when using `BehaviorVersion::v2024_03_28()`
16+
or newer. If you're using `BehaviorVersion::latest()`, you will get this change automatically when updating. This
17+
allows clients created from `SdkConfig` to use the same cache instance by default resulting in fewer cache misses
18+
when using multiple clients.
19+
"""
20+
references = ["smithy-rs#3427"]
21+
meta = { "breaking" = false, "tada" = true, "bug" = false }
22+
author = "aajtodd"
1323

24+
[[smithy-rs]]
25+
message = "Stalled stream protection on uploads is now enabled by default behind `BehaviorVersion::v2024_03_28()`. If you're using `BehaviorVersion::latest()`, you will get this change automatically by running `cargo update`."
26+
references = ["smithy-rs#3527"]
27+
meta = { "breaking" = true, "tada" = true, "bug" = false }
28+
authors = ["jdisanti"]
29+
30+
[[aws-sdk-rust]]
31+
message = "Stalled stream protection on uploads is now enabled by default behind `BehaviorVersion::v2024_03_28()`. If you're using `BehaviorVersion::latest()`, you will get this change automatically by running `cargo update`. Updating your SDK is not necessary, this change will happen when a new version of the client libraries are consumed."
32+
references = ["smithy-rs#3527"]
33+
meta = { "breaking" = true, "tada" = true, "bug" = false }
34+
author = "jdisanti"
1435

1536
[[smithy-rs]]
1637
message = "Implement Debug for DateTime"

aws/rust-runtime/aws-config/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "aws-config"
3-
version = "1.3.0"
3+
version = "1.4.0"
44
authors = [
55
"AWS Rust SDK Team <aws-sdk-rust@amazon.com>",
66
"Russell Cohen <rcoh@amazon.com>",

aws/rust-runtime/aws-config/src/lib.rs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ mod loader {
214214
use aws_credential_types::Credentials;
215215
use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep, SharedAsyncSleep};
216216
use aws_smithy_async::time::{SharedTimeSource, TimeSource};
217+
use aws_smithy_runtime::client::identity::IdentityCache;
217218
use aws_smithy_runtime_api::client::behavior_version::BehaviorVersion;
218219
use aws_smithy_runtime_api::client::http::HttpClient;
219220
use aws_smithy_runtime_api::client::identity::{ResolveCachedIdentity, SharedIdentityCache};
@@ -238,14 +239,14 @@ mod loader {
238239
use crate::provider_config::ProviderConfig;
239240

240241
#[derive(Default, Debug)]
241-
enum CredentialsProviderOption {
242-
/// No provider was set by the user. We can set up the default credentials provider chain.
242+
enum TriStateOption<T> {
243+
/// No option was set by the user. We can set up the default.
243244
#[default]
244245
NotSet,
245-
/// The credentials provider was explicitly unset. Do not set up a default chain.
246+
/// The option was explicitly unset. Do not set up a default.
246247
ExplicitlyUnset,
247-
/// Use the given credentials provider.
248-
Set(SharedCredentialsProvider),
248+
/// Use the given user provided option.
249+
Set(T),
249250
}
250251

251252
/// Load a cross-service [`SdkConfig`] from the environment
@@ -258,7 +259,7 @@ mod loader {
258259
pub struct ConfigLoader {
259260
app_name: Option<AppName>,
260261
identity_cache: Option<SharedIdentityCache>,
261-
credentials_provider: CredentialsProviderOption,
262+
credentials_provider: TriStateOption<SharedCredentialsProvider>,
262263
token_provider: Option<SharedTokenProvider>,
263264
endpoint_url: Option<String>,
264265
region: Option<Box<dyn ProvideRegion>>,
@@ -464,9 +465,8 @@ mod loader {
464465
mut self,
465466
credentials_provider: impl ProvideCredentials + 'static,
466467
) -> Self {
467-
self.credentials_provider = CredentialsProviderOption::Set(
468-
SharedCredentialsProvider::new(credentials_provider),
469-
);
468+
self.credentials_provider =
469+
TriStateOption::Set(SharedCredentialsProvider::new(credentials_provider));
470470
self
471471
}
472472

@@ -492,7 +492,7 @@ mod loader {
492492
/// # }
493493
/// ```
494494
pub fn no_credentials(mut self) -> Self {
495-
self.credentials_provider = CredentialsProviderOption::ExplicitlyUnset;
495+
self.credentials_provider = TriStateOption::ExplicitlyUnset;
496496
self
497497
}
498498

@@ -781,14 +781,14 @@ mod loader {
781781
timeout_config.take_defaults_from(&base_config);
782782

783783
let credentials_provider = match self.credentials_provider {
784-
CredentialsProviderOption::Set(provider) => Some(provider),
785-
CredentialsProviderOption::NotSet => {
784+
TriStateOption::Set(provider) => Some(provider),
785+
TriStateOption::NotSet => {
786786
let mut builder =
787787
credentials::DefaultCredentialsChain::builder().configure(conf.clone());
788788
builder.set_region(region.clone());
789789
Some(SharedCredentialsProvider::new(builder.build().await))
790790
}
791-
CredentialsProviderOption::ExplicitlyUnset => None,
791+
TriStateOption::ExplicitlyUnset => None,
792792
};
793793

794794
let token_provider = match self.token_provider {
@@ -851,7 +851,18 @@ mod loader {
851851
builder.set_behavior_version(self.behavior_version);
852852
builder.set_http_client(self.http_client);
853853
builder.set_app_name(app_name);
854-
builder.set_identity_cache(self.identity_cache);
854+
855+
let identity_cache = match self.identity_cache {
856+
None => match self.behavior_version {
857+
Some(bv) if bv.is_at_least(BehaviorVersion::v2024_03_28()) => {
858+
Some(IdentityCache::lazy().build())
859+
}
860+
_ => None,
861+
},
862+
Some(user_cache) => Some(user_cache),
863+
};
864+
865+
builder.set_identity_cache(identity_cache);
855866
builder.set_credentials_provider(credentials_provider);
856867
builder.set_token_provider(token_provider);
857868
builder.set_sleep_impl(sleep_impl);
@@ -1055,10 +1066,26 @@ mod loader {
10551066
.no_credentials()
10561067
.load()
10571068
.await;
1058-
assert!(config.identity_cache().is_none());
10591069
assert!(config.credentials_provider().is_none());
10601070
}
10611071

1072+
#[cfg(feature = "rustls")]
1073+
#[tokio::test]
1074+
async fn identity_cache_defaulted() {
1075+
let config = defaults(BehaviorVersion::latest()).load().await;
1076+
1077+
assert!(config.identity_cache().is_some());
1078+
}
1079+
1080+
#[cfg(feature = "rustls")]
1081+
#[allow(deprecated)]
1082+
#[tokio::test]
1083+
async fn identity_cache_old_behavior_version() {
1084+
let config = defaults(BehaviorVersion::v2023_11_09()).load().await;
1085+
1086+
assert!(config.identity_cache().is_none());
1087+
}
1088+
10621089
#[tokio::test]
10631090
async fn connector_is_shared() {
10641091
let num_requests = Arc::new(AtomicUsize::new(0));

aws/rust-runtime/aws-inlineable/src/s3_express.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ pub(crate) mod identity_provider {
544544
config_bag: &'a ConfigBag,
545545
) -> Result<SessionCredentials, BoxError> {
546546
let mut config_builder = crate::config::Builder::from_config_bag(config_bag)
547-
.behavior_version(self.behavior_version.clone());
547+
.behavior_version(self.behavior_version);
548548

549549
// inherits all runtime components from a current S3 operation but clears out
550550
// out interceptors configured for that operation

aws/rust-runtime/aws-types/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "aws-types"
3-
version = "1.2.0"
3+
version = "1.2.1"
44
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>", "Russell Cohen <rcoh@amazon.com>"]
55
description = "Cross-service types for the AWS SDK."
66
edition = "2021"

aws/rust-runtime/aws-types/src/sdk_config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -810,9 +810,9 @@ impl SdkConfig {
810810
self.stalled_stream_protection_config.clone()
811811
}
812812

813-
/// Behavior major version configured for this client
813+
/// Behavior version configured for this client
814814
pub fn behavior_version(&self) -> Option<BehaviorVersion> {
815-
self.behavior_version.clone()
815+
self.behavior_version
816816
}
817817

818818
/// Return an immutable reference to the service config provider configured for this client.

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/S3ExpressDecorator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ private class S3ExpressServiceRuntimePluginCustomization(codegenContext: ClientC
155155
rustTemplate(
156156
"""
157157
#{DefaultS3ExpressIdentityProvider}::builder()
158-
.behavior_version(${section.serviceConfigName}.behavior_version.clone().expect(${behaviorVersionError.dq()}))
158+
.behavior_version(${section.serviceConfigName}.behavior_version.expect(${behaviorVersionError.dq()}))
159159
.time_source(${section.serviceConfigName}.time_source().unwrap_or_default())
160160
.build()
161161
""",

aws/sdk/integration-tests/no-default-features/tests/client-construction.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ async fn test_time_source_for_identity_cache() {
152152
let _client = aws_sdk_s3::Client::from_conf(config);
153153
}
154154

155+
#[allow(deprecated)] // intentionally testing an old behavior version
155156
#[tokio::test]
156157
async fn behavior_mv_from_aws_config() {
157158
let (http_client, req) = capture_request(None);
@@ -177,6 +178,7 @@ async fn behavior_mv_from_aws_config() {
177178
.starts_with("https://s3.us-west-2.amazonaws.com/"));
178179
}
179180

181+
#[allow(deprecated)] // intentionally testing an old behavior version
180182
#[tokio::test]
181183
async fn behavior_mv_from_client_construction() {
182184
let (http_client, req) = capture_request(None);

aws/sdk/integration-tests/s3/tests/identity-cache.rs

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use std::sync::atomic::{AtomicI32, Ordering};
77
use std::sync::Arc;
88

9-
use aws_config::{identity::IdentityCache, BehaviorVersion, Region};
9+
use aws_config::{BehaviorVersion, Region};
1010
use aws_credential_types::{
1111
provider::{future::ProvideCredentials as ProvideCredentialsFuture, ProvideCredentials},
1212
Credentials,
@@ -23,12 +23,9 @@ async fn test_identity_cache_reused_by_default() {
2323
infallible_client_fn(|_req| http::Response::builder().status(200).body("OK!").unwrap());
2424

2525
let provider = TestCredProvider::new();
26-
let cache = IdentityCache::lazy().build();
2726
let config = aws_config::defaults(BehaviorVersion::latest())
2827
.http_client(http_client)
2928
.credentials_provider(provider.clone())
30-
// TODO(rfc-43) - remove adding a cache when this is the new default
31-
.identity_cache(cache)
3229
.region(Region::new("us-west-2"))
3330
.load()
3431
.await;
@@ -42,31 +39,7 @@ async fn test_identity_cache_reused_by_default() {
4239
assert_eq!(1, provider.invoke_count.load(Ordering::SeqCst));
4340
}
4441

45-
// TODO(rfc-43) - add no_identity_cache() to ConfigLoader and re-enable test
46-
// #[tokio::test]
47-
// async fn test_identity_cache_explicit_unset() {
48-
// let http_client =
49-
// infallible_client_fn(|_req| http::Response::builder().status(200).body("OK!").unwrap());
50-
//
51-
// let provider = TestCredProvider::new();
52-
//
53-
// let config = aws_config::defaults(BehaviorVersion::latest())
54-
// .no_identity_cache()
55-
// .http_client(http_client)
56-
// .credentials_provider(provider.clone())
57-
// .region(Region::new("us-west-2"))
58-
// .load()
59-
// .await;
60-
//
61-
// let c1 = Client::new(&config);
62-
// let _ = c1.list_buckets().send().await;
63-
// assert_eq!(1, provider.invoke_count.load(Ordering::SeqCst));
64-
//
65-
// let c2 = Client::new(&config);
66-
// let _ = c2.list_buckets().send().await;
67-
// assert_eq!(2, provider.invoke_count.load(Ordering::SeqCst));
68-
// }
69-
42+
#[allow(deprecated)] // intentionally testing an old behavior version
7043
#[tokio::test]
7144
async fn test_identity_cache_ga_behavior_version() {
7245
let http_client =

aws/sdk/integration-tests/s3/tests/stalled-stream-protection.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,10 @@ async fn test_stalled_stream_protection_defaults_for_upload() {
9292
let _ = tokio::spawn(server);
9393

9494
let conf = Config::builder()
95+
// Stalled stream protection MUST BE enabled by default. Do not configure it explicitly.
9596
.credentials_provider(Credentials::for_tests())
9697
.region(Region::new("us-east-1"))
9798
.endpoint_url(format!("http://{server_addr}"))
98-
// TODO(https://github.com/smithy-lang/smithy-rs/issues/3510): make stalled stream protection enabled by default with BMV and remove this line
99-
.stalled_stream_protection(StalledStreamProtectionConfig::enabled().build())
10099
.build();
101100
let client = Client::from_conf(conf);
102101

@@ -255,6 +254,7 @@ async fn test_stalled_stream_protection_for_downloads_is_enabled_by_default() {
255254

256255
// Stalled stream protection should be enabled by default.
257256
let sdk_config = aws_config::from_env()
257+
// Stalled stream protection MUST BE enabled by default. Do not configure it explicitly.
258258
.credentials_provider(Credentials::for_tests())
259259
.region(Region::new("us-east-1"))
260260
.endpoint_url(format!("http://{server_addr}"))
@@ -282,12 +282,10 @@ async fn test_stalled_stream_protection_for_downloads_is_enabled_by_default() {
282282
"minimum throughput was specified at 1 B/s, but throughput of 0 B/s was observed"
283283
);
284284
// 5s grace period
285-
// TODO(https://github.com/smithy-lang/smithy-rs/issues/3510): Currently comparing against 5 and 6 due to
286-
// the behavior change in #3485. Once that feature/fix is released, this should be changed to only check for 5.
287285
let elapsed_secs = start.elapsed().as_secs();
288286
assert!(
289-
elapsed_secs == 5 || elapsed_secs == 6,
290-
"elapsed secs should be 5 or 6, but was {elapsed_secs}"
287+
elapsed_secs == 5,
288+
"elapsed secs should be 5, but was {elapsed_secs}"
291289
)
292290
}
293291

0 commit comments

Comments
 (0)