From cab7de3fafb420d67783e724a6002103e1ea37d9 Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Fri, 19 Nov 2021 15:41:25 -0500 Subject: [PATCH] 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: John DiSanti * fix changelog * SDK changelog docs Co-authored-by: John DiSanti --- CHANGELOG.md | 7 +- aws/SDK_CHANGELOG.md | 10 ++ rust-runtime/aws-smithy-client/src/builder.rs | 2 +- .../src/{hyper_impls.rs => hyper_ext.rs} | 97 ++++++++++++++----- rust-runtime/aws-smithy-client/src/lib.rs | 15 +-- .../aws-smithy-client/src/static_tests.rs | 2 +- 6 files changed, 96 insertions(+), 37 deletions(-) rename rust-runtime/aws-smithy-client/src/{hyper_impls.rs => hyper_ext.rs} (82%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d1b22926..67b4a4cba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,11 @@ 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) =================================== diff --git a/aws/SDK_CHANGELOG.md b/aws/SDK_CHANGELOG.md index 10b8afeb0..cac190afb 100644 --- a/aws/SDK_CHANGELOG.md +++ b/aws/SDK_CHANGELOG.md @@ -1,6 +1,16 @@ 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 diff --git a/rust-runtime/aws-smithy-client/src/builder.rs b/rust-runtime/aws-smithy-client/src/builder.rs index 8ab2ebfca..dbb79f116 100644 --- a/rust-runtime/aws-smithy-client/src/builder.rs +++ b/rust-runtime/aws-smithy-client/src/builder.rs @@ -52,7 +52,7 @@ impl 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(self, connector: C) -> Builder { Builder { connector, diff --git a/rust-runtime/aws-smithy-client/src/hyper_impls.rs b/rust-runtime/aws-smithy-client/src/hyper_ext.rs similarity index 82% rename from rust-runtime/aws-smithy-client/src/hyper_impls.rs rename to rust-runtime/aws-smithy-client/src/hyper_ext.rs index bf5e4ab1b..2b0699687 100644 --- a/rust-runtime/aws-smithy-client/src/hyper_impls.rs +++ b/rust-runtime/aws-smithy-client/src/hyper_ext.rs @@ -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::::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::::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(HttpReadTimeout, SdkBody>>); +pub struct Adapter(HttpReadTimeout, SdkBody>>); -impl Service> for HyperAdapter +impl Service> for Adapter where C: Clone + Send + Sync + 'static, C: tower::Service, @@ -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::::new(DynConnector::new(hyper_connector)); +/// ``` pub struct Builder { timeout: timeout::Settings, sleep: Option>, @@ -130,7 +184,7 @@ pub struct Builder { impl Builder { /// Create a HyperAdapter from this builder and a given connector - pub fn build(self, connector: C) -> HyperAdapter + pub fn build(self, connector: C) -> Adapter where C: Clone + Send + Sync + 'static, C: tower::Service, @@ -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 ClientBuilder<(), M, R> { /// Connect to the service over HTTPS using Rustls. - pub fn rustls(self) -> ClientBuilder, M, R> { - self.connector(HyperAdapter::builder().build(crate::conns::https())) + pub fn rustls(self) -> ClientBuilder, 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, M, R> { + pub fn https(self) -> ClientBuilder, M, R> { self.rustls() } } @@ -243,9 +297,8 @@ impl ClientBuilder<(), M, R> { /// Connect to the service over HTTPS using the native TLS library on your platform. pub fn native_tls( self, - ) -> ClientBuilder>, M, R> - { - self.connector(HyperAdapter::builder().build(crate::conns::native_tls())) + ) -> ClientBuilder>, 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( diff --git a/rust-runtime/aws-smithy-client/src/lib.rs b/rust-runtime/aws-smithy-client/src/lib.rs index 13aca3af3..e77c98f65 100644 --- a/rust-runtime/aws-smithy-client/src/lib.rs +++ b/rust-runtime/aws-smithy-client/src/lib.rs @@ -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; #[cfg(feature = "rustls")] - pub type Rustls = crate::hyper_impls::HyperAdapter< - hyper_rustls::HttpsConnector, - >; + pub type Rustls = + crate::hyper_ext::Adapter>; } use aws_smithy_http::body::SdkBody; diff --git a/rust-runtime/aws-smithy-client/src/static_tests.rs b/rust-runtime/aws-smithy-client/src/static_tests.rs index d46a81706..8fc03664b 100644 --- a/rust-runtime/aws-smithy-client/src/static_tests.rs +++ b/rust-runtime/aws-smithy-client/src/static_tests.rs @@ -56,7 +56,7 @@ fn sanity_retry() { // Statically check that a hyper client can actually be used to build a Client. #[allow(dead_code)] #[cfg(all(test, feature = "hyper"))] -fn sanity_hyper(hc: crate::hyper_impls::HyperAdapter) { +fn sanity_hyper(hc: crate::hyper_ext::Adapter) { Builder::new() .middleware(tower::layer::util::Identity::new()) .connector(hc) -- GitLab