Skip to content

Commit 04eabf8

Browse files
ysaito1001aws-sdk-rust-ci
authored andcommitted
[smithy-rs] Follow up on DefaultEndpointResolver in the orchestrator (#2592)
## Motivation and Context This PR incorporates post-merge feedback left in #2577. ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._ --------- Co-authored-by: Yuki Saito <awsaito@amazon.com>
1 parent e094798 commit 04eabf8

File tree

7 files changed

+138
-120
lines changed

7 files changed

+138
-120
lines changed

sdk/aws-smithy-runtime-api/src/client.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,5 @@ pub mod retries;
2121
/// Runtime plugin type definitions.
2222
pub mod runtime_plugin;
2323

24-
/// Smithy endpoint resolution runtime plugins
25-
pub mod endpoints;
26-
2724
/// Smithy auth runtime plugins
2825
pub mod auth;

sdk/aws-smithy-runtime-api/src/client/endpoints.rs

Lines changed: 0 additions & 110 deletions
This file was deleted.

sdk/aws-smithy-runtime-api/src/client/interceptors/error.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,31 @@ impl std::error::Error for InterceptorError {
169169
self.source.as_ref().map(|err| err.as_ref() as _)
170170
}
171171
}
172+
173+
/// A convenience error that allows for adding additional `context` to `source`
174+
#[derive(Debug)]
175+
pub struct ContextAttachedError {
176+
context: String,
177+
source: Option<BoxError>,
178+
}
179+
180+
impl ContextAttachedError {
181+
pub fn new(context: impl Into<String>, source: impl Into<BoxError>) -> Self {
182+
Self {
183+
context: context.into(),
184+
source: Some(source.into()),
185+
}
186+
}
187+
}
188+
189+
impl fmt::Display for ContextAttachedError {
190+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191+
write!(f, "{}", self.context)
192+
}
193+
}
194+
195+
impl std::error::Error for ContextAttachedError {
196+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
197+
self.source.as_ref().map(|err| err.as_ref() as _)
198+
}
199+
}

sdk/aws-smithy-runtime/external-types.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ allowed_external_types = [
66
"http::header::name::HeaderName",
77
"http::request::Request",
88
"http::response::Response",
9-
"uri::Uri",
9+
"http::uri::Uri",
1010
]

sdk/aws-smithy-runtime/src/client/orchestrator.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use aws_smithy_runtime_api::config_bag::ConfigBag;
1818
use tracing::{debug_span, Instrument};
1919

2020
mod auth;
21-
mod endpoints;
21+
/// Defines types that implement a trait for endpoint resolution
22+
pub mod endpoints;
2223
mod http;
2324
pub(self) mod phase;
2425

