Skip to content

Commit d912326

Browse files
authored
Set up a default connector for generic clients in the orchestrator implementation (#2693)
## Motivation and Context This PR makes generic clients default to the built-in rustls HTTPS connector when no override is provided, but only for the new orchestrator implementation. ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._
1 parent c6e5379 commit d912326

File tree

5 files changed

+83
-37
lines changed

5 files changed

+83
-37
lines changed

aws/rust-runtime/aws-config/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repository = "https://github.com/awslabs/smithy-rs"
1010

1111
[features]
1212
client-hyper = ["aws-smithy-client/client-hyper"]
13-
rustls = ["aws-smithy-client/rustls"]
13+
rustls = ["aws-smithy-client/rustls", "client-hyper"]
1414
native-tls = []
1515
allow-compilation = [] # our tests use `cargo test --all-features` and native-tls breaks CI
1616
rt-tokio = ["aws-smithy-async/rt-tokio", "tokio/rt"]

aws/rust-runtime/aws-config/external-types.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ allowed_external_types = [
1010
"aws_sdk_sts::types::_policy_descriptor_type::PolicyDescriptorType",
1111
"aws_smithy_async::rt::sleep::AsyncSleep",
1212
"aws_smithy_client::bounds::SmithyConnector",
13+
"aws_smithy_client::conns::default_connector::default_connector",
1314
"aws_smithy_client::erase::DynConnector",
1415
"aws_smithy_client::erase::boxclone::BoxCloneService",
1516
"aws_smithy_client::http_connector::ConnectorSettings",

aws/rust-runtime/aws-config/src/connector.rs

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,25 @@
55

66
//! Functionality related to creating new HTTP Connectors
77
8-
use aws_smithy_async::rt::sleep::AsyncSleep;
98
use aws_smithy_client::erase::DynConnector;
10-
use aws_smithy_client::http_connector::ConnectorSettings;
11-
use std::sync::Arc;
129

1310
// unused when all crate features are disabled
1411
/// Unwrap an [`Option<DynConnector>`](aws_smithy_client::erase::DynConnector), and panic with a helpful error message if it's `None`
1512
pub(crate) fn expect_connector(connector: Option<DynConnector>) -> DynConnector {
1613
connector.expect("No HTTP connector was available. Enable the `rustls` crate feature or set a connector to fix this.")
1714
}
1815

16+
#[cfg(feature = "client-hyper")]
17+
pub use aws_smithy_client::conns::default_connector;
18+
1919
#[cfg(all(feature = "native-tls", not(feature = "allow-compilation")))]
2020
compile_error!("Feature native-tls has been removed. For upgrade instructions, see: https://awslabs.github.io/smithy-rs/design/transport/connector.html");
2121

22-
#[cfg(feature = "rustls")]
23-
fn base(
24-
settings: &ConnectorSettings,
25-
sleep: Option<Arc<dyn AsyncSleep>>,
26-
) -> aws_smithy_client::hyper_ext::Builder {
27-
let mut hyper =
28-
aws_smithy_client::hyper_ext::Adapter::builder().connector_settings(settings.clone());
29-
if let Some(sleep) = sleep {
30-
hyper = hyper.sleep_impl(sleep);
31-
}
32-
hyper
33-
}
34-
35-
/// Given `ConnectorSettings` and an `AsyncSleep`, create a `DynConnector` from defaults depending on what cargo features are activated.
36-
#[cfg(feature = "rustls")]
37-
pub fn default_connector(
38-
settings: &ConnectorSettings,
39-
sleep: Option<Arc<dyn AsyncSleep>>,
40-
) -> Option<DynConnector> {
41-
tracing::trace!(settings = ?settings, sleep = ?sleep, "creating a new connector");
42-
let hyper = base(settings, sleep).build(aws_smithy_client::conns::https());
43-
Some(DynConnector::new(hyper))
44-
}
45-
4622
/// Given `ConnectorSettings` and an `AsyncSleep`, create a `DynConnector` from defaults depending on what cargo features are activated.
47-
#[cfg(not(feature = "rustls"))]
23+
#[cfg(not(feature = "client-hyper"))]
4824
pub fn default_connector(
49-
_settings: &ConnectorSettings,
50-
_sleep: Option<Arc<dyn AsyncSleep>>,
25+
_settings: &aws_smithy_client::http_connector::ConnectorSettings,
26+
_sleep: Option<std::sync::Arc<dyn aws_smithy_async::rt::sleep::AsyncSleep>>,
5127
) -> Option<DynConnector> {
5228
None
5329
}

codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/ServiceRuntimePluginGenerator.kt

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class ServiceRuntimePluginGenerator(
6363
private val endpointTypesGenerator = EndpointTypesGenerator.fromContext(codegenContext)
6464
private val codegenScope = codegenContext.runtimeConfig.let { rc ->
6565
val http = RuntimeType.smithyHttp(rc)
66+
val client = RuntimeType.smithyClient(rc)
6667
val runtime = RuntimeType.smithyRuntime(rc)
6768
val runtimeApi = RuntimeType.smithyRuntimeApi(rc)
6869
arrayOf(
@@ -77,6 +78,7 @@ class ServiceRuntimePluginGenerator(
7778
"DefaultEndpointResolver" to runtime.resolve("client::orchestrator::endpoints::DefaultEndpointResolver"),
7879
"DynConnectorAdapter" to runtime.resolve("client::connections::adapter::DynConnectorAdapter"),
7980
"HttpAuthSchemes" to runtimeApi.resolve("client::auth::HttpAuthSchemes"),
81+
"HttpConnector" to client.resolve("http_connector::HttpConnector"),
8082
"IdentityResolvers" to runtimeApi.resolve("client::identity::IdentityResolvers"),
8183
"InterceptorRegistrar" to runtimeApi.resolve("client::interceptors::InterceptorRegistrar"),
8284
"NeverRetryStrategy" to runtime.resolve("client::retries::strategy::NeverRetryStrategy"),
@@ -85,6 +87,8 @@ class ServiceRuntimePluginGenerator(
8587
"RuntimePlugin" to runtimeApi.resolve("client::runtime_plugin::RuntimePlugin"),
8688
"SharedEndpointResolver" to http.resolve("endpoint::SharedEndpointResolver"),
8789
"StaticAuthOptionResolver" to runtimeApi.resolve("client::auth::option_resolver::StaticAuthOptionResolver"),
90+
"default_connector" to client.resolve("conns::default_connector"),
91+
"require_connector" to client.resolve("conns::require_connector"),
8892
)
8993
}
9094

@@ -121,15 +125,20 @@ class ServiceRuntimePluginGenerator(
121125
#{SharedEndpointResolver}::from(self.handle.conf.endpoint_resolver()));
122126
cfg.set_endpoint_resolver(endpoint_resolver);
123127
124-
// TODO(RuntimePlugins): Wire up standard retry
128+
// TODO(enableNewSmithyRuntime): Wire up standard retry
125129
cfg.set_retry_strategy(#{NeverRetryStrategy}::new());
126130
127-
// TODO(RuntimePlugins): Replace this with the correct long-term solution
128131
let sleep_impl = self.handle.conf.sleep_impl();
129-
let connection: #{Box}<dyn #{Connection}> = self.handle.conf.http_connector()
130-
.and_then(move |c| c.connector(&#{ConnectorSettings}::default(), sleep_impl))
131-
.map(|c| #{Box}::new(#{DynConnectorAdapter}::new(c)) as _)
132-
.expect("connection set");
132+
let timeout_config = self.handle.conf.timeout_config();
133+
let connector_settings = timeout_config.map(|c| #{ConnectorSettings}::from_timeout_config(c)).unwrap_or_default();
134+
let connection: #{Box}<dyn #{Connection}> = #{Box}::new(#{DynConnectorAdapter}::new(
135+
// TODO(enableNewSmithyRuntime): Replace the tower-based DynConnector and remove DynConnectorAdapter when deleting the middleware implementation
136+
#{require_connector}(
137+
self.handle.conf.http_connector()
138+
.and_then(|c| c.connector(&connector_settings, sleep_impl.clone()))
139+
.or_else(|| #{default_connector}(&connector_settings, sleep_impl))
140+
)?
141+
)) as _;
133142
cfg.set_connection(connection);
134143
135144
#{additional_config}

rust-runtime/aws-smithy-client/src/conns.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
//! Type aliases for standard connection types.
77
8+
use crate::erase::DynConnector;
9+
810
#[cfg(feature = "rustls")]
911
/// A `hyper` connector that uses the `rustls` crate for TLS. To use this in a smithy client,
1012
/// wrap it in a [hyper_ext::Adapter](crate::hyper_ext::Adapter).
@@ -49,6 +51,64 @@ lazy_static::lazy_static! {
4951
};
5052
}
5153

54+
mod default_connector {
55+
use crate::erase::DynConnector;
56+
use crate::http_connector::ConnectorSettings;
57+
use aws_smithy_async::rt::sleep::AsyncSleep;
58+
use std::sync::Arc;
59+
60+
#[cfg(feature = "rustls")]
61+
fn base(
62+
settings: &ConnectorSettings,
63+
sleep: Option<Arc<dyn AsyncSleep>>,
64+
) -> crate::hyper_ext::Builder {
65+
let mut hyper = crate::hyper_ext::Adapter::builder().connector_settings(settings.clone());
66+
if let Some(sleep) = sleep {
67+
hyper = hyper.sleep_impl(sleep);
68+
}
69+
hyper
70+
}
71+
72+
/// Given `ConnectorSettings` and an `AsyncSleep`, create a `DynConnector` from defaults depending on what cargo features are activated.
73+
pub fn default_connector(
74+
settings: &ConnectorSettings,
75+
sleep: Option<Arc<dyn AsyncSleep>>,
76+
) -> Option<DynConnector> {
77+
#[cfg(feature = "rustls")]
78+
{
79+
tracing::trace!(settings = ?settings, sleep = ?sleep, "creating a new default connector");
80+
let hyper = base(settings, sleep).build(super::https());
81+
Some(DynConnector::new(hyper))
82+
}
83+
#[cfg(not(feature = "rustls"))]
84+
{
85+
tracing::trace!(settings = ?settings, sleep = ?sleep, "no default connector available");
86+
None
87+
}
88+
}
89+
}
90+
pub use default_connector::default_connector;
91+
92+
/// Error that indicates a connector is required.
93+
#[non_exhaustive]
94+
#[derive(Debug, Default)]
95+
pub struct ConnectorRequiredError;
96+
97+
impl std::fmt::Display for ConnectorRequiredError {
98+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99+
f.write_str("No HTTP connector was available. Enable the `rustls` crate feature or set a connector to fix this.")
100+
}
101+
}
102+
103+
impl std::error::Error for ConnectorRequiredError {}
104+
105+
/// Converts an optional connector to a result.
106+
pub fn require_connector(
107+
connector: Option<DynConnector>,
108+
) -> Result<DynConnector, ConnectorRequiredError> {
109+
connector.ok_or(ConnectorRequiredError)
110+
}
111+
52112
#[cfg(feature = "rustls")]
53113
/// Return a default HTTPS connector backed by the `rustls` crate.
54114
///

0 commit comments

Comments
 (0)