Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Rust examples after timeout breaking changes #3739

Merged
merged 3 commits into from
Oct 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async fn delete_group(client: &Client, name: &str, force: bool) -> Result<(), Er
client
.delete_auto_scaling_group()
.auto_scaling_group_name(name)
.set_force_delete(force.then_some(true))
.set_force_delete(if force { Some(true) } else { None })
.send()
.await?;

Expand Down
44 changes: 17 additions & 27 deletions rust_dev_preview/kms/src/bin/kms-helloworld.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,29 @@
* SPDX-License-Identifier: Apache-2.0.
*/

use aws_sdk_kms::middleware::DefaultMiddleware;
use aws_sdk_kms::operation::GenerateRandom;
use aws_sdk_kms::{Config, Region};
use aws_smithy_client::erase::DynConnector;
use aws_sdk_kms::{Client, Region};

// snippet-start:[kms.rust.kms-helloworld]
/// Creates a random byte string that is cryptographically secure in __us-east-1__.
#[tokio::main]
async fn main() {
let config = Config::builder()
async fn main() -> Result<(), aws_sdk_kms::Error> {
let config = aws_config::from_env()
// region can also be loaded from AWS_DEFAULT_REGION, just remove this line.
.region(Region::new("us-east-1"))
// creds loaded from environment variables, or they can be hard coded.
// Other credential providers not currently supported
.build();
// NB: This example uses the "low level internal API" for demonstration purposes
// This is sometimes necessary to get precise control over behavior, but in most cases
// using `kms::Client` is recommended.
let client = aws_smithy_client::Client::<DynConnector, DefaultMiddleware>::dyn_https();
.load()
.await;
let client = Client::new(&config);

let data = client
.call(
GenerateRandom::builder()
.number_of_bytes(64)
.build()
.expect("valid operation")
.make_operation(&config)
.await
.expect("valid operation"),
)
.await
.expect("failed to generate random data");
println!("{:?}", data);
assert_eq!(data.plaintext.expect("should have data").as_ref().len(), 64);
let response = client.generate_random().number_of_bytes(64).send().await?;
println!("{:?}", response);
assert_eq!(
64,
response
.plaintext()
.expect("should have data")
.as_ref()
.len()
);
Ok(())
}
// snippet-end:[kms.rust.kms-helloworld]
3 changes: 2 additions & 1 deletion rust_dev_preview/sdk-config/src/bin/disable_retries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
*/

use aws_config::meta::region::RegionProviderChain;
use aws_sdk_s3::{Client, Error, Region, RetryConfig, PKG_VERSION};
use aws_sdk_s3::config::retry::RetryConfig;
use aws_sdk_s3::{Client, Error, Region, PKG_VERSION};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
Expand Down
3 changes: 2 additions & 1 deletion rust_dev_preview/sdk-config/src/bin/set_retries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
*/

use aws_config::meta::region::RegionProviderChain;
use aws_sdk_s3::{config, Client, Error, Region, RetryConfig, PKG_VERSION};
use aws_sdk_s3::config::retry::RetryConfig;
use aws_sdk_s3::{config, Client, Error, Region, PKG_VERSION};
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
Expand Down
105 changes: 31 additions & 74 deletions rust_dev_preview/sdk-config/src/bin/timeouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,9 @@
* SPDX-License-Identifier: Apache-2.0.
*/

use aws_smithy_client::{conns, erase::DynConnector, hyper_ext};
// Note: `TriState` is used to distinguish between configurations that are
// intentionally set, disabled, or unset.
//
// If you're familiar with languages like SQL or JavaScript, it might be
// helpful to think of the `TriState` definitions as follows:
//
// - `TriState::Set(value)` is a set value
// - `TriState::Disabled` is similar to `null`
// - `TriState::Unset` is similar to `undefined`
//
// With these distinctions, it's less complicated to merge configurations
// from multiple sources. Set or disabled values are kept, while unset values are overwritten.
use aws_smithy_types::{timeout, tristate::TriState};
use aws_config::timeout::TimeoutConfig;
use std::time::Duration;

/// The SDK divides timeouts into two groups:
///
/// - Timeouts that occur at the client level _(outside of a `Connector`)_, hereafter referred to
/// as "first group" timeouts
/// - Timeouts that occur at the connector level _(inside a `Connector`)_, hereafter referred to
/// as "second group" timeouts
///
/// In the future, all timeouts will be set in the same way. In the present, these two groups of
/// timeouts must be set separately. This app provides an example of how to set both groups of
/// timeouts.
///
/// **TLS negotiation timeouts will eventually be included with the second group but are
/// not yet supported**
///
/// The timeouts in this example are set to one second which may or may not be fast enough to
/// trigger them based on your connection speeds. If you want to ensure a timeout gets triggered
/// so you can see what the resulting error looks like, change the durations from
Expand All @@ -44,55 +17,39 @@ use std::time::Duration;
async fn main() -> Result<(), aws_sdk_s3::Error> {
tracing_subscriber::fmt::init();

// Here we create an object that holds timeout-related configuration. We'll have to pass this
// config into two places. This is because different timeouts are handled at different
// "levels" of the AWS SDK Client networking stack. We'll note which timeouts are getting
// set each time we pass in this configuration.
let timeout_config = timeout::Config::new()
.with_api_timeouts(
timeout::Api::new()
// This timeout acts at the "Request to a service" level. When the SDK makes a request to a
// service, that "request" can contain several HTTP requests. This way, you can retry
// failures that are likely spurious, or refresh credentials.
.with_call_timeout(TriState::Set(Duration::from_secs(2)))
// This timeout acts at the "HTTP request" level and sets a separate timeout for each
// HTTP request made as part of a "service request."
.with_call_attempt_timeout(TriState::Set(Duration::from_secs(2))),
)
.with_http_timeouts(
timeout::Http::new()
// A limit on the amount of time an application takes to attempt to read the first byte over
// an established, open connection after a write request.
// Also known as the "time to first byte" timeout.
.with_read_timeout(TriState::Set(Duration::from_secs(2)))
// A time limit for completing the connect-handshake. The time starts when
// making an initial connect attempt on a socket.
.with_connect_timeout(TriState::Set(Duration::from_secs(2))),
);

// You can define timeouts in your environment or your AWS profile, but in the following
// example, we overrule any previously set timeouts.
// NOTE: The two API call timeouts get set here.
let shared_config = aws_config::from_env()
// Here we create an object that holds timeout-related configuration.
let timeout_config = TimeoutConfig::builder()
// This timeout acts at the "Request to a service" level. When the SDK makes a request to a
// service, that "request" can contain several HTTP requests. This way, you can retry
// failures that are likely spurious, or refresh credentials.
.operation_timeout(Duration::from_secs(2))
// This timeout acts at the "HTTP request" level and sets a separate timeout for each
// HTTP request made as part of a "service request."
.operation_attempt_timeout(Duration::from_secs(2))
// A limit on the amount of time an application takes to attempt to read the first byte over
// an established, open connection after a write request.
// Also known as the "time to first byte" timeout.
.read_timeout(Duration::from_secs(2))
// A time limit for completing the connect-handshake. The time starts when
// making an initial connect attempt on a socket.
.connect_timeout(Duration::from_secs(2))
.build();

let config = aws_config::from_env()
.timeout_config(timeout_config.clone())
.load()
.await;

// These timeouts must also be passed to create the `Connector` that will handle our HTTP requests.
// If a timeout needs to be changed after this, we'd have to create a new `Connector`.
// NOTE: The read and connect timeouts get set here.
let conn = DynConnector::new(
hyper_ext::Adapter::builder()
.timeout(&timeout_config.http)
.build(conns::https()),
);
let s3_config = aws_sdk_s3::Config::from(&shared_config);
let client = aws_sdk_s3::Client::from_conf_conn(s3_config, conn);

let resp = client.list_buckets().send().await?;

for bucket in resp.buckets().unwrap_or_default() {
println!("bucket: {:?}", bucket.name().unwrap_or_default())
let client = aws_sdk_s3::Client::new(&config);

match client.list_buckets().send().await {
Ok(response) => {
for bucket in response.buckets().unwrap_or_default() {
println!("bucket: {:?}", bucket.name().unwrap_or_default())
}
}
Err(err) => {
println!("{err}");
}
}

Ok(())
Expand Down