sdk/aws-smithy-runtime/src/client/orchestrator/endpoints.rs

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,114 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
use aws_smithy_http::endpoint::EndpointPrefix;
6+
use aws_smithy_http::endpoint::error::ResolveEndpointError;
7+
use aws_smithy_http::endpoint::{
8+
apply_endpoint, EndpointPrefix, ResolveEndpoint, SharedEndpointResolver,
9+
};
710
use aws_smithy_runtime_api::client::interceptors::InterceptorContext;
811
use aws_smithy_runtime_api::client::orchestrator::{
9-
BoxError, ConfigBagAccessors, HttpRequest, HttpResponse,
12+
BoxError, ConfigBagAccessors, EndpointResolver, EndpointResolverParams, HttpRequest,
13+
HttpResponse,
1014
};
1115
use aws_smithy_runtime_api::config_bag::ConfigBag;
16+
use http::header::HeaderName;
17+
use http::{HeaderValue, Uri};
18+
use std::fmt::Debug;
19+
use std::str::FromStr;
20+
21+
#[derive(Debug, Clone)]
22+
pub struct StaticUriEndpointResolver {
23+
endpoint: Uri,
24+
}
25+
26+
impl StaticUriEndpointResolver {
27+
pub fn http_localhost(port: u16) -> Self {
28+
Self {
29+
endpoint: Uri::from_str(&format!("http://localhost:{port}"))
30+
.expect("all u16 values are valid ports"),
31+
}
32+
}
33+
34+
pub fn uri(endpoint: Uri) -> Self {
35+
Self { endpoint }
36+
}
37+
}
38+
39+
impl EndpointResolver for StaticUriEndpointResolver {
40+
fn resolve_and_apply_endpoint(
41+
&self,
42+
_params: &EndpointResolverParams,
43+
_endpoint_prefix: Option<&EndpointPrefix>,
44+
request: &mut HttpRequest,
45+
) -> Result<(), BoxError> {
46+
apply_endpoint(request.uri_mut(), &self.endpoint, None)?;
47+
Ok(())
48+
}
49+
}
50+
51+
#[derive(Debug, Clone)]
52+
pub struct DefaultEndpointResolver<Params> {
53+
inner: SharedEndpointResolver<Params>,
54+
}
55+
56+
impl<Params> DefaultEndpointResolver<Params> {
57+
pub fn new(resolve_endpoint: SharedEndpointResolver<Params>) -> Self {
58+
Self {
59+
inner: resolve_endpoint,
60+
}
61+
}
62+
}
63+
64+
impl<Params> EndpointResolver for DefaultEndpointResolver<Params>
65+
where
66+
Params: Debug + Send + Sync + 'static,
67+
{
68+
fn resolve_and_apply_endpoint(
69+
&self,
70+
params: &EndpointResolverParams,
71+
endpoint_prefix: Option<&EndpointPrefix>,
72+
request: &mut HttpRequest,
73+
) -> Result<(), BoxError> {
74+
let endpoint = match params.get::<Params>() {
75+
Some(params) => self.inner.resolve_endpoint(params)?,
76+
None => {
77+
return Err(Box::new(ResolveEndpointError::message(
78+
"params of expected type was not present",
79+
)));
80+
}
81+
};
82+
83+
let uri: Uri = endpoint.url().parse().map_err(|err| {
84+
ResolveEndpointError::from_source("endpoint did not have a valid uri", err)
85+
})?;
86+
87+
apply_endpoint(request.uri_mut(), &uri, endpoint_prefix).map_err(|err| {
88+
ResolveEndpointError::message(format!(
89+
"failed to apply endpoint `{:?}` to request `{:?}`",
90+
uri, request,
91+
))
92+
.with_source(Some(err.into()))
93+
})?;
94+
95+
for (header_name, header_values) in endpoint.headers() {
96+
request.headers_mut().remove(header_name);
97+
for value in header_values {
98+
request.headers_mut().insert(
99+
HeaderName::from_str(header_name).map_err(|err| {
100+
ResolveEndpointError::message("invalid header name")
101+
.with_source(Some(err.into()))
102+
})?,
103+
HeaderValue::from_str(value).map_err(|err| {
104+
ResolveEndpointError::message("invalid header value")
105+
.with_source(Some(err.into()))
106+
})?,
107+
);
108+
}
109+
}
110+
111+
Ok(())
112+
}
113+
}
12114

13115
pub(super) fn orchestrate_endpoint(
14116
ctx: &mut InterceptorContext<HttpRequest, HttpResponse>,

versions.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
smithy_rs_revision = '1b138b09a2196d67fe6bc6a7b481ba4edfe25b0e'
1+
smithy_rs_revision = '08642d1e891733e08f8715f2a4d81f789ac133b5'
22
aws_doc_sdk_examples_revision = '1f48dbeac254cb3fa6d3eb25628ee748d42017d1'
33

44
[manual_interventions]
@@ -2141,12 +2141,12 @@ source_hash = 'd23bb3777f4a48f82be9d68582b67b14e73832f04a58dd29e632f2171a2d7df5'
21412141
[crates.aws-smithy-runtime]
21422142
category = 'SmithyRuntime'
21432143
version = '0.55.1'
2144-
source_hash = '8892131bb1110fcd32cc8bca1a7995be0124bd5ba8262d340b7c083b1387b2d3'
2144+
source_hash = '8d1bd249588e0280782e56b1871ecdcd0ea5aad41e6b432103db0d75cc7b10b9'
21452145

21462146
[crates.aws-smithy-runtime-api]
21472147
category = 'SmithyRuntime'
21482148
version = '0.55.1'
2149-
source_hash = 'ea4721f30fe639b63a87f2deee516096310de52127f7bb326e1510fe61a034f0'
2149+
source_hash = '80a5a7b92ec8b4f4eb5be0966ed5a7c0202d0866ab3c34946608b2f290e0ba04'
21502150

21512151
[crates.aws-smithy-types]
21522152
category = 'SmithyRuntime'

0 commit comments

Comments
 (0)