Unverified Commit cab7de3f authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Add / fix smithy-client docs (#855)



* Add / fix smithy-client docs

* Rework hyper impls to be a regular public module instead of pub use

* clarify comments, fix changelog

* cleanup code in docs

* Add doc linking

* Update rust-runtime/aws-smithy-client/src/hyper_ext.rs

Co-authored-by: default avatarJohn DiSanti <jdisanti@amazon.com>

* fix changelog

* SDK changelog docs

Co-authored-by: default avatarJohn DiSanti <jdisanti@amazon.com>
parent 1df4c126
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
vNext (Month Day, Year)
=======================

**TODO Next Release:**
- Update README & aws-sdk-rust CI for MSRV upgrade to 1.54
**New this release**
- Improve docs on `aws-smithy-client` (smithy-rs#855)

**Breaking Changes**
- (aws-smithy-client): Extraneous `pub use SdkSuccess` removed from `aws_smithy_client::hyper_ext`. (smithy-rs#855)

v0.29.0-alpha (November 11th, 2021)
===================================
+10 −0
Original line number Diff line number Diff line
vNext (Month Day, Year)
=======================

**New this release**
- Improve docs on `aws-smithy-client` (smithy-rs#855)

**Breaking Changes**
- (aws-smithy-client): Extraneous `pub use SdkSuccess` removed from `aws_smithy_client::hyper_ext`. (smithy-rs#855)


v0.0.26-alpha (TBD)
=======================

**TODO Upon release**
- Update README & aws-sdk-rust CI for MSRV upgrade to 1.54

+1 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ impl<M, R> Builder<(), M, R> {
    /// be able to use a custom connector instead, such as to mock the network for tests.
    ///
    /// If you just want to specify a function from request to response instead, use
    /// [`Builder::map_connector`].
    /// [`Builder::connector_fn`].
    pub fn connector<C>(self, connector: C) -> Builder<C, M, R> {
        Builder {
            connector,
+75 −22
Original line number Diff line number Diff line
@@ -2,6 +2,41 @@
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */
//! Implementation of [`SmithyConnector`](crate::bounds::SmithyConnector) for Hyper
//!
//! The module provides [`Adapter`] which enables using a [`hyper::Client`] as the connector for a Smithy
//! [`Client`](crate::Client).
//!
//! # Examples
//! ### Construct a Smithy Client with Hyper and Rustls
//! In the basic case, customers should not need to use this module. A default implementation of Hyper
//! with `rustls` will be constructed during client creation. However, if you are creating a Smithy
//! [`Client`](crate::Client), directly, use the `https()` method to match the default behavior:
//! ```rust
//! use aws_smithy_client::Client;
//! use aws_smithy_client::erase::DynConnector;
//!
//! // TODO: replace this with your middleware
//! type MyMiddleware = tower::layer::util::Identity;
//! let client = Client::<DynConnector, MyMiddleware>::https();
//! ```
//!
//! ### Create a Hyper client with a custom timeout
//! One common use case for constructing a connector directly is setting `CONNECT` timeouts. Since the
//! internal connector is cheap to clone, you can also use this to share a connector between multiple services.
//! ```rust
//! use std::time::Duration;
//! use aws_smithy_client::{Client, conns, hyper_ext};
//! use aws_smithy_client::erase::DynConnector;
//! use aws_smithy_client::timeout::Settings;
//!
//! let timeout = Settings::new().with_connect_timeout(Duration::from_secs(1));
//! let connector = hyper_ext::Adapter::builder().timeout(&timeout).build(conns::https());
//! // TODO: replace this with your middleware
//! type MyMiddleware = tower::layer::util::Identity;
//! // once you have a connector, use it to construct a Smithy client:
//! let client = Client::<DynConnector, MyMiddleware>::new(DynConnector::new(connector));
//! ```

use std::sync::Arc;

@@ -14,22 +49,22 @@ use tower::{BoxError, Service};
use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep};
use aws_smithy_http::body::SdkBody;
use aws_smithy_http::result::ConnectorError;
pub use aws_smithy_http::result::{SdkError, SdkSuccess};
use std::error::Error;

use crate::hyper_impls::timeout_middleware::{ConnectTimeout, HttpReadTimeout, TimeoutError};
use crate::hyper_ext::timeout_middleware::{ConnectTimeout, HttpReadTimeout, TimeoutError};
use crate::{timeout, Builder as ClientBuilder};
use aws_smithy_async::future::timeout::TimedOutError;
use aws_smithy_types::retry::ErrorKind;

/// Adapter from a [`hyper::Client`] to a connector usable by a [`Client`](crate::Client).
/// Adapter from a [`hyper::Client`](hyper::Client) to a connector usable by a Smithy [`Client`](crate::Client).
///
/// This adapter also enables TCP connect and HTTP read timeouts via [`HyperAdapter::builder`]
/// This adapter also enables TCP `CONNECT` and HTTP `READ` timeouts via [`Adapter::builder`]. For examples
/// see [the module documentation](crate::hyper_ext).
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct HyperAdapter<C>(HttpReadTimeout<hyper::Client<ConnectTimeout<C>, SdkBody>>);
pub struct Adapter<C>(HttpReadTimeout<hyper::Client<ConnectTimeout<C>, SdkBody>>);

impl<C> Service<http::Request<SdkBody>> for HyperAdapter<C>
impl<C> Service<http::Request<SdkBody>> for Adapter<C>
where
    C: Clone + Send + Sync + 'static,
    C: tower::Service<Uri>,
@@ -58,10 +93,10 @@ where
    }
}

impl HyperAdapter<()> {
impl Adapter<()> {
    /// Builder for a Hyper Adapter
    ///
    /// Generally, end users should not need to construct a HyperAdapter manually: a hyper adapter
    /// Generally, end users should not need to construct an [`Adapter`] manually: a hyper adapter
    /// will be constructed automatically during client creation.
    pub fn builder() -> Builder {
        Builder::default()
@@ -121,7 +156,26 @@ fn find_source<'a, E: Error + 'static>(err: &'a (dyn Error + 'static)) -> Option
}

#[derive(Default, Debug)]
/// Builder for [`HyperAdapter`]
/// Builder for [`hyper_ext::Adapter`](Adapter)
///
/// Unlike a Smithy client, the [`tower::Service`] inside a [`hyper_ext::Adapter`](Adapter) is actually a service that
/// accepts a `Uri` and returns a TCP stream. Two default implementations of this are provided, one
/// that encrypts the stream with `rustls`, the other that encrypts the stream with `native-tls`.
///
/// # Examples
/// Construct a HyperAdapter with the default HTTP implementation (rustls). This can be useful when you want to share a Hyper connector
/// between multiple Smithy clients.
///
/// ```rust
/// use tower::layer::util::Identity;
/// use aws_smithy_client::{conns, hyper_ext};
/// use aws_smithy_client::erase::DynConnector;
///
/// let hyper_connector = hyper_ext::Adapter::builder().build(conns::https());
/// // this client can then be used when constructing a Smithy Client
/// // TODO: replace `Identity` with your middleware implementation
/// let client = aws_smithy_client::Client::<DynConnector, Identity>::new(DynConnector::new(hyper_connector));
/// ```
pub struct Builder {
    timeout: timeout::Settings,
    sleep: Option<Arc<dyn AsyncSleep>>,
@@ -130,7 +184,7 @@ pub struct Builder {

impl Builder {
    /// Create a HyperAdapter from this builder and a given connector
    pub fn build<C>(self, connector: C) -> HyperAdapter<C>
    pub fn build<C>(self, connector: C) -> Adapter<C>
    where
        C: Clone + Send + Sync + 'static,
        C: tower::Service<Uri>,
@@ -161,7 +215,7 @@ impl Builder {
            ),
            None => HttpReadTimeout::no_timeout(base),
        };
        HyperAdapter(http_timeout)
        Adapter(http_timeout)
    }

    /// Set the async sleep implementation used for timeouts
@@ -226,15 +280,15 @@ where
#[cfg(feature = "rustls")]
impl<M, R> ClientBuilder<(), M, R> {
    /// Connect to the service over HTTPS using Rustls.
    pub fn rustls(self) -> ClientBuilder<HyperAdapter<crate::conns::Https>, M, R> {
        self.connector(HyperAdapter::builder().build(crate::conns::https()))
    pub fn rustls(self) -> ClientBuilder<Adapter<crate::conns::Https>, M, R> {
        self.connector(Adapter::builder().build(crate::conns::https()))
    }

    /// Connect to the service over HTTPS using Rustls.
    ///
    /// This is exactly equivalent to [`Builder::rustls`](ClientBuilder::rustls). If you instead wish to use `native_tls`,
    /// use `Builder::native_tls`.
    pub fn https(self) -> ClientBuilder<HyperAdapter<crate::conns::Https>, M, R> {
    pub fn https(self) -> ClientBuilder<Adapter<crate::conns::Https>, M, R> {
        self.rustls()
    }
}
@@ -243,9 +297,8 @@ impl<M, R> ClientBuilder<(), M, R> {
    /// Connect to the service over HTTPS using the native TLS library on your platform.
    pub fn native_tls(
        self,
    ) -> ClientBuilder<HyperAdapter<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>, M, R>
    {
        self.connector(HyperAdapter::builder().build(crate::conns::native_tls()))
    ) -> ClientBuilder<Adapter<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>, M, R> {
        self.connector(Adapter::builder().build(crate::conns::native_tls()))
    }
}

@@ -454,7 +507,7 @@ mod timeout_middleware {

    #[cfg(test)]
    mod test {
        use crate::hyper_impls::HyperAdapter;
        use crate::hyper_ext::Adapter;
        use crate::never::{NeverConnected, NeverReplies};
        use crate::timeout;
        use aws_smithy_async::rt::sleep::TokioSleep;
@@ -490,7 +543,7 @@ mod timeout_middleware {
        async fn connect_timeout_works() {
            let inner = NeverConnected::new();
            let timeout = timeout::Settings::new().with_connect_timeout(Duration::from_secs(1));
            let mut hyper = HyperAdapter::builder()
            let mut hyper = Adapter::builder()
                .timeout(&timeout)
                .sleep_impl(TokioSleep::new())
                .build(inner);
@@ -519,7 +572,7 @@ mod timeout_middleware {
            let timeout = timeout::Settings::new()
                .with_connect_timeout(Duration::from_secs(1))
                .with_read_timeout(Duration::from_secs(2));
            let mut hyper = HyperAdapter::builder()
            let mut hyper = Adapter::builder()
                .timeout(&timeout)
                .sleep_impl(TokioSleep::new())
                .build(inner);
@@ -542,7 +595,7 @@ mod timeout_middleware {

#[cfg(test)]
mod test {
    use crate::hyper_impls::HyperAdapter;
    use crate::hyper_ext::Adapter;
    use http::Uri;
    use hyper::client::connect::{Connected, Connection};

@@ -559,7 +612,7 @@ mod test {
        let connector = TestConnection {
            inner: HangupStream,
        };
        let mut adapter = HyperAdapter::builder().build(connector);
        let mut adapter = Adapter::builder().build(connector);
        use tower::Service;
        let err = adapter
            .call(
+4 −11
Original line number Diff line number Diff line
@@ -25,14 +25,7 @@ pub mod dvr;
pub mod test_connection;

#[cfg(feature = "hyper")]
mod hyper_impls;

/// Re-export HyperAdapter
#[cfg(feature = "hyper")]
pub mod hyper_ext {
    pub use crate::hyper_impls::Builder;
    pub use crate::hyper_impls::HyperAdapter as Adapter;
}
pub mod hyper_ext;

// The types in this module are only used to write the bounds in [`Client::check`]. Customers will
// not need them. But the module and its types must be public so that we can call `check` from
@@ -40,6 +33,7 @@ pub mod hyper_ext {
#[doc(hidden)]
pub mod static_tests;

#[cfg(feature = "hyper")]
pub mod never;
pub mod timeout;

@@ -74,9 +68,8 @@ pub mod conns {
    pub type NativeTls = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;

    #[cfg(feature = "rustls")]
    pub type Rustls = crate::hyper_impls::HyperAdapter<
        hyper_rustls::HttpsConnector<hyper::client::HttpConnector>,
    >;
    pub type Rustls =
        crate::hyper_ext::Adapter<hyper_rustls::HttpsConnector<hyper::client::HttpConnector>>;
}

use aws_smithy_http::body::SdkBody;
Loading