-
| Hi, Is there something similar within the aws-sdk-rust that could be used to injecting faults into DynamoDB requests? | 
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
| While there isn't any built-in support for failure/latency injection, there are two approaches you can take for this: 
 I recently built a custom connector to diagnose a throttling failure for STS, so I've adapted that to DynamoDB below as an example of approach 1. Cargo.toml dependencies [dependencies]
aws-config = "0.12.0"
aws-sdk-dynamodb = "0.12.0"
aws-smithy-client = "0.42.0"
aws-smithy-http = "0.42.0"
bytes = "1"
http = "0.2.7"
rand = "0.8.5"
tokio = { version = "1", features = ["full"] }
tower = "0.4"Custom failure injecting connector use aws_sdk_dynamodb as dynamo;
use aws_smithy_client::erase::DynConnector;
use aws_smithy_client::hyper_ext;
use aws_smithy_http::body::SdkBody;
use aws_smithy_http::result::ConnectorError;
use bytes::Bytes;
use rand::{thread_rng, Rng};
use std::future::Future;
use std::pin::Pin;
use std::task::Poll;
use std::time::Duration;
/// Custom connector that injects failures
#[derive(Clone, Debug)]
struct FakeFailureConnector {
    inner: DynConnector,
}
impl FakeFailureConnector {
    fn new() -> FakeFailureConnector {
        FakeFailureConnector {
            // Construct a default HTTPS connector to delegate to
            inner: DynConnector::new(
                hyper_ext::Adapter::builder().build(aws_smithy_client::conns::https()),
            ),
        }
    }
}
// The custom connector must implement Service<Request<SdkBody>> in order to work with the SDK
impl tower::Service<http::Request<SdkBody>> for FakeFailureConnector {
    type Response = http::Response<SdkBody>;
    type Error = ConnectorError;
    type Future =
        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
    fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
        self.inner.poll_ready(cx)
    }
    fn call(&mut self, req: http::Request<SdkBody>) -> Self::Future {
        // Inject a failure 30% of the time
        let failure_chance = 0.3;
        let inject_failure = thread_rng().gen_bool(failure_chance);
        // Note: The SDK will retry these failures, so if this is working, there should be more
        // of these outputs than calls made.
        println!(
            "FakeFailureConnector called; decision: {:?}",
            inject_failure
        );
        // Either inject a failure, or delegate to the underlying HTTPS connector to make a real call
        let result: Self::Future = if inject_failure {
            Box::pin(async {
                Ok(http::Response::builder()
                    .status(500)
                    .body(SdkBody::from(Bytes::from_static(b"")))
                    .unwrap())
            })
        } else {
            let inner_call = self.inner.call(req);
            Box::pin(async { Ok(inner_call.await?) })
        };
        result
    }
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = aws_config::load_from_env().await;
    // When constructing the client, use `from_conf_conn` to override the connector with our `FakeFailureConnector`
    let client = dynamo::Client::from_conf_conn((&config).into(), FakeFailureConnector::new());
    // To illustrate it working, call DynamoDB a few times
    for _ in 1..=5 {
        match client.list_tables().send().await {
            Ok(_) => println!("call succeeded!"),
            Err(err) => println!("failed: {:#?}", err),
        }
        tokio::time::sleep(Duration::from_millis(50)).await;
    }
    Ok(())
} | 
Beta Was this translation helpful? Give feedback.
-
| Hello! Reopening this discussion to make it searchable. | 
Beta Was this translation helpful? Give feedback.
While there isn't any built-in support for failure/latency injection, there are two approaches you can take for this:
hyper/rustlsHTTPS connector with your own delegating connector that injects the failures, orI recently built a custom connector to diagnose a throttling failure for STS, so I've adapted that to DynamoDB below as an example of approach 1.
Cargo.toml dependencies