From 6f2a0fa89ee36dc80e3efa2f4e8820ea87631186 Mon Sep 17 00:00:00 2001 From: AWS SDK Rust Bot Date: Thu, 16 Nov 2023 19:52:12 +0000 Subject: [PATCH] [examples] Sync SDK examples from `awsdocs/aws-doc-sdk-examples` Includes commit(s): b7635b1ab88285a744547c4aa33b6ba8bf0a1c57 9465b36910cdc1962dadfe53af2ce31098a7abd8 a48be99cf3e1e920698bbbd4fe5c22c4f9bef279 d73bd946755cb53a0984af323e6bc0817bf5c9f6 a29f4e9d999254adf8b3594ad8904e781ab01f1b e68209ef191d825e7b19dd5b0ea84a980df54922 8595338924aae24aa9815e26d8b536a231b52e78 8d51b94f33b95667b76a2232762560304a28b6e5 9f08f276537a38dc094727f1ad0b0ceacbb1dc7b Co-authored-by: David Souther Co-authored-by: Eric Shepherd Co-authored-by: John DiSanti --- .../cross_service/detect_faces/src/main.rs | 5 +- .../cross_service/detect_labels/src/main.rs | 7 +- .../photo_asset_management/src/common.rs | 4 +- .../src/handlers/detect_labels.rs | 8 +- .../photo_asset_management/src/uploader.rs | 7 +- .../tests/test_upload_part.rs | 3 +- examples/cross_service/rest_ses/src/main.rs | 3 +- .../rest_ses/tests/api/startup.rs | 6 +- examples/cross_service/telephone/src/main.rs | 7 +- examples/examples/apigateway/Cargo.toml | 2 +- .../examples/apigatewaymanagement/Cargo.toml | 2 +- .../applicationautoscaling/Cargo.toml | 2 +- examples/examples/aurora/Cargo.toml | 2 +- .../aurora/src/aurora_scenario/tests.rs | 26 +-- .../examples/aurora/src/bin/hello-world.rs | 39 +++++ examples/examples/auto-scaling/Cargo.toml | 2 +- examples/examples/autoscalingplans/Cargo.toml | 2 +- examples/examples/batch/Cargo.toml | 2 +- examples/examples/cloudformation/Cargo.toml | 2 +- examples/examples/cloudwatch/Cargo.toml | 2 +- examples/examples/cloudwatchlogs/Cargo.toml | 2 +- examples/examples/cognitoidentity/Cargo.toml | 2 +- .../cognitoidentityprovider/Cargo.toml | 2 +- examples/examples/cognitosync/Cargo.toml | 2 +- examples/examples/config/Cargo.toml | 2 +- .../config/src/bin/config-helloworld.rs | 10 +- .../config/src/bin/show-resource-history.rs | 12 +- .../custom-root-certificates/Cargo.toml | 2 +- .../custom-root-certificates/src/main.rs | 6 +- examples/examples/dynamodb/Cargo.toml | 2 +- .../dynamodb/src/bin/list-tables-main.rs | 6 +- examples/examples/ebs/Cargo.toml | 2 +- .../examples/ebs/src/bin/create-snapshot.rs | 17 +- examples/examples/ec2/Cargo.toml | 2 +- examples/examples/ecr/Cargo.toml | 2 +- examples/examples/ecs/Cargo.toml | 2 +- examples/examples/eks/Cargo.toml | 2 +- examples/examples/firehose/Cargo.toml | 2 +- .../examples/globalaccelerator/Cargo.toml | 2 +- .../src/bin/globalaccelerator-helloworld.rs | 22 ++- examples/examples/glue/Cargo.toml | 2 +- examples/examples/greengrassv2/Cargo.toml | 2 +- examples/examples/iam/Cargo.toml | 2 +- examples/examples/iam/src/iam-service-lib.rs | 39 ++--- examples/examples/iot/Cargo.toml | 2 +- examples/examples/kinesis/Cargo.toml | 2 +- examples/examples/kms/Cargo.toml | 2 +- examples/examples/lambda/Cargo.toml | 2 +- examples/examples/lambda/src/actions.rs | 13 +- examples/examples/lambda/src/main.rs | 3 +- examples/examples/localstack/Cargo.toml | 2 +- .../localstack/src/bin/use-localstack.rs | 3 +- examples/examples/logging/logger/Cargo.toml | 2 +- examples/examples/logging/logger/src/main.rs | 6 +- examples/examples/logging/tracing/Cargo.toml | 2 +- examples/examples/logging/tracing/src/main.rs | 6 +- examples/examples/medialive/Cargo.toml | 2 +- examples/examples/mediapackage/Cargo.toml | 2 +- examples/examples/polly/Cargo.toml | 2 +- examples/examples/qldb/Cargo.toml | 2 +- examples/examples/rds/Cargo.toml | 2 +- examples/examples/rdsdata/Cargo.toml | 2 +- examples/examples/route53/Cargo.toml | 2 +- examples/examples/s3/Cargo.toml | 2 +- examples/examples/s3/src/bin/get-object.rs | 9 +- .../examples/s3/src/bin/if-modified-since.rs | 15 +- .../s3/src/bin/put-object-progress.rs | 2 +- examples/examples/sagemaker/Cargo.toml | 2 +- examples/examples/sdk-config/Cargo.toml | 5 +- .../sdk-config/src/bin/disable_retries.rs | 3 +- .../examples/sdk-config/src/bin/no_env.rs | 139 +++++++++++++++ .../sdk-config/src/bin/set_retries.rs | 6 +- examples/examples/secretsmanager/Cargo.toml | 2 +- .../sending-presigned-requests/Cargo.toml | 2 +- examples/examples/ses/Cargo.toml | 2 +- examples/examples/sitewise/Cargo.toml | 2 +- examples/examples/snowball/Cargo.toml | 2 +- examples/examples/sns/Cargo.toml | 2 +- examples/examples/sqs/Cargo.toml | 2 +- examples/examples/ssm/Cargo.toml | 2 +- examples/examples/stepfunction/Cargo.toml | 2 +- examples/examples/sts/Cargo.toml | 2 +- examples/examples/testing/Cargo.toml | 22 ++- examples/examples/testing/src/enums.rs | 126 +++++++------- .../testing/src/{intro.rs => main.rs} | 18 +- examples/examples/testing/src/replay.rs | 156 +++++++++++++++++ .../testing/src/testing/response_1.xml | 22 +++ .../testing/src/testing/response_multi_1.xml | 23 +++ .../testing/src/testing/response_multi_2.xml | 22 +++ examples/examples/testing/src/traits.rs | 127 +++++++------- examples/examples/testing/src/wrapper.rs | 161 ++++++++++++++++++ examples/examples/textract/Cargo.toml | 4 +- examples/examples/tls/Cargo.toml | 2 +- examples/examples/tls/src/lib.rs | 6 +- .../examples/transcribestreaming/Cargo.toml | 2 +- examples/test-utils/src/macros.rs | 1 + examples/webassembly/src/lib.rs | 7 +- versions.toml | 2 +- 98 files changed, 923 insertions(+), 319 deletions(-) create mode 100644 examples/examples/aurora/src/bin/hello-world.rs create mode 100644 examples/examples/sdk-config/src/bin/no_env.rs rename examples/examples/testing/src/{intro.rs => main.rs} (90%) create mode 100644 examples/examples/testing/src/replay.rs create mode 100644 examples/examples/testing/src/testing/response_1.xml create mode 100644 examples/examples/testing/src/testing/response_multi_1.xml create mode 100644 examples/examples/testing/src/testing/response_multi_2.xml create mode 100644 examples/examples/testing/src/wrapper.rs diff --git a/examples/cross_service/detect_faces/src/main.rs b/examples/cross_service/detect_faces/src/main.rs index f0298b13ad1b..9396ab8ec14a 100644 --- a/examples/cross_service/detect_faces/src/main.rs +++ b/examples/cross_service/detect_faces/src/main.rs @@ -4,6 +4,7 @@ */ use aws_config::meta::region::RegionProviderChain; +use aws_config::BehaviorVersion; use aws_sdk_s3::config::Region; use clap::Parser; use std::error::Error; @@ -205,13 +206,13 @@ async fn main() -> Result<(), Box> { println!(); } - let s3_shared_config = aws_config::from_env() + let s3_shared_config = aws_config::defaults(BehaviorVersion::latest()) .region(s3_region_provider) .load() .await; let s3_client = aws_sdk_s3::Client::new(&s3_shared_config); - let rek_shared_config = aws_config::from_env() + let rek_shared_config = aws_config::defaults(BehaviorVersion::latest()) .region(rek_region_provider) .load() .await; diff --git a/examples/cross_service/detect_labels/src/main.rs b/examples/cross_service/detect_labels/src/main.rs index c5ae6be8d29d..862c31a6ce87 100644 --- a/examples/cross_service/detect_labels/src/main.rs +++ b/examples/cross_service/detect_labels/src/main.rs @@ -6,6 +6,7 @@ extern crate exif; use aws_config::meta::region::RegionProviderChain; +use aws_config::BehaviorVersion; use aws_sdk_dynamodb::config::Region; use aws_sdk_dynamodb::types::AttributeValue; use clap::Parser; @@ -279,7 +280,7 @@ async fn main() -> Result<(), exif::Error> { println!(); } - let s3_shared_config = aws_config::from_env() + let s3_shared_config = aws_config::defaults(BehaviorVersion::latest()) .region(s3_region_provider) .load() .await; @@ -289,7 +290,7 @@ async fn main() -> Result<(), exif::Error> { let edata = get_exif_data(&filename); - let rek_shared_config = aws_config::from_env() + let rek_shared_config = aws_config::defaults(BehaviorVersion::latest()) .region(rek_region_provider) .load() .await; @@ -297,7 +298,7 @@ async fn main() -> Result<(), exif::Error> { let labels = get_label_data(&rek_client, &bucket, &filename).await; - let dynamo_shared_config = aws_config::from_env() + let dynamo_shared_config = aws_config::defaults(BehaviorVersion::latest()) .region(dynamo_region_provider) .load() .await; diff --git a/examples/cross_service/photo_asset_management/src/common.rs b/examples/cross_service/photo_asset_management/src/common.rs index 8f6c10e1bd7a..7f1eaa903337 100644 --- a/examples/cross_service/photo_asset_management/src/common.rs +++ b/examples/cross_service/photo_asset_management/src/common.rs @@ -1,4 +1,4 @@ -use aws_config::SdkConfig; +use aws_config::{BehaviorVersion, SdkConfig}; #[cfg(not(debug_assertions))] pub fn init_tracing_subscriber() { @@ -62,7 +62,7 @@ impl Common { } pub async fn load_from_env() -> Self { - let sdk_config = aws_config::load_from_env().await; + let sdk_config = aws_config::load_defaults(BehaviorVersion::latest()).await; // PAM environment is declared in the cdk, in lib/backend/lambdas.ts let storage_bucket = std::env::var("STORAGE_BUCKET_NAME").expect("storage bucket in environment"); diff --git a/examples/cross_service/photo_asset_management/src/handlers/detect_labels.rs b/examples/cross_service/photo_asset_management/src/handlers/detect_labels.rs index b0b2ab1bec4d..68138ebe0d6f 100644 --- a/examples/cross_service/photo_asset_management/src/handlers/detect_labels.rs +++ b/examples/cross_service/photo_asset_management/src/handlers/detect_labels.rs @@ -127,7 +127,7 @@ pub async fn handler( #[cfg(test)] mod test { use super::prepare_update_expression; - use aws_config::SdkConfig; + use aws_config::{BehaviorVersion, SdkConfig}; #[tokio::test] async fn test_prepare_update_statement() { @@ -136,7 +136,11 @@ mod test { .name("label") .build(); - let client = aws_sdk_dynamodb::Client::new(&SdkConfig::builder().build()); + let client = aws_sdk_dynamodb::Client::new( + &SdkConfig::builder() + .behavior_version(BehaviorVersion::latest()) + .build(), + ); let update = client.update_item(); let update = prepare_update_expression(update, &object, &label); diff --git a/examples/cross_service/photo_asset_management/src/uploader.rs b/examples/cross_service/photo_asset_management/src/uploader.rs index 712b8495aa18..1db59ebf753a 100644 --- a/examples/cross_service/photo_asset_management/src/uploader.rs +++ b/examples/cross_service/photo_asset_management/src/uploader.rs @@ -57,9 +57,10 @@ impl<'a> ZipUpload<'a> { let mut byte_count = 0_usize; while let Some(bytes) = object.body.try_next().await? { - let bytes = self.zip.write(&bytes)?; - byte_count += bytes; - tracing::trace!("Intermediate read of {bytes} (total {byte_count})"); + let bytes_len = bytes.len(); + self.zip.write_all(&bytes)?; + byte_count += bytes_len; + tracing::trace!("Intermediate read of {bytes_len} (total {byte_count})"); } Ok(()) diff --git a/examples/cross_service/photo_asset_management/tests/test_upload_part.rs b/examples/cross_service/photo_asset_management/tests/test_upload_part.rs index 3886a8fb6683..66cded221f01 100644 --- a/examples/cross_service/photo_asset_management/tests/test_upload_part.rs +++ b/examples/cross_service/photo_asset_management/tests/test_upload_part.rs @@ -1,8 +1,9 @@ +use aws_config::BehaviorVersion; use aws_sdk_s3::Client; #[tokio::main] async fn main() -> Result<(), anyhow::Error> { - let s3_client = Client::new(&aws_config::load_from_env().await); + let s3_client = Client::new(&aws_config::load_defaults(BehaviorVersion::latest()).await); let part = 0; let bucket: String = "bucket".to_string(); let key: String = "key".to_string(); diff --git a/examples/cross_service/rest_ses/src/main.rs b/examples/cross_service/rest_ses/src/main.rs index c3d0e93ea2cd..faa5f8f23375 100644 --- a/examples/cross_service/rest_ses/src/main.rs +++ b/examples/cross_service/rest_ses/src/main.rs @@ -8,6 +8,7 @@ //! Main that loads environments & prepares clients, and hands them to `startup`. use std::net::TcpListener; +use aws_config::BehaviorVersion; use rest_ses::client::{RdsClient, SesClient}; use rest_ses::configuration::{get_settings, init_environment}; use rest_ses::startup::run; @@ -30,7 +31,7 @@ async fn main() -> std::io::Result<()> { init_subscriber(subscriber); // AWS Settings (Region & role) come from the environment. - let config = aws_config::from_env().load().await; + let config = aws_config::load_defaults(BehaviorVersion::latest()).await; let rds = RdsClient::new(&settings.rds, &config); let ses = SesClient::new(&settings.ses, &config); diff --git a/examples/cross_service/rest_ses/tests/api/startup.rs b/examples/cross_service/rest_ses/tests/api/startup.rs index a99f9f82b1fb..70795fbed58d 100644 --- a/examples/cross_service/rest_ses/tests/api/startup.rs +++ b/examples/cross_service/rest_ses/tests/api/startup.rs @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ +use aws_config::BehaviorVersion; use once_cell::sync::Lazy; use rest_ses::{ client::{RdsClient, SesClient}, @@ -27,14 +28,15 @@ static TRACING: Lazy = Lazy::new(|| { /// Spawn the app against a MockServer resolved backend. pub async fn spawn_app_mocked() -> (String, MockServer) { let mock_server = MockServer::builder().start().await; - let config_loader = aws_config::from_env().endpoint_url(mock_server.uri()); + let config_loader = + aws_config::defaults(BehaviorVersion::latest()).endpoint_url(mock_server.uri()); let (app, _) = prep_app(config_loader).await; (app, mock_server) } /// Spawn the app using production AWS credentials. pub async fn spawn_app() -> (String, RdsClient) { - prep_app(aws_config::from_env()).await + prep_app(aws_config::defaults(BehaviorVersion::latest())).await } /// Prepare the application for testing. diff --git a/examples/cross_service/telephone/src/main.rs b/examples/cross_service/telephone/src/main.rs index 46ca79f9a5ee..30651242c08c 100644 --- a/examples/cross_service/telephone/src/main.rs +++ b/examples/cross_service/telephone/src/main.rs @@ -5,6 +5,7 @@ use anyhow::{Context, Result}; use aws_config::meta::region::RegionProviderChain; +use aws_config::BehaviorVersion; use aws_sdk_polly::config::Region; use aws_sdk_polly::types::{OutputFormat, VoiceId}; use aws_sdk_transcribe::types::{LanguageCode, Media, MediaFormat, TranscriptionJobStatus}; @@ -269,15 +270,15 @@ async fn main() -> Result<(), anyhow::Error> { } // Create configurations for each service client. - let polly_shared_config = aws_config::from_env() + let polly_shared_config = aws_config::defaults(BehaviorVersion::latest()) .region(polly_region_provider) .load() .await; - let s3_shared_config = aws_config::from_env() + let s3_shared_config = aws_config::defaults(BehaviorVersion::latest()) .region(s3_region_provider) .load() .await; - let transcribe_shared_config = aws_config::from_env() + let transcribe_shared_config = aws_config::defaults(BehaviorVersion::latest()) .region(transcribe_region_provider) .load() .await; diff --git a/examples/examples/apigateway/Cargo.toml b/examples/examples/apigateway/Cargo.toml index 2619bd2f3b5f..e987d9b3bbe2 100644 --- a/examples/examples/apigateway/Cargo.toml +++ b/examples/examples/apigateway/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] thiserror = "1.0" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-apigateway= { version = "0.37.0", path = "../../../sdk/apigateway" } aws-smithy-types-convert= { version = "0.58.0", path = "../../../sdk/aws-smithy-types-convert", features = ["convert-chrono"] } diff --git a/examples/examples/apigatewaymanagement/Cargo.toml b/examples/examples/apigatewaymanagement/Cargo.toml index 92fb2e3c770e..cfccc4fba509 100644 --- a/examples/examples/apigatewaymanagement/Cargo.toml +++ b/examples/examples/apigatewaymanagement/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] http = "0.2.5" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-apigatewaymanagement= { version = "0.37.0", path = "../../../sdk/apigatewaymanagement" } [dependencies.tokio] diff --git a/examples/examples/applicationautoscaling/Cargo.toml b/examples/examples/applicationautoscaling/Cargo.toml index 919bbe64cb7e..b3c2314670dc 100644 --- a/examples/examples/applicationautoscaling/Cargo.toml +++ b/examples/examples/applicationautoscaling/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-applicationautoscaling= { version = "0.37.0", path = "../../../sdk/applicationautoscaling" } [dependencies.tokio] diff --git a/examples/examples/aurora/Cargo.toml b/examples/examples/aurora/Cargo.toml index b42ae687fe50..a0b6d8ad59d2 100644 --- a/examples/examples/aurora/Cargo.toml +++ b/examples/examples/aurora/Cargo.toml @@ -13,7 +13,7 @@ inquire = "0.6.2" mockall = "0.11.4" secrecy = "0.8.0" tracing = "0.1.37" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-smithy-types= { version = "0.100.0", path = "../../../sdk/aws-smithy-types" } aws-smithy-runtime-api= { version = "0.100.0", path = "../../../sdk/aws-smithy-runtime-api" } aws-sdk-rds= { version = "0.37.0", path = "../../../sdk/rds" } diff --git a/examples/examples/aurora/src/aurora_scenario/tests.rs b/examples/examples/aurora/src/aurora_scenario/tests.rs index 317e02c8a430..54f0ce1dd62f 100644 --- a/examples/examples/aurora/src/aurora_scenario/tests.rs +++ b/examples/examples/aurora/src/aurora_scenario/tests.rs @@ -39,7 +39,7 @@ use aws_sdk_rds::{ OrderableDbInstanceOption, }, }; -use aws_smithy_runtime_api::client::orchestrator::HttpResponse; +use aws_smithy_runtime_api::http::{Response, StatusCode}; use aws_smithy_types::body::SdkBody; use mockall::predicate::eq; use secrecy::ExposeSecret; @@ -103,7 +103,7 @@ async fn test_scenario_set_engine_param_group_exists() { CreateDBClusterParameterGroupError::DbParameterGroupAlreadyExistsFault( DbParameterGroupAlreadyExistsFault::builder().build(), ), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); @@ -173,7 +173,7 @@ async fn test_scenario_get_engines_failed() { ErrorKind::Other, "describe_db_engine_versions error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); @@ -244,7 +244,7 @@ async fn test_scenario_get_instance_classes_error() { ErrorKind::Other, "describe_orderable_db_instance_options_error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); @@ -327,7 +327,7 @@ async fn test_scenario_get_cluster_error() { ErrorKind::Other, "describe_db_clusters_error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); @@ -419,7 +419,7 @@ async fn test_scenario_cluster_parameters_error() { ErrorKind::Other, "describe_db_cluster_parameters_error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); @@ -478,7 +478,7 @@ async fn test_scenario_update_auto_increment_error() { ErrorKind::Other, "modify_db_cluster_parameter_group_error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); @@ -602,7 +602,7 @@ async fn test_start_cluster_and_instance_cluster_create_error() { ErrorKind::Other, "create db cluster error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); @@ -667,7 +667,7 @@ async fn test_start_cluster_and_instance_instance_create_error() { ErrorKind::Other, "create db instance error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); @@ -733,7 +733,7 @@ async fn test_start_cluster_and_instance_wait_hiccup() { ErrorKind::Other, "describe cluster error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }) .with(eq("RustSDKCodeExamplesDBCluster")) @@ -892,7 +892,7 @@ async fn test_scenario_clean_up_errors() { ErrorKind::Other, "describe db instances error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); @@ -923,7 +923,7 @@ async fn test_scenario_clean_up_errors() { ErrorKind::Other, "describe db clusters error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); @@ -1000,7 +1000,7 @@ async fn test_scenario_snapshot_error() { ErrorKind::Other, "create snapshot error", ))), - HttpResponse::new(SdkBody::empty()), + Response::new(StatusCode::try_from(400).unwrap(), SdkBody::empty()), )) }); diff --git a/examples/examples/aurora/src/bin/hello-world.rs b/examples/examples/aurora/src/bin/hello-world.rs new file mode 100644 index 000000000000..15999ea1f15a --- /dev/null +++ b/examples/examples/aurora/src/bin/hello-world.rs @@ -0,0 +1,39 @@ +use aws_sdk_rds::Client; + +#[derive(Debug)] +struct Error(String); +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} +impl std::error::Error for Error {} + +#[tokio::main] +async fn main() -> Result<(), Error> { + tracing_subscriber::fmt::init(); + let sdk_config = aws_config::from_env().load().await; + let client = Client::new(&sdk_config); + + let describe_db_clusters_output = client + .describe_db_clusters() + .send() + .await + .map_err(|e| Error(e.to_string()))?; + println!( + "Found {} clusters:", + describe_db_clusters_output.db_clusters().len() + ); + for cluster in describe_db_clusters_output.db_clusters() { + let name = cluster.database_name().unwrap_or("Unknown"); + let engine = cluster.engine().unwrap_or("Unknown"); + let id = cluster.db_cluster_identifier().unwrap_or("Unknown"); + let class = cluster.db_cluster_instance_class().unwrap_or("Unknown"); + println!("\tDatabase: {name}",); + println!("\t Engine: {engine}",); + println!("\t ID: {id}",); + println!("\tInstance: {class}",); + } + + Ok(()) +} diff --git a/examples/examples/auto-scaling/Cargo.toml b/examples/examples/auto-scaling/Cargo.toml index 8afcc981d056..763c03a0353f 100644 --- a/examples/examples/auto-scaling/Cargo.toml +++ b/examples/examples/auto-scaling/Cargo.toml @@ -10,7 +10,7 @@ publish = false anyhow = "1.0.75" tracing = "0.1.37" tokio-stream = "0.1.14" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-autoscaling= { version = "0.37.0", path = "../../../sdk/autoscaling" } aws-sdk-ec2= { version = "0.37.0", path = "../../../sdk/ec2" } aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } diff --git a/examples/examples/autoscalingplans/Cargo.toml b/examples/examples/autoscalingplans/Cargo.toml index bec88ee705c0..d41d340307e1 100644 --- a/examples/examples/autoscalingplans/Cargo.toml +++ b/examples/examples/autoscalingplans/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] aws-sdk-autoscalingplans= { version = "0.37.0", path = "../../../sdk/autoscalingplans" } -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } [dependencies.tokio] diff --git a/examples/examples/batch/Cargo.toml b/examples/examples/batch/Cargo.toml index 22a992233c38..ec17696631df 100644 --- a/examples/examples/batch/Cargo.toml +++ b/examples/examples/batch/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-batch= { version = "0.37.0", path = "../../../sdk/batch" } [dependencies.tokio] diff --git a/examples/examples/cloudformation/Cargo.toml b/examples/examples/cloudformation/Cargo.toml index a6a3b2253f6a..2ae8e8bf55f9 100644 --- a/examples/examples/cloudformation/Cargo.toml +++ b/examples/examples/cloudformation/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-cloudformation= { version = "0.37.0", path = "../../../sdk/cloudformation" } [dependencies.tokio] diff --git a/examples/examples/cloudwatch/Cargo.toml b/examples/examples/cloudwatch/Cargo.toml index fe4f23db3613..183fa3462433 100644 --- a/examples/examples/cloudwatch/Cargo.toml +++ b/examples/examples/cloudwatch/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-cloudwatch= { version = "0.37.0", path = "../../../sdk/cloudwatch" } [dependencies.tokio] diff --git a/examples/examples/cloudwatchlogs/Cargo.toml b/examples/examples/cloudwatchlogs/Cargo.toml index d90144805530..818cc2926f32 100644 --- a/examples/examples/cloudwatchlogs/Cargo.toml +++ b/examples/examples/cloudwatchlogs/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-cloudwatchlogs= { version = "0.37.0", path = "../../../sdk/cloudwatchlogs" } aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } diff --git a/examples/examples/cognitoidentity/Cargo.toml b/examples/examples/cognitoidentity/Cargo.toml index 17eb1bed0155..3372162f49f3 100644 --- a/examples/examples/cognitoidentity/Cargo.toml +++ b/examples/examples/cognitoidentity/Cargo.toml @@ -9,7 +9,7 @@ publish = false [dependencies] chrono = "0.4" thiserror = "1.0" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-cognitoidentity= { version = "0.37.0", path = "../../../sdk/cognitoidentity" } aws-smithy-types-convert= { version = "0.58.0", path = "../../../sdk/aws-smithy-types-convert", features = ["convert-chrono"] } diff --git a/examples/examples/cognitoidentityprovider/Cargo.toml b/examples/examples/cognitoidentityprovider/Cargo.toml index a489775abffa..cca0e632930b 100644 --- a/examples/examples/cognitoidentityprovider/Cargo.toml +++ b/examples/examples/cognitoidentityprovider/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] thiserror = "1.0" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-cognitoidentityprovider= { version = "0.37.0", path = "../../../sdk/cognitoidentityprovider" } aws-smithy-types-convert= { version = "0.58.0", path = "../../../sdk/aws-smithy-types-convert", features = ["convert-chrono"] } diff --git a/examples/examples/cognitosync/Cargo.toml b/examples/examples/cognitosync/Cargo.toml index 5f3b22091e07..bd477bbd98f5 100644 --- a/examples/examples/cognitosync/Cargo.toml +++ b/examples/examples/cognitosync/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] thiserror = "1.0" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-cognitosync= { version = "0.37.0", path = "../../../sdk/cognitosync" } aws-smithy-types-convert= { version = "0.58.0", path = "../../../sdk/aws-smithy-types-convert", features = ["convert-chrono"] } diff --git a/examples/examples/config/Cargo.toml b/examples/examples/config/Cargo.toml index 93a9d0c9a1e0..7fb5b5a073cf 100644 --- a/examples/examples/config/Cargo.toml +++ b/examples/examples/config/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-config= { version = "0.37.0", path = "../../../sdk/config" } [dependencies.tokio] diff --git a/examples/examples/config/src/bin/config-helloworld.rs b/examples/examples/config/src/bin/config-helloworld.rs index c388a551fea0..732f95ad805b 100644 --- a/examples/examples/config/src/bin/config-helloworld.rs +++ b/examples/examples/config/src/bin/config-helloworld.rs @@ -89,14 +89,14 @@ async fn main() -> Result<(), Error> { let client = Client::new(&shared_config); // parse resource type from user input - let parsed = ResourceType::from(resource_type.as_str()); - if matches!(parsed, ResourceType::Unknown(_)) { - panic!( + let parsed = match ResourceType::try_parse(resource_type.as_str()) { + Ok(parsed) => parsed, + Err(_) => panic!( "unknown resource type: `{}`. Valid resource types: {:#?}", &resource_type, ResourceType::values() - ) - } + ), + }; get_history(&client, &resource_id, parsed).await } diff --git a/examples/examples/config/src/bin/show-resource-history.rs b/examples/examples/config/src/bin/show-resource-history.rs index 4726f756f3fd..48e2e918f667 100644 --- a/examples/examples/config/src/bin/show-resource-history.rs +++ b/examples/examples/config/src/bin/show-resource-history.rs @@ -85,16 +85,14 @@ async fn main() -> Result<(), Error> { } // Parse resource type from user input. - let parsed = ResourceType::from(resource_type.as_str()); - - // Make sure it's a known type. - if matches!(parsed, ResourceType::Unknown(_)) { - panic!( + let parsed = match ResourceType::try_parse(resource_type.as_str()) { + Ok(parsed) => parsed, + Err(_) => panic!( "unknown resource type: `{}`. Valid resource types: {:#?}", &resource_type, ResourceType::values() - ) - } + ), + }; let shared_config = aws_config::from_env().region(region_provider).load().await; let client = Client::new(&shared_config); diff --git a/examples/examples/custom-root-certificates/Cargo.toml b/examples/examples/custom-root-certificates/Cargo.toml index 31dbb9e11641..16d1648e3c2e 100644 --- a/examples/examples/custom-root-certificates/Cargo.toml +++ b/examples/examples/custom-root-certificates/Cargo.toml @@ -9,7 +9,7 @@ publish = false [dependencies] rustls = "0.20.7" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-s3= { version = "0.37.0", path = "../../../sdk/s3", default-features = false } [dependencies.tokio] diff --git a/examples/examples/custom-root-certificates/src/main.rs b/examples/examples/custom-root-certificates/src/main.rs index 2f118a3129e8..c762f6600ecd 100644 --- a/examples/examples/custom-root-certificates/src/main.rs +++ b/examples/examples/custom-root-certificates/src/main.rs @@ -4,9 +4,7 @@ */ use aws_config::provider_config::ProviderConfig; -use aws_smithy_client::erase::DynConnector; -use aws_smithy_client::http_connector::HttpConnector; -use aws_smithy_client::hyper_ext; +use aws_config::BehaviorVersion; use rustls::RootCertStore; use std::sync::Arc; @@ -28,7 +26,7 @@ async fn main() { // Currently, aws_config connectors are buildable directly from something that implements `hyper::Connect`. // This enables different providers to construct clients with different timeouts. let provider_config = ProviderConfig::default().with_tcp_connector(rustls_connector.clone()); - let sdk_config = aws_config::from_env() + let sdk_config = aws_config::defaults(BehaviorVersion::latest()) .configure(provider_config) .http_connector(HttpConnector::ConnectorFn(Arc::new( move |connector_settings, sleep_impl| { diff --git a/examples/examples/dynamodb/Cargo.toml b/examples/examples/dynamodb/Cargo.toml index 5d3e38cb7bad..22a5a8d69474 100644 --- a/examples/examples/dynamodb/Cargo.toml +++ b/examples/examples/dynamodb/Cargo.toml @@ -16,7 +16,7 @@ serde_json = "1" thiserror = "1.0" tokio-stream = "0.1.8" tracing = "0.1" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-http= { version = "0.58.0", path = "../../../sdk/aws-http" } aws-sdk-dynamodb= { version = "0.37.0", path = "../../../sdk/dynamodb" } aws-smithy-runtime= { version = "0.58.0", path = "../../../sdk/aws-smithy-runtime", features = ["test-util"] } diff --git a/examples/examples/dynamodb/src/bin/list-tables-main.rs b/examples/examples/dynamodb/src/bin/list-tables-main.rs index 1a3bb6e9d723..3355655e04c3 100644 --- a/examples/examples/dynamodb/src/bin/list-tables-main.rs +++ b/examples/examples/dynamodb/src/bin/list-tables-main.rs @@ -7,13 +7,17 @@ // snippet-start:[dynamodb.rust.list-tables-main] use aws_config::meta::region::RegionProviderChain; +use aws_config::BehaviorVersion; use aws_sdk_dynamodb::{Client, Error}; /// Lists your DynamoDB tables in the default Region or us-east-1 if a default Region isn't set. #[tokio::main] async fn main() -> Result<(), Error> { let region_provider = RegionProviderChain::default_provider().or_else("us-east-1"); - let config = aws_config::from_env().region(region_provider).load().await; + let config = aws_config::defaults(BehaviorVersion::latest()) + .region(region_provider) + .load() + .await; let client = Client::new(&config); let resp = client.list_tables().send().await?; diff --git a/examples/examples/ebs/Cargo.toml b/examples/examples/ebs/Cargo.toml index 4613f6a620b8..88becf8eeb6b 100644 --- a/examples/examples/ebs/Cargo.toml +++ b/examples/examples/ebs/Cargo.toml @@ -9,7 +9,7 @@ publish = false [dependencies] base64 = "0.13.0" sha2 = "0.9.5" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-ebs= { version = "0.37.0", path = "../../../sdk/ebs" } aws-sdk-ec2= { version = "0.37.0", path = "../../../sdk/ec2" } diff --git a/examples/examples/ebs/src/bin/create-snapshot.rs b/examples/examples/ebs/src/bin/create-snapshot.rs index 2af75311ba2a..29cf0c5abf77 100644 --- a/examples/examples/ebs/src/bin/create-snapshot.rs +++ b/examples/examples/ebs/src/bin/create-snapshot.rs @@ -126,17 +126,12 @@ async fn main() -> Result<(), Error> { let snapshot_id = start(&client, &description).await.unwrap(); - let mut blocks = vec![]; - - // Append a block of all 1s. - let mut block: Vec = Vec::new(); - block.resize(EBS_BLOCK_SIZE, 1); - blocks.push(block); - - // Append a block of all 0s. - let mut block: Vec = Vec::new(); - block.resize(EBS_BLOCK_SIZE, 0); - blocks.push(block); + let blocks = vec![ + // Block of all 1s. + vec![1u8; EBS_BLOCK_SIZE], + // Block of all 0s. + vec![0u8; EBS_BLOCK_SIZE], + ]; for (idx, block) in blocks.into_iter().enumerate() { let mut hasher = sha2::Sha256::new(); diff --git a/examples/examples/ec2/Cargo.toml b/examples/examples/ec2/Cargo.toml index a2635ba75077..c62b2f6ce658 100644 --- a/examples/examples/ec2/Cargo.toml +++ b/examples/examples/ec2/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-ec2= { version = "0.37.0", path = "../../../sdk/ec2" } aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } diff --git a/examples/examples/ecr/Cargo.toml b/examples/examples/ecr/Cargo.toml index 5e1e326c306c..1224c745b12c 100644 --- a/examples/examples/ecr/Cargo.toml +++ b/examples/examples/ecr/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-ecr= { version = "0.37.0", path = "../../../sdk/ecr" } aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } diff --git a/examples/examples/ecs/Cargo.toml b/examples/examples/ecs/Cargo.toml index af678f04d17a..b6ae82b104e1 100644 --- a/examples/examples/ecs/Cargo.toml +++ b/examples/examples/ecs/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-ecs= { version = "0.37.0", path = "../../../sdk/ecs" } [dependencies.tokio] diff --git a/examples/examples/eks/Cargo.toml b/examples/examples/eks/Cargo.toml index 7cfb9d67ced7..48d3ebacd374 100644 --- a/examples/examples/eks/Cargo.toml +++ b/examples/examples/eks/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-eks= { version = "0.37.0", path = "../../../sdk/eks" } aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } diff --git a/examples/examples/firehose/Cargo.toml b/examples/examples/firehose/Cargo.toml index 80d1f02c39f8..ea73d4afaf44 100644 --- a/examples/examples/firehose/Cargo.toml +++ b/examples/examples/firehose/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-firehose= { version = "0.37.0", path = "../../../sdk/firehose" } [dependencies.tokio] diff --git a/examples/examples/globalaccelerator/Cargo.toml b/examples/examples/globalaccelerator/Cargo.toml index dd3a5d3929fd..824e1f961b17 100644 --- a/examples/examples/globalaccelerator/Cargo.toml +++ b/examples/examples/globalaccelerator/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] tokio-stream = "0.1.8" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-globalaccelerator= { version = "0.37.0", path = "../../../sdk/globalaccelerator" } [dependencies.tokio] diff --git a/examples/examples/globalaccelerator/src/bin/globalaccelerator-helloworld.rs b/examples/examples/globalaccelerator/src/bin/globalaccelerator-helloworld.rs index d8ceded526f3..d108e66fd7a7 100644 --- a/examples/examples/globalaccelerator/src/bin/globalaccelerator-helloworld.rs +++ b/examples/examples/globalaccelerator/src/bin/globalaccelerator-helloworld.rs @@ -21,17 +21,21 @@ struct Opt { async fn show_accelerators(client: &Client) -> Result<(), Error> { println!("Welcome to the AWS Rust SDK Global Accelerator example!"); println!(); - let mut paginator = client.list_accelerators().into_paginator().send(); + let accelerators = client + .list_accelerators() + .into_paginator() + .items() + .send() + .try_collect() + .await?; - while let Some(page) = paginator.try_next().await? { - for accelerator in page.accelerators().iter() { - let accelerator_arn = accelerator.name().unwrap_or_default(); - let accelerator_name = accelerator.accelerator_arn().unwrap_or_default(); + for accelerator in accelerators { + let accelerator_arn = accelerator.name().unwrap_or_default(); + let accelerator_name = accelerator.accelerator_arn().unwrap_or_default(); - println!("Accelerator Name : {}", accelerator_name); - println!("Accelerator ARN : {}", accelerator_arn); - println!(); - } + println!("Accelerator Name : {}", accelerator_name); + println!("Accelerator ARN : {}", accelerator_arn); + println!(); } Ok(()) diff --git a/examples/examples/glue/Cargo.toml b/examples/examples/glue/Cargo.toml index e867a46227ef..0a295a4c1f0a 100644 --- a/examples/examples/glue/Cargo.toml +++ b/examples/examples/glue/Cargo.toml @@ -18,7 +18,7 @@ thiserror = "1.0.37" secrecy = "0.8.0" futures = "0.3.25" tracing-bunyan-formatter = "0.3.4" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-glue= { version = "0.37.0", path = "../../../sdk/glue" } aws-sdk-s3= { version = "0.37.0", path = "../../../sdk/s3" } aws-http= { version = "0.58.0", path = "../../../sdk/aws-http" } diff --git a/examples/examples/greengrassv2/Cargo.toml b/examples/examples/greengrassv2/Cargo.toml index fd7cc97f5172..7ce386108c6f 100644 --- a/examples/examples/greengrassv2/Cargo.toml +++ b/examples/examples/greengrassv2/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-greengrassv2= { version = "0.37.0", path = "../../../sdk/greengrassv2" } aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } diff --git a/examples/examples/iam/Cargo.toml b/examples/examples/iam/Cargo.toml index 12c9ec55be3b..1a45a0b8d321 100644 --- a/examples/examples/iam/Cargo.toml +++ b/examples/examples/iam/Cargo.toml @@ -21,7 +21,7 @@ http = "0.2.8" futures = "0.3.28" async_once = "0.2.6" lazy_static = "1.4.0" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-credential-types= { version = "0.58.0", path = "../../../sdk/aws-credential-types", features = ["hardcoded-credentials"] } aws-sdk-iam= { version = "0.37.0", path = "../../../sdk/iam" } aws-sdk-s3= { version = "0.37.0", path = "../../../sdk/s3" } diff --git a/examples/examples/iam/src/iam-service-lib.rs b/examples/examples/iam/src/iam-service-lib.rs index 4f6b71a25c31..5fb5c70be3aa 100644 --- a/examples/examples/iam/src/iam-service-lib.rs +++ b/examples/examples/iam/src/iam-service-lib.rs @@ -371,33 +371,28 @@ pub async fn list_policies( client: iamClient, path_prefix: String, ) -> Result, SdkError> { - let mut list_policies = client + let list_policies = client .list_policies() .path_prefix(path_prefix) .scope(PolicyScopeType::Local) .into_paginator() - .send(); - - let mut v = Vec::new(); - - while let Some(list_policies_output) = list_policies.next().await { - match list_policies_output { - Ok(list_policies) => { - for policy in list_policies.policies() { - let policy_name = policy - .policy_name() - .unwrap_or("Missing policy name.") - .to_string(); - println!("{}", policy_name); - v.push(policy_name); - } - } - - Err(err) => return Err(err), - } - } + .items() + .send() + .try_collect() + .await?; - Ok(v) + let policy_names = list_policies + .into_iter() + .map(|p| { + let name = p + .policy_name + .unwrap_or_else(|| "Missing Policy Name".to_string()); + println!("{}", name); + name + }) + .collect(); + + Ok(policy_names) } // snippet-end:[rust.example_code.iam.hello_lib] // snippet-end:[rust.example_code.iam.service.list_policies] diff --git a/examples/examples/iot/Cargo.toml b/examples/examples/iot/Cargo.toml index 625130080729..1064cc1bfccd 100644 --- a/examples/examples/iot/Cargo.toml +++ b/examples/examples/iot/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-iot= { version = "0.37.0", path = "../../../sdk/iot" } aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } diff --git a/examples/examples/kinesis/Cargo.toml b/examples/examples/kinesis/Cargo.toml index 57b9f4be3b51..8ba8cbc43242 100644 --- a/examples/examples/kinesis/Cargo.toml +++ b/examples/examples/kinesis/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-kinesis= { version = "0.37.0", path = "../../../sdk/kinesis" } [dependencies.tokio] diff --git a/examples/examples/kms/Cargo.toml b/examples/examples/kms/Cargo.toml index 894b30bb8096..562fc4639b68 100644 --- a/examples/examples/kms/Cargo.toml +++ b/examples/examples/kms/Cargo.toml @@ -9,7 +9,7 @@ publish = false [dependencies] base64 = "0.13.0" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-kms= { version = "0.37.0", path = "../../../sdk/kms" } [dependencies.tokio] diff --git a/examples/examples/lambda/Cargo.toml b/examples/examples/lambda/Cargo.toml index cd9fdf53b9d4..281a59945fb2 100644 --- a/examples/examples/lambda/Cargo.toml +++ b/examples/examples/lambda/Cargo.toml @@ -11,7 +11,7 @@ serde_json = "1.0.94" anyhow = "1.0.71" lambda_runtime = "0.8.0" serde = "1.0.164" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-ec2= { version = "0.37.0", path = "../../../sdk/ec2" } aws-sdk-iam= { version = "0.37.0", path = "../../../sdk/iam" } aws-sdk-lambda= { version = "0.37.0", path = "../../../sdk/lambda" } diff --git a/examples/examples/lambda/src/actions.rs b/examples/examples/lambda/src/actions.rs index 7b822b1e2298..fb08df06b96e 100644 --- a/examples/examples/lambda/src/actions.rs +++ b/examples/examples/lambda/src/actions.rs @@ -22,7 +22,7 @@ use aws_sdk_s3::{ use aws_smithy_types::Blob; use serde::{ser::SerializeMap, Serialize}; use std::{path::PathBuf, str::FromStr, time::Duration}; -use tracing::{debug, error, info, warn}; +use tracing::{debug, info, warn}; /* Operation describes */ #[derive(Clone, Copy, Debug, Serialize)] @@ -345,16 +345,15 @@ impl LambdaManager { LastUpdateStatus::Failed | LastUpdateStatus::InProgress => { return Ok(false); } - LastUpdateStatus::Unknown(status_variant) => { - warn!(?status_variant, "LastUpdateStatus unknown"); + unknown => { + warn!( + status_variant = unknown.as_str(), + "LastUpdateStatus unknown" + ); return Err(anyhow!( "Unknown LastUpdateStatus, fn config is {config:?}" )); } - _ => { - error!("Unmatched LastUpdateStatus"); - return Err(anyhow!("Unmatched LastUpdateStatus")); - } } } None => { diff --git a/examples/examples/lambda/src/main.rs b/examples/examples/lambda/src/main.rs index 12d3b12f9d72..71465f29c574 100644 --- a/examples/examples/lambda/src/main.rs +++ b/examples/examples/lambda/src/main.rs @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ // snippet-start:[lambda.rust.main] +use aws_config::BehaviorVersion; use lambda_runtime::{service_fn, Error, LambdaEvent}; use serde::{Deserialize, Serialize}; use std::time::SystemTime; @@ -99,7 +100,7 @@ async fn main() -> Result<(), Error> { // // No extra configuration is needed as long as your Lambda has // the necessary permissions attached to its role. - let config = aws_config::load_from_env().await; + let config = aws_config::load_defaults(BehaviorVersion::latest()).await; let s3_client = aws_sdk_s3::Client::new(&config); lambda_runtime::run(service_fn(|event: LambdaEvent| async { diff --git a/examples/examples/localstack/Cargo.toml b/examples/examples/localstack/Cargo.toml index 867f24a057f4..f859936a1aa1 100644 --- a/examples/examples/localstack/Cargo.toml +++ b/examples/examples/localstack/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] http = "0.2" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-s3= { version = "0.37.0", path = "../../../sdk/s3" } aws-sdk-sqs= { version = "0.37.0", path = "../../../sdk/sqs" } diff --git a/examples/examples/localstack/src/bin/use-localstack.rs b/examples/examples/localstack/src/bin/use-localstack.rs index 21b5eb9da280..8b63451a265d 100644 --- a/examples/examples/localstack/src/bin/use-localstack.rs +++ b/examples/examples/localstack/src/bin/use-localstack.rs @@ -6,13 +6,14 @@ #![allow(clippy::result_large_err)] // snippet-start:[localstack.rust.use-localstack] +use aws_config::BehaviorVersion; use std::error::Error; #[tokio::main] async fn main() -> Result<(), Box> { tracing_subscriber::fmt::init(); - let shared_config = aws_config::from_env().load().await; + let shared_config = aws_config::load_defaults(BehaviorVersion::latest()).await; let sqs_client = sqs_client(&shared_config); let s3_client = s3_client(&shared_config); diff --git a/examples/examples/logging/logger/Cargo.toml b/examples/examples/logging/logger/Cargo.toml index a6ca84427e7f..722fb810efcd 100644 --- a/examples/examples/logging/logger/Cargo.toml +++ b/examples/examples/logging/logger/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] env_logger = "0.9.0" -aws-config= { version = "0.100.0", path = "../../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-dynamodb= { version = "0.37.0", path = "../../../../sdk/dynamodb" } [dependencies.clap] diff --git a/examples/examples/logging/logger/src/main.rs b/examples/examples/logging/logger/src/main.rs index 70aa8539cba4..5e26de4d03aa 100644 --- a/examples/examples/logging/logger/src/main.rs +++ b/examples/examples/logging/logger/src/main.rs @@ -7,6 +7,7 @@ // snippet-start:[logging.rust.main] use aws_config::meta::region::RegionProviderChain; +use aws_config::BehaviorVersion; use aws_sdk_dynamodb::{config::Region, meta::PKG_VERSION, Client, Error}; use clap::Parser; @@ -45,7 +46,10 @@ async fn main() -> Result<(), Error> { println!(); } - let shared_config = aws_config::from_env().region(region_provider).load().await; + let shared_config = aws_config::defaults(BehaviorVersion::latest()) + .region(region_provider) + .load() + .await; let client = Client::new(&shared_config); let resp = client.list_tables().send().await?; diff --git a/examples/examples/logging/tracing/Cargo.toml b/examples/examples/logging/tracing/Cargo.toml index a9e3819d9530..5ddca88588b7 100644 --- a/examples/examples/logging/tracing/Cargo.toml +++ b/examples/examples/logging/tracing/Cargo.toml @@ -7,7 +7,7 @@ version = "0.1.0" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-dynamodb= { version = "0.37.0", path = "../../../../sdk/dynamodb" } [dependencies.clap] diff --git a/examples/examples/logging/tracing/src/main.rs b/examples/examples/logging/tracing/src/main.rs index e1086bbd15f5..86e024cf7d1a 100644 --- a/examples/examples/logging/tracing/src/main.rs +++ b/examples/examples/logging/tracing/src/main.rs @@ -7,6 +7,7 @@ // snippet-start:[tracing.rust.main] use aws_config::meta::region::RegionProviderChain; +use aws_config::BehaviorVersion; use aws_sdk_dynamodb::{config::Region, meta::PKG_VERSION, Client, Error}; use clap::Parser; @@ -45,7 +46,10 @@ async fn main() -> Result<(), Error> { println!(); } - let shared_config = aws_config::from_env().region(region_provider).load().await; + let shared_config = aws_config::defaults(BehaviorVersion::latest()) + .region(region_provider) + .load() + .await; let client = Client::new(&shared_config); let resp = client.list_tables().send().await?; diff --git a/examples/examples/medialive/Cargo.toml b/examples/examples/medialive/Cargo.toml index 2c8f78c054cd..c962ee8c5d3b 100644 --- a/examples/examples/medialive/Cargo.toml +++ b/examples/examples/medialive/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-medialive= { version = "0.37.0", path = "../../../sdk/medialive" } [dependencies.tokio] diff --git a/examples/examples/mediapackage/Cargo.toml b/examples/examples/mediapackage/Cargo.toml index 246f4937fb1a..ea44cc7d0737 100644 --- a/examples/examples/mediapackage/Cargo.toml +++ b/examples/examples/mediapackage/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-mediapackage= { version = "0.37.0", path = "../../../sdk/mediapackage" } [dependencies.tokio] diff --git a/examples/examples/polly/Cargo.toml b/examples/examples/polly/Cargo.toml index d80237f53f78..8a7a02c18068 100644 --- a/examples/examples/polly/Cargo.toml +++ b/examples/examples/polly/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] bytes = "1" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-polly= { version = "0.37.0", path = "../../../sdk/polly" } [dependencies.tokio] diff --git a/examples/examples/qldb/Cargo.toml b/examples/examples/qldb/Cargo.toml index b5ee025f97fa..052e361d7e8c 100644 --- a/examples/examples/qldb/Cargo.toml +++ b/examples/examples/qldb/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-qldb= { version = "0.37.0", path = "../../../sdk/qldb" } aws-sdk-qldbsession= { version = "0.37.0", path = "../../../sdk/qldbsession" } diff --git a/examples/examples/rds/Cargo.toml b/examples/examples/rds/Cargo.toml index 4bbe74c927c7..f9a4d9293666 100644 --- a/examples/examples/rds/Cargo.toml +++ b/examples/examples/rds/Cargo.toml @@ -14,7 +14,7 @@ inquire = "0.6.2" mockall = "0.11.4" secrecy = "0.8.0" tracing = "0.1.37" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-smithy-http= { version = "0.58.0", path = "../../../sdk/aws-smithy-http" } aws-smithy-runtime-api= { version = "0.100.0", path = "../../../sdk/aws-smithy-runtime-api" } aws-sdk-rds= { version = "0.37.0", path = "../../../sdk/rds" } diff --git a/examples/examples/rdsdata/Cargo.toml b/examples/examples/rdsdata/Cargo.toml index 87c4f6db327b..f1bd37f5e3b7 100644 --- a/examples/examples/rdsdata/Cargo.toml +++ b/examples/examples/rdsdata/Cargo.toml @@ -7,7 +7,7 @@ version = "0.1.0" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-rdsdata= { version = "0.37.0", path = "../../../sdk/rdsdata" } [dependencies.tokio] diff --git a/examples/examples/route53/Cargo.toml b/examples/examples/route53/Cargo.toml index 00dc3ffe07f1..f6d4a8d31e9c 100644 --- a/examples/examples/route53/Cargo.toml +++ b/examples/examples/route53/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-route53= { version = "0.37.0", path = "../../../sdk/route53" } [dependencies.tokio] diff --git a/examples/examples/s3/Cargo.toml b/examples/examples/s3/Cargo.toml index 289380e24e6e..f1e294334b98 100644 --- a/examples/examples/s3/Cargo.toml +++ b/examples/examples/s3/Cargo.toml @@ -29,7 +29,7 @@ rand = "0.8.5" thiserror = "1.0" tokio-stream = "0.1.8" tracing = "0.1.37" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-endpoint= { version = "0.58.0", path = "../../../sdk/aws-endpoint" } aws-sdk-s3= { version = "0.37.0", path = "../../../sdk/s3", features = ["rt-tokio"] } aws-smithy-runtime= { version = "0.58.0", path = "../../../sdk/aws-smithy-runtime" } diff --git a/examples/examples/s3/src/bin/get-object.rs b/examples/examples/s3/src/bin/get-object.rs index f0b3975a197e..a3cae7ca3735 100644 --- a/examples/examples/s3/src/bin/get-object.rs +++ b/examples/examples/s3/src/bin/get-object.rs @@ -3,7 +3,7 @@ use std::{fs::File, io::Write, path::PathBuf, process::exit}; use aws_sdk_s3::Client; use clap::Parser; -use tracing::log::trace; +use tracing::trace; #[derive(Debug, Parser)] struct Opt { @@ -32,9 +32,10 @@ async fn get_object(client: Client, opt: Opt) -> Result { let mut byte_count = 0_usize; while let Some(bytes) = object.body.try_next().await? { - let bytes = file.write(&bytes)?; - byte_count += bytes; - trace!("Intermediate write of {bytes}"); + let bytes_len = bytes.len(); + file.write_all(&bytes)?; + trace!("Intermediate write of {bytes_len}"); + byte_count += bytes_len; } Ok(byte_count) diff --git a/examples/examples/s3/src/bin/if-modified-since.rs b/examples/examples/s3/src/bin/if-modified-since.rs index 9595c1ea96ee..8a251c81d11f 100644 --- a/examples/examples/s3/src/bin/if-modified-since.rs +++ b/examples/examples/s3/src/bin/if-modified-since.rs @@ -10,7 +10,6 @@ use aws_sdk_s3::{ primitives::{ByteStream, DateTime, DateTimeFormat}, Client, Error, }; -use http::StatusCode; use tracing::{error, warn}; const KEY: &str = "key"; @@ -85,21 +84,17 @@ async fn main() -> Result<(), Error> { Err(err) => match err { SdkError::ServiceError(err) => { let http = err.raw(); - match http.status() { - StatusCode::NOT_MODIFIED => ( + match http.status().as_u16() { + // HTTP 304: not modified + 304 => ( Ok(Some( DateTime::from_str( - http.headers() - .get("last-modified") - .map(|t| t.to_str().unwrap()) - .unwrap(), + http.headers().get("last-modified").unwrap(), DateTimeFormat::HttpDate, ) .unwrap(), )), - http.headers() - .get("etag") - .map(|t| t.to_str().unwrap().into()), + http.headers().get("etag").map(|t| t.into()), ), _ => (Err(SdkError::ServiceError(err)), None), } diff --git a/examples/examples/s3/src/bin/put-object-progress.rs b/examples/examples/s3/src/bin/put-object-progress.rs index 9f47c536254a..be73f00b14ef 100644 --- a/examples/examples/s3/src/bin/put-object-progress.rs +++ b/examples/examples/s3/src/bin/put-object-progress.rs @@ -11,7 +11,7 @@ use aws_sdk_s3::{ primitives::{ByteStream, SdkBody}, Client, }; -use aws_smithy_runtime_api::client::http::request::Request; +use aws_smithy_runtime_api::http::Request; use bytes::Bytes; use clap::Parser; use http_body::{Body, SizeHint}; diff --git a/examples/examples/sagemaker/Cargo.toml b/examples/examples/sagemaker/Cargo.toml index 8f5180baf56c..46658fec8962 100644 --- a/examples/examples/sagemaker/Cargo.toml +++ b/examples/examples/sagemaker/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] thiserror = "1.0" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-sagemaker= { version = "0.37.0", path = "../../../sdk/sagemaker" } aws-smithy-types-convert= { version = "0.58.0", path = "../../../sdk/aws-smithy-types-convert", features = ["convert-chrono"] } diff --git a/examples/examples/sdk-config/Cargo.toml b/examples/examples/sdk-config/Cargo.toml index c712fad969ad..6596089605fb 100644 --- a/examples/examples/sdk-config/Cargo.toml +++ b/examples/examples/sdk-config/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "custom-retries-examples" version = "0.1.0" -authors = ["John DiSanti ", "Doug Schwartz "] +authors = ["John DiSanti ", "Doug Schwartz ", "David Souther "] edition = "2021" publish = false @@ -10,7 +10,8 @@ publish = false lazy_static = "1.4.0" async_once = "0.2.6" tracing = "0.1.37" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } +aws-credential-types= { version = "0.58.0", path = "../../../sdk/aws-credential-types" } aws-sdk-s3= { version = "0.37.0", path = "../../../sdk/s3" } [dependencies.tokio] diff --git a/examples/examples/sdk-config/src/bin/disable_retries.rs b/examples/examples/sdk-config/src/bin/disable_retries.rs index ebfb893f4adb..e200ef85a4b5 100644 --- a/examples/examples/sdk-config/src/bin/disable_retries.rs +++ b/examples/examples/sdk-config/src/bin/disable_retries.rs @@ -6,6 +6,7 @@ #![allow(clippy::result_large_err)] use aws_config::meta::region::RegionProviderChain; +use aws_config::BehaviorVersion; use aws_sdk_s3::config::retry::RetryConfig; use aws_sdk_s3::{config::Region, meta::PKG_VERSION, Client, Error}; use clap::Parser; @@ -58,7 +59,7 @@ async fn main() -> Result<(), Error> { } // snippet-start:[custom_retries.rust.disable_retries] - let shared_config = aws_config::from_env() + let shared_config = aws_config::defaults(BehaviorVersion::latest()) .region(region_provider) // Disable retries .retry_config(RetryConfig::disabled()) diff --git a/examples/examples/sdk-config/src/bin/no_env.rs b/examples/examples/sdk-config/src/bin/no_env.rs new file mode 100644 index 000000000000..134a9478c44b --- /dev/null +++ b/examples/examples/sdk-config/src/bin/no_env.rs @@ -0,0 +1,139 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#![allow(clippy::result_large_err)] + +// File overview: This example shows how to create an SdkConfig without using the +// default AWS environment configuration. + +use aws_config::meta::region::RegionProviderChain; +use aws_credential_types::provider::{ProvideCredentials, SharedCredentialsProvider}; +use aws_sdk_s3::config::retry::RetryConfig; +use aws_sdk_s3::config::Credentials; +use aws_sdk_s3::{config::Region, meta::PKG_VERSION, Client, Error}; +use clap::Parser; + +#[derive(Debug, Parser)] +struct Opt { + /// The AWS Region. + #[structopt(short, long)] + region: Option, + + /// The number of (re)tries. + #[structopt(short, long, default_value = "2")] + tries: u32, + + /// Whether to display additional information. + #[structopt(short, long)] + verbose: bool, +} + +// Shows your buckets. +async fn show_num_buckets(client: &Client) -> Result<(), Error> { + let resp = client.list_buckets().send().await?; + let buckets = resp.buckets(); + + println!("Found {} buckets in all regions.", buckets.len()); + + Ok(()) +} + +/// A Credentials provider that uses non-standard environment variables `MY_ID` +/// and `MY_KEY` instead of `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. This +/// could alternatively load credentials from another secure source of environment +/// secrets, if traditional AWS SDK for Rust credentials providers do not suit +/// your use case. +/// +/// WARNING: This example is for demonstration purposes only. Your code should always +/// load credentials in a secure fashion. +#[derive(Debug)] +struct StaticCredentials { + access_key_id: String, + secret_access_key: String, +} + +impl StaticCredentials { + pub fn new() -> Self { + let access_key_id = std::env::var("MY_ID").expect("access key id"); + let secret_access_key = std::env::var("MY_KEY").expect("secret access key"); + Self { + access_key_id: access_key_id.trim().to_string(), + secret_access_key: secret_access_key.trim().to_string(), + } + } + + async fn load_credentials(&self) -> aws_credential_types::provider::Result { + Ok(Credentials::new( + self.access_key_id.clone(), + self.secret_access_key.clone(), + None, + None, + "StaticCredentials", + )) + } +} + +impl ProvideCredentials for StaticCredentials { + fn provide_credentials<'a>( + &'a self, + ) -> aws_credential_types::provider::future::ProvideCredentials<'a> + where + Self: 'a, + { + aws_credential_types::provider::future::ProvideCredentials::new(self.load_credentials()) + } +} + +/// Displays how many Amazon S3 buckets you have. +/// # Arguments +/// +/// * `[-r REGION]` - The Region in which the client is created. +/// If not supplied, uses the value of the **AWS_REGION** environment variable. +/// If the environment variable is not set, defaults to **us-west-2**. +/// * `[-t TRIES]` - The number of times to (re)try the request. +/// * `[-v]` - Whether to display additional information. +/// +/// # Environment +/// +/// * MY_ID - an AWS IAM Access Key ID to use for this request. +/// * MY_KEY - an AWS IAM Secret Access Key to use for this request. +#[tokio::main] +async fn main() -> Result<(), Error> { + tracing_subscriber::fmt::init(); + + let Opt { + region, + tries, + verbose, + } = Opt::parse(); + + let region = RegionProviderChain::first_try(region.map(Region::new)) + .or_else(Region::new("us-west-2")) + .region() + .await + .expect("parsed region"); + println!(); + + if verbose { + println!("S3 client version: {PKG_VERSION}"); + println!("Region: {region}"); + println!("Retries: {tries}"); + println!(); + } + + assert_ne!(tries, 0, "You cannot set zero retries."); + + let shared_config = aws_config::SdkConfig::builder() + .region(region) + .credentials_provider(SharedCredentialsProvider::new(StaticCredentials::new())) + // Set max attempts. + // If tries is 1, there are no retries. + .retry_config(RetryConfig::standard().with_max_attempts(tries)) + .build(); + + // Construct an S3 client with customized retry configuration. + let client = Client::new(&shared_config); + + show_num_buckets(&client).await +} diff --git a/examples/examples/sdk-config/src/bin/set_retries.rs b/examples/examples/sdk-config/src/bin/set_retries.rs index c8ec67e969e5..ddce0e102153 100644 --- a/examples/examples/sdk-config/src/bin/set_retries.rs +++ b/examples/examples/sdk-config/src/bin/set_retries.rs @@ -6,6 +6,7 @@ #![allow(clippy::result_large_err)] use aws_config::meta::region::RegionProviderChain; +use aws_config::BehaviorVersion; use aws_sdk_s3::config::retry::RetryConfig; use aws_sdk_s3::{config, config::Region, meta::PKG_VERSION, Client, Error}; use clap::Parser; @@ -71,7 +72,10 @@ async fn main() -> Result<(), Error> { assert_ne!(tries, 0, "You cannot set zero retries."); // snippet-start:[custom_retries.rust.set_retries] - let shared_config = aws_config::from_env().region(region_provider).load().await; + let shared_config = aws_config::defaults(BehaviorVersion::latest()) + .region(region_provider) + .load() + .await; // Construct an S3 client with customized retry configuration. let client = Client::from_conf( diff --git a/examples/examples/secretsmanager/Cargo.toml b/examples/examples/secretsmanager/Cargo.toml index cd76f70d4093..bf9e3017a9ab 100644 --- a/examples/examples/secretsmanager/Cargo.toml +++ b/examples/examples/secretsmanager/Cargo.toml @@ -8,7 +8,7 @@ description = "Example usage of the SecretManager service" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-secretsmanager= { version = "0.37.0", path = "../../../sdk/secretsmanager" } [dependencies.tokio] diff --git a/examples/examples/sending-presigned-requests/Cargo.toml b/examples/examples/sending-presigned-requests/Cargo.toml index 3dfc84d1cf76..dcd91f8fb086 100644 --- a/examples/examples/sending-presigned-requests/Cargo.toml +++ b/examples/examples/sending-presigned-requests/Cargo.toml @@ -11,7 +11,7 @@ http = "0.2.6" hyper = "0.14" reqwest = "0.11" hyper-tls = "0.5.0" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-s3= { version = "0.37.0", path = "../../../sdk/s3" } aws-smithy-client= { version = "0.58.0", path = "../../../sdk/aws-smithy-client" } diff --git a/examples/examples/ses/Cargo.toml b/examples/examples/ses/Cargo.toml index ca14fa2df883..c75ad2f72b40 100644 --- a/examples/examples/ses/Cargo.toml +++ b/examples/examples/ses/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-sesv2= { version = "0.37.0", path = "../../../sdk/sesv2" } [dependencies.tokio] diff --git a/examples/examples/sitewise/Cargo.toml b/examples/examples/sitewise/Cargo.toml index 13ee932386de..90250416e983 100644 --- a/examples/examples/sitewise/Cargo.toml +++ b/examples/examples/sitewise/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] thiserror = "1.0" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-iotsitewise= { version = "0.37.0", path = "../../../sdk/iotsitewise" } aws-smithy-types-convert= { version = "0.58.0", path = "../../../sdk/aws-smithy-types-convert", features = ["convert-chrono"] } diff --git a/examples/examples/snowball/Cargo.toml b/examples/examples/snowball/Cargo.toml index 158834edb77f..134c01f35780 100644 --- a/examples/examples/snowball/Cargo.toml +++ b/examples/examples/snowball/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-snowball= { version = "0.37.0", path = "../../../sdk/snowball" } [dependencies.tokio] diff --git a/examples/examples/sns/Cargo.toml b/examples/examples/sns/Cargo.toml index c1989a03a77c..a73c624d7fae 100644 --- a/examples/examples/sns/Cargo.toml +++ b/examples/examples/sns/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-sns= { version = "0.37.0", path = "../../../sdk/sns" } [dependencies.tokio] diff --git a/examples/examples/sqs/Cargo.toml b/examples/examples/sqs/Cargo.toml index 6fed03fb14d8..97ab3217f916 100644 --- a/examples/examples/sqs/Cargo.toml +++ b/examples/examples/sqs/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-sqs= { version = "0.37.0", path = "../../../sdk/sqs" } [dependencies.tokio] diff --git a/examples/examples/ssm/Cargo.toml b/examples/examples/ssm/Cargo.toml index 1a29a2c88f80..f014c14174f1 100644 --- a/examples/examples/ssm/Cargo.toml +++ b/examples/examples/ssm/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-ssm= { version = "0.37.0", path = "../../../sdk/ssm" } [dependencies.tokio] diff --git a/examples/examples/stepfunction/Cargo.toml b/examples/examples/stepfunction/Cargo.toml index 78bc4017fc89..b1ef7edf75d7 100644 --- a/examples/examples/stepfunction/Cargo.toml +++ b/examples/examples/stepfunction/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-sfn= { version = "0.37.0", path = "../../../sdk/sfn" } [dependencies.tokio] diff --git a/examples/examples/sts/Cargo.toml b/examples/examples/sts/Cargo.toml index c9a15de12916..71e0b16e4c67 100644 --- a/examples/examples/sts/Cargo.toml +++ b/examples/examples/sts/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-sts= { version = "0.37.0", path = "../../../sdk/sts" } aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } diff --git a/examples/examples/testing/Cargo.toml b/examples/examples/testing/Cargo.toml index bb9ac27c3f0a..864c3e8e95f6 100644 --- a/examples/examples/testing/Cargo.toml +++ b/examples/examples/testing/Cargo.toml @@ -1,7 +1,7 @@ # Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT. [[bin]] -name = "intro" -path = "src/intro.rs" +name = "main" +path = "src/main.rs" [package] name = "testing-examples" @@ -12,21 +12,25 @@ publish = false [dependencies] async-trait = "0.1.51" +http = "0.2.9" +mockall = "0.11.4" serde_json = "1" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } +aws-credential-types= { version = "0.58.0", path = "../../../sdk/aws-credential-types", features = ["hardcoded-credentials"] } aws-sdk-s3= { version = "0.37.0", path = "../../../sdk/s3" } -aws-smithy-http= { version = "0.58.0", path = "../../../sdk/aws-smithy-http" } +aws-smithy-types= { version = "0.100.0", path = "../../../sdk/aws-smithy-types" } +aws-smithy-runtime= { version = "0.58.0", path = "../../../sdk/aws-smithy-runtime", features = ["test-util"] } +aws-smithy-runtime-api= { version = "0.100.0", path = "../../../sdk/aws-smithy-runtime-api", features = ["test-util"] } aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } -aws-credential-types= { version = "0.58.0", path = "../../../sdk/aws-credential-types", features = ["hardcoded-credentials"] } - -[dependencies.tokio] -version = "1.20.1" -features = ["full"] [dependencies.clap] version = "~4.4" features = ["derive"] +[dependencies.tokio] +version = "1.20.1" +features = ["full"] + [dependencies.tracing-subscriber] version = "0.3.15" features = ["env-filter"] diff --git a/examples/examples/testing/src/enums.rs b/examples/examples/testing/src/enums.rs index c07e4880d175..75279478c329 100644 --- a/examples/examples/testing/src/enums.rs +++ b/examples/examples/testing/src/enums.rs @@ -3,19 +3,18 @@ * SPDX-License-Identifier: Apache-2.0. */ -#![allow(dead_code)] - use aws_sdk_s3 as s3; -use std::error::Error; +#[allow(dead_code)] // snippet-start:[testing.rust.enums-struct] pub struct ListObjectsResult { pub objects: Vec, - pub continuation_token: Option, + pub next_continuation_token: Option, pub has_more: bool, } // snippet-end:[testing.rust.enums-struct] +#[allow(dead_code)] // snippet-start:[testing.rust.enums-enum] pub enum ListObjects { Real(s3::Client), @@ -30,12 +29,13 @@ pub enum ListObjects { // snippet-start:[testing.rust.enums-list_objects] impl ListObjects { + #[allow(dead_code)] pub async fn list_objects( &self, bucket: &str, prefix: &str, continuation_token: Option, - ) -> Result> { + ) -> Result { match self { Self::Real(s3) => { Self::real_list_objects(s3.clone(), bucket, prefix, continuation_token).await @@ -54,13 +54,14 @@ impl ListObjects { } // snippet-end:[testing.rust.enums-list_objects] + #[allow(dead_code)] // snippet-start:[testing.rust.enums-real-list-objects] async fn real_list_objects( s3: s3::Client, bucket: &str, prefix: &str, continuation_token: Option, - ) -> Result> { + ) -> Result { let response = s3 .list_objects_v2() .bucket(bucket) @@ -70,18 +71,19 @@ impl ListObjects { .await?; Ok(ListObjectsResult { objects: response.contents().to_vec(), - continuation_token: response.continuation_token().map(|t| t.to_string()), + next_continuation_token: response.next_continuation_token.clone(), has_more: response.is_truncated(), }) } // snippet-end:[testing.rust.enums-real-list-objects] + #[allow(clippy::result_large_err)] // snippet-start:[testing.rust.enums-test] #[cfg(test)] fn test_list_objects( pages: &[Vec], continuation_token: Option, - ) -> Result> { + ) -> Result { use std::str::FromStr; let index = continuation_token .map(|t| usize::from_str(&t).expect("valid token")) @@ -89,13 +91,13 @@ impl ListObjects { if pages.is_empty() { Ok(ListObjectsResult { objects: Vec::new(), - continuation_token: None, + next_continuation_token: None, has_more: false, }) } else { Ok(ListObjectsResult { - objects: pages[index].clone(), - continuation_token: Some(format!("{}", index + 1)), + objects: pages[index].to_vec(), + next_continuation_token: Some(format!("{}", index + 1)), has_more: index + 1 < pages.len(), }) } @@ -103,13 +105,14 @@ impl ListObjects { } // snippet-end:[testing.rust.enums-test] +#[allow(dead_code)] // snippet-start:[testing.rust.enums-function] async fn determine_prefix_file_size( // Now we take an instance of our enum rather than the S3 client list_objects_impl: ListObjects, bucket: &str, prefix: &str, -) -> Result> { +) -> Result { let mut next_token: Option = None; let mut total_size_bytes = 0; loop { @@ -123,7 +126,7 @@ async fn determine_prefix_file_size( } // Handle pagination, and break the loop if there are no more pages - next_token = result.continuation_token; + next_token = result.next_continuation_token; if !result.has_more { break; } @@ -132,53 +135,58 @@ async fn determine_prefix_file_size( } // snippet-end:[testing.rust.enums-function] -// snippet-start:[testing.rust.enums-tests] -#[tokio::test] -async fn test_single_page() { - use s3::types::Object; - - // Create a TestListObjects instance with just one page of two objects in it - let fake = ListObjects::Test { - expected_bucket: "some-bucket".into(), - expected_prefix: "some-prefix".into(), - pages: vec![[5, 2i64] - .iter() - .map(|size| Object::builder().size(*size).build()) - .collect()], - }; - - // Run the code we want to test with it - let size = determine_prefix_file_size(fake, "some-bucket", "some-prefix") - .await - .unwrap(); - - // Verify we got the correct total size back - assert_eq!(7, size); -} +#[cfg(test)] +mod test { + use super::*; + use aws_sdk_s3 as s3; + // snippet-start:[testing.rust.enums-tests] + #[tokio::test] + async fn test_single_page() { + use s3::types::Object; + + // Create a TestListObjects instance with just one page of two objects in it + let fake = ListObjects::Test { + expected_bucket: "test-bucket".into(), + expected_prefix: "test-prefix".into(), + pages: vec![vec![ + Object::builder().size(5).build(), + Object::builder().size(2).build(), + ]], + }; + + // Run the code we want to test with it + let size = determine_prefix_file_size(fake, "test-bucket", "test-prefix") + .await + .unwrap(); + + // Verify we got the correct total size back + assert_eq!(7, size); + } -#[tokio::test] -async fn test_multiple_pages() { - use s3::types::Object; + #[tokio::test] + async fn test_multiple_pages() { + use s3::types::Object; - // This time, we add a helper function for making pages - fn make_page(sizes: &[i64]) -> Vec { - sizes - .iter() - .map(|size| Object::builder().size(*size).build()) - .collect() - } + // This time, we add a helper function for making pages + fn make_page(sizes: &[i64]) -> Vec { + sizes + .iter() + .map(|size| Object::builder().size(*size).build()) + .collect() + } - // Create the TestListObjects instance with two pages of objects now - let fake = ListObjects::Test { - expected_bucket: "some-bucket".into(), - expected_prefix: "some-prefix".into(), - pages: vec![make_page(&[5, 2]), make_page(&[3, 9])], - }; - - // And now test and verify - let size = determine_prefix_file_size(fake, "some-bucket", "some-prefix") - .await - .unwrap(); - assert_eq!(19, size); + // Create the TestListObjects instance with two pages of objects now + let fake = ListObjects::Test { + expected_bucket: "test-bucket".into(), + expected_prefix: "test-prefix".into(), + pages: vec![make_page(&[5, 2]), make_page(&[3, 9])], + }; + + // And now test and verify + let size = determine_prefix_file_size(fake, "test-bucket", "test-prefix") + .await + .unwrap(); + assert_eq!(19, size); + } + // snippet-end:[testing.rust.enums-tests] } -// snippet-end:[testing.rust.enums-tests] diff --git a/examples/examples/testing/src/intro.rs b/examples/examples/testing/src/main.rs similarity index 90% rename from examples/examples/testing/src/intro.rs rename to examples/examples/testing/src/main.rs index 8d1dfabe2481..cc3973d8cecd 100644 --- a/examples/examples/testing/src/intro.rs +++ b/examples/examples/testing/src/main.rs @@ -9,7 +9,12 @@ use aws_config::meta::region::RegionProviderChain; use aws_sdk_s3 as s3; // snippet-end:[testing.rust.intro-import] use clap::Parser; -use std::error::Error; + +// The testing approaches imported as modules below +mod enums; +mod replay; +mod traits; +mod wrapper; #[derive(Debug, Parser)] struct Opt { @@ -30,17 +35,13 @@ struct Opt { verbose: bool, } -// The two testing approaches imported as modules below -mod enums; -mod traits; - // snippet-start:[testing.rust.intro-function] // Lists all objects in an S3 bucket with the given prefix, and adds up their size. async fn determine_prefix_file_size( s3: s3::Client, bucket: &str, prefix: &str, -) -> Result> { +) -> Result { let mut next_token: Option = None; let mut total_size_bytes = 0; loop { @@ -59,7 +60,7 @@ async fn determine_prefix_file_size( } // Handle pagination, and break the loop if there are no more pages - next_token = response.continuation_token().map(|t| t.to_string()); + next_token = response.next_continuation_token.clone(); if !response.is_truncated() { break; } @@ -68,8 +69,9 @@ async fn determine_prefix_file_size( } // snippet-end:[testing.rust.intro-function] +#[allow(clippy::result_large_err)] #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<(), s3::Error> { tracing_subscriber::fmt::init(); let Opt { diff --git a/examples/examples/testing/src/replay.rs b/examples/examples/testing/src/replay.rs new file mode 100644 index 000000000000..f6f349cbca68 --- /dev/null +++ b/examples/examples/testing/src/replay.rs @@ -0,0 +1,156 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +// snippet-start:[testing.rust.replay-uses] +use aws_sdk_s3 as s3; +// snippet-end:[testing.rust.replay-uses] + +#[allow(dead_code)] +// snippet-start:[testing.rust.replay] +pub async fn determine_prefix_file_size( + // Now we take a reference to our trait object instead of the S3 client + // s3_list: ListObjectsService, + s3: s3::Client, + bucket: &str, + prefix: &str, +) -> Result { + let mut next_token: Option = None; + let mut total_size_bytes = 0; + loop { + let result = s3 + .list_objects_v2() + .prefix(prefix) + .bucket(bucket) + .set_continuation_token(next_token.take()) + .send() + .await?; + + // Add up the file sizes we got back + for object in result.contents() { + total_size_bytes += object.size() as usize; + } + + // Handle pagination, and break the loop if there are no more pages + next_token = result.next_continuation_token.clone(); + if next_token.is_none() { + break; + } + } + Ok(total_size_bytes) +} +// snippet-end:[testing.rust.replay] + +#[allow(dead_code)] +// snippet-start:[testing.rust.replay-tests] +// snippet-start:[testing.rust.replay-make-credentials] +fn make_s3_test_credentials() -> s3::config::Credentials { + s3::config::Credentials::new( + "ATESTCLIENT", + "astestsecretkey", + Some("atestsessiontoken".to_string()), + None, + "", + ) +} +// snippet-end:[testing.rust.replay-make-credentials] + +// snippet-start:[testing.rust.replay-test-module] +#[cfg(test)] +mod test { + // snippet-start:[testing.rust.replay-test-single] + use super::*; + use aws_config::BehaviorVersion; + use aws_sdk_s3 as s3; + use aws_smithy_runtime::client::http::test_util::{ReplayEvent, StaticReplayClient}; + use aws_smithy_types::body::SdkBody; + + #[tokio::test] + async fn test_single_page() { + let page_1 = ReplayEvent::new( + http::Request::builder() + .method("GET") + .uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=test-prefix") + .body(SdkBody::empty()) + .unwrap(), + http::Response::builder() + .status(200) + .body(SdkBody::from(include_str!("./testing/response_1.xml"))) + .unwrap(), + ); + let replay_client = StaticReplayClient::new(vec![page_1]); + let client: s3::Client = s3::Client::from_conf( + s3::Config::builder() + .behavior_version(BehaviorVersion::latest()) + .credentials_provider(make_s3_test_credentials()) + .region(s3::config::Region::new("us-east-1")) + .http_client(replay_client.clone()) + .build(), + ); + + // Run the code we want to test with it + let size = determine_prefix_file_size(client, "test-bucket", "test-prefix") + .await + .unwrap(); + + // Verify we got the correct total size back + assert_eq!(7, size); + replay_client.assert_requests_match(&[]); + } + // snippet-end:[testing.rust.replay-test-single] + + // snippet-start:[testing.rust.replay-test-multiple] + #[tokio::test] + async fn test_multiple_pages() { + // snippet-start:[testing.rust.replay-create-replay] + let page_1 = ReplayEvent::new( + http::Request::builder() + .method("GET") + .uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=test-prefix") + .body(SdkBody::empty()) + .unwrap(), + http::Response::builder() + .status(200) + .body(SdkBody::from(include_str!("./testing/response_multi_1.xml"))) + .unwrap(), + ); + let page_2 = ReplayEvent::new( + http::Request::builder() + .method("GET") + .uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=test-prefix&continuation-token=next") + .body(SdkBody::empty()) + .unwrap(), + http::Response::builder() + .status(200) + .body(SdkBody::from(include_str!("./testing/response_multi_2.xml"))) + .unwrap(), + ); + let replay_client = StaticReplayClient::new(vec![page_1, page_2]); + // snippet-end:[testing.rust.replay-create-replay] + // snippet-start:[testing.rust.replay-create-client] + let client: s3::Client = s3::Client::from_conf( + s3::Config::builder() + .behavior_version(BehaviorVersion::latest()) + .credentials_provider(make_s3_test_credentials()) + .region(s3::config::Region::new("us-east-1")) + .http_client(replay_client.clone()) + .build(), + ); + // snippet-end:[testing.rust.replay-create-client] + + // Run the code we want to test with it + // snippet-start:[testing.rust.replay-test-and-verify] + let size = determine_prefix_file_size(client, "test-bucket", "test-prefix") + .await + .unwrap(); + + assert_eq!(19, size); + + replay_client.assert_requests_match(&[]); + // snippet-end:[testing.rust.replay-test-and-verify] + } + // snippet-end:[testing.rust.replay-test-multiple] +} +// snippet-end:[testing.rust.replay-tests] +// snippet-end:[testing.rust.replay-test-module] diff --git a/examples/examples/testing/src/testing/response_1.xml b/examples/examples/testing/src/testing/response_1.xml new file mode 100644 index 000000000000..5ce17d61ec24 --- /dev/null +++ b/examples/examples/testing/src/testing/response_1.xml @@ -0,0 +1,22 @@ + + + test-bucket + test-prefix + 2 + 1000 + false + + test-prefix/A + 2023-04-10T21:33:28.000Z + "a2" + 2 + STANDARD + + + test-prefix/B + 2023-04-10T21:33:28.000Z + "b5" + 5 + STANDARD + + \ No newline at end of file diff --git a/examples/examples/testing/src/testing/response_multi_1.xml b/examples/examples/testing/src/testing/response_multi_1.xml new file mode 100644 index 000000000000..563d7500473b --- /dev/null +++ b/examples/examples/testing/src/testing/response_multi_1.xml @@ -0,0 +1,23 @@ + + + test-bucket + test-prefix + 2 + 1000 + true + next + + test-prefix/A + 2023-04-10T21:33:28.000Z + "a2" + 2 + STANDARD + + + test-prefix/B + 2023-04-10T21:33:28.000Z + "b5" + 5 + STANDARD + + \ No newline at end of file diff --git a/examples/examples/testing/src/testing/response_multi_2.xml b/examples/examples/testing/src/testing/response_multi_2.xml new file mode 100644 index 000000000000..56f2e86130b5 --- /dev/null +++ b/examples/examples/testing/src/testing/response_multi_2.xml @@ -0,0 +1,22 @@ + + + test-bucket + test-prefix + 2 + 1000 + next + + test-prefix/C + 2023-04-10T21:33:28.000Z + "c3" + 3 + STANDARD + + + test-prefix/D + 2023-04-10T21:33:28.000Z + "d9" + 9 + STANDARD + + \ No newline at end of file diff --git a/examples/examples/testing/src/traits.rs b/examples/examples/testing/src/traits.rs index 8ace08cf4aee..5358423bc233 100644 --- a/examples/examples/testing/src/traits.rs +++ b/examples/examples/testing/src/traits.rs @@ -3,17 +3,14 @@ * SPDX-License-Identifier: Apache-2.0. */ -#![allow(dead_code)] - use async_trait::async_trait; use aws_sdk_s3 as s3; -use std::error::Error; use std::str::FromStr; // snippet-start:[testing.rust.traits-trait] pub struct ListObjectsResult { pub objects: Vec, - pub continuation_token: Option, + pub next_continuation_token: Option, pub has_more: bool, } @@ -24,7 +21,7 @@ pub trait ListObjects { bucket: &str, prefix: &str, continuation_token: Option, - ) -> Result>; + ) -> Result; } // snippet-end:[testing.rust.traits-trait] @@ -35,6 +32,7 @@ pub struct S3ListObjects { } impl S3ListObjects { + #[allow(dead_code)] pub fn new(s3: s3::Client) -> Self { Self { s3 } } @@ -47,7 +45,7 @@ impl ListObjects for S3ListObjects { bucket: &str, prefix: &str, continuation_token: Option, - ) -> Result> { + ) -> Result { let response = self .s3 .list_objects_v2() @@ -58,7 +56,7 @@ impl ListObjects for S3ListObjects { .await?; Ok(ListObjectsResult { objects: response.contents().to_vec(), - continuation_token: response.continuation_token().map(|t| t.to_string()), + next_continuation_token: response.next_continuation_token.clone(), has_more: response.is_truncated(), }) } @@ -79,24 +77,24 @@ impl ListObjects for TestListObjects { &self, bucket: &str, prefix: &str, - continuation_token: Option, - ) -> Result> { + next_continuation_token: Option, + ) -> Result { assert_eq!(self.expected_bucket, bucket); assert_eq!(self.expected_prefix, prefix); - let index = continuation_token + let index = next_continuation_token .map(|t| usize::from_str(&t).expect("valid token")) .unwrap_or_default(); if self.pages.is_empty() { Ok(ListObjectsResult { objects: Vec::new(), - continuation_token: None, + next_continuation_token: None, has_more: false, }) } else { Ok(ListObjectsResult { objects: self.pages[index].clone(), - continuation_token: Some(format!("{}", index + 1)), + next_continuation_token: Some(format!("{}", index + 1)), has_more: index + 1 < self.pages.len(), }) } @@ -104,13 +102,14 @@ impl ListObjects for TestListObjects { } // snippet-end:[testing.rust.traits-fake] +#[allow(dead_code)] // snippet-start:[testing.rust.traits-function] -async fn determine_prefix_file_size( +pub async fn determine_prefix_file_size( // Now we take a reference to our trait object instead of the S3 client list_objects_impl: &dyn ListObjects, bucket: &str, prefix: &str, -) -> Result> { +) -> Result { let mut next_token: Option = None; let mut total_size_bytes = 0; loop { @@ -124,7 +123,7 @@ async fn determine_prefix_file_size( } // Handle pagination, and break the loop if there are no more pages - next_token = result.continuation_token; + next_token = result.next_continuation_token; if !result.has_more { break; } @@ -133,53 +132,59 @@ async fn determine_prefix_file_size( } // snippet-end:[testing.rust.traits-function] -// snippet-start:[testing.rust.traits-tests] -#[tokio::test] -async fn test_single_page() { - use s3::types::Object; - - // Create a TestListObjects instance with just one page of two objects in it - let fake = TestListObjects { - expected_bucket: "some-bucket".into(), - expected_prefix: "some-prefix".into(), - pages: vec![[5, 2i64] - .iter() - .map(|size| Object::builder().size(*size).build()) - .collect()], - }; - - // Run the code we want to test with it - let size = determine_prefix_file_size(&fake, "some-bucket", "some-prefix") - .await - .unwrap(); - - // Verify we got the correct total size back - assert_eq!(7, size); -} +#[cfg(test)] +mod test { + use super::*; + use aws_sdk_s3 as s3; + + // snippet-start:[testing.rust.traits-tests] + #[tokio::test] + async fn test_single_page() { + use s3::types::Object; + + // Create a TestListObjects instance with just one page of two objects in it + let fake = TestListObjects { + expected_bucket: "test-bucket".into(), + expected_prefix: "test-prefix".into(), + pages: vec![vec![ + Object::builder().size(5).build(), + Object::builder().size(2).build(), + ]], + }; + + // Run the code we want to test with it + let size = determine_prefix_file_size(&fake, "test-bucket", "test-prefix") + .await + .unwrap(); + + // Verify we got the correct total size back + assert_eq!(7, size); + } -#[tokio::test] -async fn test_multiple_pages() { - use s3::types::Object; + #[tokio::test] + async fn test_multiple_pages() { + use s3::types::Object; - // This time, we add a helper function for making pages - fn make_page(sizes: &[i64]) -> Vec { - sizes - .iter() - .map(|size| Object::builder().size(*size).build()) - .collect() - } + // This time, we add a helper function for making pages + fn make_page(sizes: &[i64]) -> Vec { + sizes + .iter() + .map(|size| Object::builder().size(*size).build()) + .collect() + } - // Create the TestListObjects instance with two pages of objects now - let fake = TestListObjects { - expected_bucket: "some-bucket".into(), - expected_prefix: "some-prefix".into(), - pages: vec![make_page(&[5, 2]), make_page(&[3, 9])], - }; - - // And now test and verify - let size = determine_prefix_file_size(&fake, "some-bucket", "some-prefix") - .await - .unwrap(); - assert_eq!(19, size); + // Create the TestListObjects instance with two pages of objects now + let fake = TestListObjects { + expected_bucket: "test-bucket".into(), + expected_prefix: "test-prefix".into(), + pages: vec![make_page(&[5, 2]), make_page(&[3, 9])], + }; + + // And now test and verify + let size = determine_prefix_file_size(&fake, "test-bucket", "test-prefix") + .await + .unwrap(); + assert_eq!(19, size); + } + // snippet-end:[testing.rust.traits-tests] } -// snippet-end:[testing.rust.traits-tests] diff --git a/examples/examples/testing/src/wrapper.rs b/examples/examples/testing/src/wrapper.rs new file mode 100644 index 000000000000..6dae10e9f6fb --- /dev/null +++ b/examples/examples/testing/src/wrapper.rs @@ -0,0 +1,161 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +// snippet-start:[testing.rust.wrapper] +// snippet-start:[testing.rust.wrapper-uses] +use aws_sdk_s3 as s3; +#[allow(unused_imports)] +use mockall::automock; + +use s3::operation::list_objects_v2::{ListObjectsV2Error, ListObjectsV2Output}; +// snippet-end:[testing.rust.wrapper-uses] + +// snippet-start:[testing.rust.wrapper-which-impl] +#[cfg(test)] +pub use MockS3Impl as S3; +#[cfg(not(test))] +pub use S3Impl as S3; +// snippet-end:[testing.rust.wrapper-which-impl] + +// snippet-start:[testing.rust.wrapper-impl] +#[allow(dead_code)] +pub struct S3Impl { + inner: s3::Client, +} + +#[cfg_attr(test, automock)] +impl S3Impl { + #[allow(dead_code)] + pub fn new(inner: s3::Client) -> Self { + Self { inner } + } + + #[allow(dead_code)] + pub async fn list_objects( + &self, + bucket: &str, + prefix: &str, + continuation_token: Option, + ) -> Result> { + self.inner + .list_objects_v2() + .bucket(bucket) + .prefix(prefix) + .set_continuation_token(continuation_token) + .send() + .await + } +} +// snippet-end:[testing.rust.wrapper-impl] + +// snippet-start:[testing.rust.wrapper-func] +#[allow(dead_code)] +pub async fn determine_prefix_file_size( + // Now we take a reference to our trait object instead of the S3 client + // s3_list: ListObjectsService, + s3_list: S3, + bucket: &str, + prefix: &str, +) -> Result { + let mut next_token: Option = None; + let mut total_size_bytes = 0; + loop { + let result = s3_list + .list_objects(bucket, prefix, next_token.take()) + .await?; + + // Add up the file sizes we got back + for object in result.contents() { + total_size_bytes += object.size() as usize; + } + + // Handle pagination, and break the loop if there are no more pages + next_token = result.next_continuation_token.clone(); + if next_token.is_none() { + break; + } + } + Ok(total_size_bytes) +} +// snippet-end:[testing.rust.wrapper-func] +// snippet-end:[testing.rust.wrapper] + +// snippet-start:[testing.rust.wrapper-test-mod] +#[cfg(test)] +mod test { + // snippet-start:[testing.rust.wrapper-tests] + use super::*; + use mockall::predicate::eq; + + // snippet-start:[testing.rust.wrapper-test-single] + #[tokio::test] + async fn test_single_page() { + let mut mock = MockS3Impl::default(); + mock.expect_list_objects() + .with(eq("test-bucket"), eq("test-prefix"), eq(None)) + .return_once(|_, _, _| { + Ok(ListObjectsV2Output::builder() + .set_contents(Some(vec![ + // Mock content for ListObjectsV2 response + s3::types::Object::builder().size(5).build(), + s3::types::Object::builder().size(2).build(), + ])) + .build()) + }); + + // Run the code we want to test with it + let size = determine_prefix_file_size(mock, "test-bucket", "test-prefix") + .await + .unwrap(); + + // Verify we got the correct total size back + assert_eq!(7, size); + } + // snippet-end:[testing.rust.wrapper-test-single] + + // snippet-start:[testing.rust.wrapper-test-multiple] + #[tokio::test] + async fn test_multiple_pages() { + // Create the Mock instance with two pages of objects now + let mut mock = MockS3Impl::default(); + mock.expect_list_objects() + .with(eq("test-bucket"), eq("test-prefix"), eq(None)) + .return_once(|_, _, _| { + Ok(ListObjectsV2Output::builder() + .set_contents(Some(vec![ + // Mock content for ListObjectsV2 response + s3::types::Object::builder().size(5).build(), + s3::types::Object::builder().size(2).build(), + ])) + .set_next_continuation_token(Some("next".to_string())) + .build()) + }); + mock.expect_list_objects() + .with( + eq("test-bucket"), + eq("test-prefix"), + eq(Some("next".to_string())), + ) + .return_once(|_, _, _| { + Ok(ListObjectsV2Output::builder() + .set_contents(Some(vec![ + // Mock content for ListObjectsV2 response + s3::types::Object::builder().size(3).build(), + s3::types::Object::builder().size(9).build(), + ])) + .build()) + }); + + // Run the code we want to test with it + let size = determine_prefix_file_size(mock, "test-bucket", "test-prefix") + .await + .unwrap(); + + assert_eq!(19, size); + } + // snippet-end:[testing.rust.wrapper-test-multiple] + // snippet-end:[testing.rust.wrapper-tests] +} +// snippet-end:[testing.rust.wrapper-test-mod] diff --git a/examples/examples/textract/Cargo.toml b/examples/examples/textract/Cargo.toml index a04de9b13d78..e55211bba068 100644 --- a/examples/examples/textract/Cargo.toml +++ b/examples/examples/textract/Cargo.toml @@ -8,8 +8,8 @@ publish = false [dependencies] thiserror = "1.0.49" -aws-types= { version = "0.100.0", path = "../../../sdk/aws-types" } -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-types = { version = "0.100.0", path = "../../../sdk/aws-types" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-textract= { version = "0.37.0", path = "../../../sdk/textract" } [dependencies.tokio] diff --git a/examples/examples/tls/Cargo.toml b/examples/examples/tls/Cargo.toml index f1b641a64b73..2fe41fd0a28f 100644 --- a/examples/examples/tls/Cargo.toml +++ b/examples/examples/tls/Cargo.toml @@ -16,7 +16,7 @@ path = "src/lib.rs" [dependencies] webpki-roots = "0.22.4" rustls = "0.20.6" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-smithy-runtime= { version = "0.58.0", path = "../../../sdk/aws-smithy-runtime" } aws-sdk-kms= { version = "0.37.0", path = "../../../sdk/kms", default-features = false } diff --git a/examples/examples/tls/src/lib.rs b/examples/examples/tls/src/lib.rs index 47ab6be57c2e..d0fcc2764f6e 100644 --- a/examples/examples/tls/src/lib.rs +++ b/examples/examples/tls/src/lib.rs @@ -14,6 +14,7 @@ This example assumes you have set up environment variables for authentication. */ +use aws_config::BehaviorVersion; use aws_sdk_kms::Error; use aws_smithy_runtime::client::http::hyper_014::HyperClientBuilder; use rustls::RootCertStore; @@ -52,7 +53,10 @@ pub async fn connect_via_tls_13() -> Result<(), Error> { // See https://github.com/awslabs/smithy-rs/discussions/3022 for the HyperClientBuilder let http_client = HyperClientBuilder::new().build(rustls_connector); - let shared_conf = aws_config::from_env().http_client(http_client).load().await; + let shared_conf = aws_config::defaults(BehaviorVersion::latest()) + .http_client(http_client) + .load() + .await; let kms_client = aws_sdk_kms::Client::new(&shared_conf); let response = kms_client.list_keys().send().await?; diff --git a/examples/examples/transcribestreaming/Cargo.toml b/examples/examples/transcribestreaming/Cargo.toml index 66b1b94fb78c..7c75ba0ce1e4 100644 --- a/examples/examples/transcribestreaming/Cargo.toml +++ b/examples/examples/transcribestreaming/Cargo.toml @@ -10,7 +10,7 @@ publish = false async-stream = "0.3" bytes = "1" hound = "3.4" -aws-config= { version = "0.100.0", path = "../../../sdk/aws-config" } +aws-config= { version = "0.100.0", path = "../../../sdk/aws-config", features = ["behavior-version-latest"] } aws-sdk-transcribestreaming= { version = "0.37.0", path = "../../../sdk/transcribestreaming" } [dependencies.clap] diff --git a/examples/test-utils/src/macros.rs b/examples/test-utils/src/macros.rs index a4fa0dfd7147..a9d857eb0963 100644 --- a/examples/test-utils/src/macros.rs +++ b/examples/test-utils/src/macros.rs @@ -90,6 +90,7 @@ macro_rules! client_config { ) => { /// TODO: remove after https://github.com/awslabs/smithy-rs/pull/2145 $sdk_crate::Config::builder() + .behavior_version($sdk_crate::config::BehaviorVersion::latest()) .credentials_provider($sdk_crate::config::Credentials::new( "ATESTCLIENT", "atestsecretkey", diff --git a/examples/webassembly/src/lib.rs b/examples/webassembly/src/lib.rs index 851f3f6764a4..0b84b9eabffc 100644 --- a/examples/webassembly/src/lib.rs +++ b/examples/webassembly/src/lib.rs @@ -9,8 +9,8 @@ use aws_sdk_lambda::config::{AsyncSleep, Region, Sleep}; use aws_sdk_lambda::primitives::SdkBody; use aws_sdk_lambda::{meta::PKG_VERSION, Client}; use aws_smithy_async::time::TimeSource; -use aws_smithy_runtime_api::client::http::request::Request; use aws_smithy_runtime_api::client::result::ConnectorError; +use aws_smithy_runtime_api::http::{Request, Response}; use aws_smithy_runtime_api::{ client::{ http::{ @@ -23,6 +23,7 @@ use aws_smithy_runtime_api::{ shared::IntoShared, }; +use aws_config::BehaviorVersion; use serde::Deserialize; use std::time::SystemTime; use wasm_bindgen::{prelude::*, JsCast}; @@ -71,7 +72,7 @@ pub async fn main(region: String, verbose: bool) -> Result { let credentials = credentials_provider.provide_credentials().await.unwrap(); let access_key = credentials.access_key_id(); - let shared_config = aws_config::from_env() + let shared_config = aws_config::defaults(BehaviorVersion::latest()) .sleep_impl(BrowserSleep) .region(Region::new(region)) .time_source(BrowserNow) @@ -267,7 +268,7 @@ impl HttpConnector for Adapter { HttpConnectorFuture::new(async move { let response = rx.await.map_err(|e| ConnectorError::user(Box::new(e)))?; log!("response received"); - Ok(response) + Ok(Response::try_from(response).unwrap()) }) } } diff --git a/versions.toml b/versions.toml index 92e2f3dec1fa..b33d3a0f47b8 100644 --- a/versions.toml +++ b/versions.toml @@ -1,5 +1,5 @@ smithy_rs_revision = 'f63980cda330c2d76384d465692110f04d517092' -aws_doc_sdk_examples_revision = '26f1a3d11de9c6488e9b1db175ffc92c370c5c27' +aws_doc_sdk_examples_revision = '9f08f276537a38dc094727f1ad0b0ceacbb1dc7b' [manual_interventions] crates_to_remove = []