mirror of https://github.com/smithy-lang/smithy-rs
Remove deprecated ResolveAwsEndpoint and related interfaces. (#2464)
* Remove deprecated ResolveAwsEndpoint and related interfaces. * update changelog with pointer * Rename AwsEndpointDecorator to have a more appropriate name * Allow endpoint resolver to be omitted
This commit is contained in:
parent
05f920f672
commit
de97b3d7f3
|
@ -288,7 +288,6 @@ references = ["smithy-rs#2448"]
|
|||
meta = { "breaking" = true, "tada" = false, "bug" = false, "target" = "client" }
|
||||
author = "jdisanti"
|
||||
|
||||
|
||||
[[smithy-rs]]
|
||||
message = "Fix bug in timestamp format resolution. Prior to this fix, the timestamp format may have been incorrect if set on the target instead of on the member."
|
||||
references = ["smithy-rs#2226"]
|
||||
|
@ -339,8 +338,6 @@ references = ["smithy-rs#2467"]
|
|||
meta = { "breaking" = true, "tada" = true, "bug" = false, "target" = "all" }
|
||||
author = "Velfi"
|
||||
|
||||
###############
|
||||
|
||||
[[aws-sdk-rust]]
|
||||
message = """Default connector provided by `aws-config` now respects `ConnectorSettings`.
|
||||
|
||||
|
@ -353,6 +350,14 @@ references = ["smithy-rs#2471", "smithy-rs#2333", "smithy-rs#2151"]
|
|||
meta = { "breaking" = false, "tada" = false, "bug" = true }
|
||||
author = "rcoh"
|
||||
|
||||
[[aws-sdk-rust]] # remove interfaces
|
||||
message = """Remove deprecated `ResolveAwsEndpoint` interfaces.
|
||||
[For details see the longform changelog entry](https://github.com/awslabs/aws-sdk-rust/discussions/755).
|
||||
"""
|
||||
author = "rcoh"
|
||||
references = ["smithy-rs#2390", "smithy-rs#1784"]
|
||||
meta = { "breaking" = true, "tada" = false, "bug" = false }
|
||||
|
||||
[[smithy-rs]] # tokio-upgrade
|
||||
message = "Increase Tokio version to 1.23.1 for all crates. This is to address [RUSTSEC-2023-0001](https://rustsec.org/advisories/RUSTSEC-2023-0001)"
|
||||
references = ["smithy-rs#2474"]
|
||||
|
|
|
@ -159,7 +159,6 @@ mod loader {
|
|||
use aws_smithy_types::timeout::TimeoutConfig;
|
||||
use aws_types::app_name::AppName;
|
||||
use aws_types::docs_for;
|
||||
use aws_types::endpoint::ResolveAwsEndpoint;
|
||||
use aws_types::SdkConfig;
|
||||
|
||||
use crate::connector::default_connector;
|
||||
|
@ -181,7 +180,6 @@ mod loader {
|
|||
app_name: Option<AppName>,
|
||||
credentials_cache: Option<CredentialsCache>,
|
||||
credentials_provider: Option<SharedCredentialsProvider>,
|
||||
endpoint_resolver: Option<Arc<dyn ResolveAwsEndpoint>>,
|
||||
endpoint_url: Option<String>,
|
||||
region: Option<Box<dyn ProvideRegion>>,
|
||||
retry_config: Option<RetryConfig>,
|
||||
|
@ -345,36 +343,6 @@ mod loader {
|
|||
self
|
||||
}
|
||||
|
||||
/// Override the endpoint resolver used for **all** AWS Services
|
||||
///
|
||||
/// This method is deprecated. Use [`Self::endpoint_url`] instead.
|
||||
///
|
||||
/// This method will override the endpoint resolver used for **all** AWS services. This mainly
|
||||
/// exists to set a static endpoint for tools like `LocalStack`. For live traffic, AWS services
|
||||
/// require the service-specific endpoint resolver they load by default.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Use a static endpoint for all services
|
||||
/// ```no_run
|
||||
/// # async fn create_config() -> Result<(), aws_smithy_http::endpoint::error::InvalidEndpointError> {
|
||||
/// use aws_config::endpoint::Endpoint;
|
||||
///
|
||||
/// let sdk_config = aws_config::from_env()
|
||||
/// .endpoint_resolver(Endpoint::immutable("http://localhost:1234")?)
|
||||
/// .load()
|
||||
/// .await;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
#[deprecated(note = "use `.endpoint_url(...)` instead")]
|
||||
pub fn endpoint_resolver(
|
||||
mut self,
|
||||
endpoint_resolver: impl ResolveAwsEndpoint + 'static,
|
||||
) -> Self {
|
||||
self.endpoint_resolver = Some(Arc::new(endpoint_resolver));
|
||||
self
|
||||
}
|
||||
|
||||
/// Provides the ability to programmatically override the profile files that get loaded by the SDK.
|
||||
///
|
||||
/// The [`Default`] for `ProfileFiles` includes the default SDK config and credential files located in
|
||||
|
@ -600,8 +568,6 @@ mod loader {
|
|||
SharedCredentialsProvider::new(builder.build().await)
|
||||
};
|
||||
|
||||
let endpoint_resolver = self.endpoint_resolver;
|
||||
|
||||
let mut builder = SdkConfig::builder()
|
||||
.region(region)
|
||||
.retry_config(retry_config)
|
||||
|
@ -610,7 +576,6 @@ mod loader {
|
|||
.credentials_provider(credentials_provider)
|
||||
.http_connector(http_connector);
|
||||
|
||||
builder.set_endpoint_resolver(endpoint_resolver);
|
||||
builder.set_app_name(app_name);
|
||||
builder.set_sleep_impl(sleep_impl);
|
||||
builder.set_endpoint_url(self.endpoint_url);
|
||||
|
|
|
@ -5,84 +5,17 @@
|
|||
|
||||
#![allow(clippy::derive_partial_eq_without_eq)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
|
||||
use aws_smithy_http::endpoint::error::ResolveEndpointError;
|
||||
use aws_smithy_http::endpoint::ResolveEndpoint;
|
||||
use aws_smithy_http::middleware::MapRequest;
|
||||
use aws_smithy_http::operation::Request;
|
||||
use aws_smithy_types::endpoint::Endpoint as SmithyEndpoint;
|
||||
use aws_smithy_types::Document;
|
||||
|
||||
pub use aws_types::endpoint::{AwsEndpoint, BoxError, CredentialScope, ResolveAwsEndpoint};
|
||||
use aws_types::region::{Region, SigningRegion};
|
||||
use aws_types::SigningService;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct Params {
|
||||
region: Option<Region>,
|
||||
}
|
||||
|
||||
impl Params {
|
||||
pub fn new(region: Option<Region>) -> Self {
|
||||
Self { region }
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct EndpointShim(Arc<dyn ResolveAwsEndpoint>);
|
||||
impl EndpointShim {
|
||||
pub fn from_resolver(resolver: impl ResolveAwsEndpoint + 'static) -> Self {
|
||||
Self(Arc::new(resolver))
|
||||
}
|
||||
|
||||
pub fn from_arc(arc: Arc<dyn ResolveAwsEndpoint>) -> Self {
|
||||
Self(arc)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ResolveEndpoint<T> for EndpointShim
|
||||
where
|
||||
T: Clone + Into<Params>,
|
||||
{
|
||||
fn resolve_endpoint(&self, params: &T) -> Result<SmithyEndpoint, ResolveEndpointError> {
|
||||
let params: Params = params.clone().into();
|
||||
let aws_endpoint = self
|
||||
.0
|
||||
.resolve_endpoint(
|
||||
params
|
||||
.region
|
||||
.as_ref()
|
||||
.ok_or_else(|| ResolveEndpointError::message("no region in params"))?,
|
||||
)
|
||||
.map_err(|err| {
|
||||
ResolveEndpointError::message("failure resolving endpoint").with_source(Some(err))
|
||||
})?;
|
||||
let uri = aws_endpoint.endpoint().uri();
|
||||
let mut auth_scheme =
|
||||
HashMap::from([("name".to_string(), Document::String("sigv4".into()))]);
|
||||
if let Some(region) = aws_endpoint.credential_scope().region() {
|
||||
auth_scheme.insert(
|
||||
"signingRegion".to_string(),
|
||||
region.as_ref().to_string().into(),
|
||||
);
|
||||
}
|
||||
if let Some(service) = aws_endpoint.credential_scope().service() {
|
||||
auth_scheme.insert(
|
||||
"signingName".to_string(),
|
||||
service.as_ref().to_string().into(),
|
||||
);
|
||||
}
|
||||
Ok(SmithyEndpoint::builder()
|
||||
.url(uri.to_string())
|
||||
.property("authSchemes", vec![Document::Object(auth_scheme)])
|
||||
.build())
|
||||
}
|
||||
}
|
||||
|
||||
/// Middleware Stage to add authentication information from a Smithy endpoint into the property bag
|
||||
///
|
||||
/// AwsAuthStage implements [`MapRequest`](MapRequest). It will:
|
||||
|
@ -95,7 +28,7 @@ pub struct AwsAuthStage;
|
|||
#[derive(Debug)]
|
||||
enum AwsAuthStageErrorKind {
|
||||
NoEndpointResolver,
|
||||
EndpointResolutionError(BoxError),
|
||||
EndpointResolutionError(Box<dyn Error + Send + Sync>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -1,192 +0,0 @@
|
|||
/*
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
//! AWS SDK endpoint support.
|
||||
#![allow(deprecated)]
|
||||
|
||||
use crate::region::{Region, SigningRegion};
|
||||
use crate::SigningService;
|
||||
use aws_smithy_http::endpoint::error::InvalidEndpointError;
|
||||
use aws_smithy_http::endpoint::{Endpoint, EndpointPrefix};
|
||||
use std::error::Error;
|
||||
use std::fmt::Debug;
|
||||
|
||||
/// Endpoint to connect to an AWS Service
|
||||
///
|
||||
/// An `AwsEndpoint` captures all necessary information needed to connect to an AWS service, including:
|
||||
/// - The URI of the endpoint (needed to actually send the request)
|
||||
/// - The name of the service (needed downstream for signing)
|
||||
/// - The signing region (which may differ from the actual region)
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AwsEndpoint {
|
||||
endpoint: Endpoint,
|
||||
credential_scope: CredentialScope,
|
||||
}
|
||||
|
||||
impl AwsEndpoint {
|
||||
/// Constructs a new AWS endpoint.
|
||||
pub fn new(endpoint: Endpoint, credential_scope: CredentialScope) -> AwsEndpoint {
|
||||
AwsEndpoint {
|
||||
endpoint,
|
||||
credential_scope,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the underlying endpoint.
|
||||
pub fn endpoint(&self) -> &Endpoint {
|
||||
&self.endpoint
|
||||
}
|
||||
|
||||
/// Returns the credential scope.
|
||||
pub fn credential_scope(&self) -> &CredentialScope {
|
||||
&self.credential_scope
|
||||
}
|
||||
|
||||
/// Sets the endpoint on a given `uri` based on this endpoint
|
||||
pub fn set_endpoint(
|
||||
&self,
|
||||
uri: &mut http::Uri,
|
||||
endpoint_prefix: Option<&EndpointPrefix>,
|
||||
) -> Result<(), InvalidEndpointError> {
|
||||
self.endpoint.set_endpoint(uri, endpoint_prefix)
|
||||
}
|
||||
}
|
||||
|
||||
/// A boxed error.
|
||||
pub type BoxError = Box<dyn Error + Send + Sync + 'static>;
|
||||
|
||||
/// Resolve the AWS Endpoint for a given region
|
||||
///
|
||||
/// To provide a static endpoint, [`Endpoint`](aws_smithy_http::endpoint::Endpoint) implements this trait.
|
||||
/// Example usage:
|
||||
/// ```rust
|
||||
/// # mod dynamodb {
|
||||
/// # use aws_types::endpoint::ResolveAwsEndpoint;
|
||||
/// # pub struct ConfigBuilder;
|
||||
/// # impl ConfigBuilder {
|
||||
/// # pub fn endpoint(&mut self, resolver: impl ResolveAwsEndpoint + 'static) {
|
||||
/// # // ...
|
||||
/// # }
|
||||
/// # }
|
||||
/// # pub struct Config;
|
||||
/// # impl Config {
|
||||
/// # pub fn builder() -> ConfigBuilder {
|
||||
/// # ConfigBuilder
|
||||
/// # }
|
||||
/// # }
|
||||
/// # }
|
||||
/// # fn wrapper() -> Result<(), aws_smithy_http::endpoint::error::InvalidEndpointError> {
|
||||
/// use aws_smithy_http::endpoint::Endpoint;
|
||||
/// let config = dynamodb::Config::builder()
|
||||
/// .endpoint(Endpoint::immutable("http://localhost:8080")?);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
/// Each AWS service generates their own implementation of `ResolveAwsEndpoint`.
|
||||
pub trait ResolveAwsEndpoint: Send + Sync + Debug {
|
||||
/// Resolves the AWS endpoint for a given region.
|
||||
fn resolve_endpoint(&self, region: &Region) -> Result<AwsEndpoint, BoxError>;
|
||||
}
|
||||
|
||||
/// The scope for AWS credentials.
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct CredentialScope {
|
||||
region: Option<SigningRegion>,
|
||||
service: Option<SigningService>,
|
||||
}
|
||||
|
||||
impl CredentialScope {
|
||||
/// Creates a builder for [`CredentialScope`].
|
||||
pub fn builder() -> credential_scope::Builder {
|
||||
credential_scope::Builder::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Types associated with [`CredentialScope`].
|
||||
pub mod credential_scope {
|
||||
use crate::endpoint::CredentialScope;
|
||||
use crate::region::SigningRegion;
|
||||
use crate::SigningService;
|
||||
|
||||
/// A builder for [`CredentialScope`].
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Builder {
|
||||
region: Option<SigningRegion>,
|
||||
service: Option<SigningService>,
|
||||
}
|
||||
|
||||
impl Builder {
|
||||
/// Sets the signing region.
|
||||
pub fn region(mut self, region: impl Into<SigningRegion>) -> Self {
|
||||
self.region = Some(region.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the signing service.
|
||||
pub fn service(mut self, service: impl Into<SigningService>) -> Self {
|
||||
self.service = Some(service.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Constructs a [`CredentialScope`] from the builder.
|
||||
pub fn build(self) -> CredentialScope {
|
||||
CredentialScope {
|
||||
region: self.region,
|
||||
service: self.service,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CredentialScope {
|
||||
/// Returns the signing region.
|
||||
pub fn region(&self) -> Option<&SigningRegion> {
|
||||
self.region.as_ref()
|
||||
}
|
||||
|
||||
/// Returns the signing service.
|
||||
pub fn service(&self) -> Option<&SigningService> {
|
||||
self.service.as_ref()
|
||||
}
|
||||
|
||||
/// Uses the values from `other` to fill in unconfigured parameters on this
|
||||
/// credential scope object.
|
||||
pub fn merge(&self, other: &CredentialScope) -> CredentialScope {
|
||||
CredentialScope {
|
||||
region: self.region.clone().or_else(|| other.region.clone()),
|
||||
service: self.service.clone().or_else(|| other.service.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An `Endpoint` can be its own resolver to support static endpoints
|
||||
impl ResolveAwsEndpoint for Endpoint {
|
||||
fn resolve_endpoint(&self, _region: &Region) -> Result<AwsEndpoint, BoxError> {
|
||||
Ok(AwsEndpoint {
|
||||
endpoint: self.clone(),
|
||||
credential_scope: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::endpoint::CredentialScope;
|
||||
use crate::region::SigningRegion;
|
||||
use crate::SigningService;
|
||||
|
||||
#[test]
|
||||
fn create_credentials_scope_from_strs() {
|
||||
let scope = CredentialScope::builder()
|
||||
.service("s3")
|
||||
.region("us-east-1")
|
||||
.build();
|
||||
assert_eq!(scope.service(), Some(&SigningService::from_static("s3")));
|
||||
assert_eq!(
|
||||
scope.region(),
|
||||
Some(&SigningRegion::from_static("us-east-1"))
|
||||
);
|
||||
}
|
||||
}
|
|
@ -16,9 +16,6 @@
|
|||
|
||||
pub mod app_name;
|
||||
pub mod build_metadata;
|
||||
#[deprecated(since = "0.9.0", note = "renamed to sdk_config")]
|
||||
pub mod config;
|
||||
pub mod endpoint;
|
||||
#[doc(hidden)]
|
||||
pub mod os_shim_internal;
|
||||
pub mod region;
|
||||
|
|
|
@ -20,7 +20,6 @@ use aws_smithy_types::timeout::TimeoutConfig;
|
|||
|
||||
use crate::app_name::AppName;
|
||||
use crate::docs_for;
|
||||
use crate::endpoint::ResolveAwsEndpoint;
|
||||
use crate::region::Region;
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -51,7 +50,6 @@ pub struct SdkConfig {
|
|||
credentials_cache: Option<CredentialsCache>,
|
||||
credentials_provider: Option<SharedCredentialsProvider>,
|
||||
region: Option<Region>,
|
||||
endpoint_resolver: Option<Arc<dyn ResolveAwsEndpoint>>,
|
||||
endpoint_url: Option<String>,
|
||||
retry_config: Option<RetryConfig>,
|
||||
sleep_impl: Option<Arc<dyn AsyncSleep>>,
|
||||
|
@ -72,7 +70,6 @@ pub struct Builder {
|
|||
credentials_cache: Option<CredentialsCache>,
|
||||
credentials_provider: Option<SharedCredentialsProvider>,
|
||||
region: Option<Region>,
|
||||
endpoint_resolver: Option<Arc<dyn ResolveAwsEndpoint>>,
|
||||
endpoint_url: Option<String>,
|
||||
retry_config: Option<RetryConfig>,
|
||||
sleep_impl: Option<Arc<dyn AsyncSleep>>,
|
||||
|
@ -117,31 +114,6 @@ impl Builder {
|
|||
self
|
||||
}
|
||||
|
||||
/// Set the endpoint resolver to use when making requests
|
||||
///
|
||||
/// This method is deprecated. Use [`Self::endpoint_url`] instead.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # fn wrapper() -> Result<(), aws_smithy_http::endpoint::error::InvalidEndpointError> {
|
||||
/// use std::sync::Arc;
|
||||
/// use aws_types::SdkConfig;
|
||||
/// use aws_smithy_http::endpoint::Endpoint;
|
||||
/// let config = SdkConfig::builder().endpoint_resolver(
|
||||
/// Endpoint::immutable("http://localhost:8080")?
|
||||
/// ).build();
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[deprecated(note = "use `endpoint_url` instead")]
|
||||
pub fn endpoint_resolver(
|
||||
mut self,
|
||||
endpoint_resolver: impl ResolveAwsEndpoint + 'static,
|
||||
) -> Self {
|
||||
self.set_endpoint_resolver(Some(Arc::new(endpoint_resolver)));
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the endpoint url to use when making requests.
|
||||
/// # Examples
|
||||
/// ```
|
||||
|
@ -159,29 +131,6 @@ impl Builder {
|
|||
self
|
||||
}
|
||||
|
||||
/// Set the endpoint resolver to use when making requests
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use std::sync::Arc;
|
||||
/// use aws_types::SdkConfig;
|
||||
/// use aws_types::endpoint::ResolveAwsEndpoint;
|
||||
/// fn endpoint_resolver_override() -> Option<Arc<dyn ResolveAwsEndpoint>> {
|
||||
/// // ...
|
||||
/// # None
|
||||
/// }
|
||||
/// let mut config = SdkConfig::builder();
|
||||
/// config.set_endpoint_resolver(endpoint_resolver_override());
|
||||
/// config.build();
|
||||
/// ```
|
||||
pub fn set_endpoint_resolver(
|
||||
&mut self,
|
||||
endpoint_resolver: Option<Arc<dyn ResolveAwsEndpoint>>,
|
||||
) -> &mut Self {
|
||||
self.endpoint_resolver = endpoint_resolver;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the retry_config for the builder
|
||||
///
|
||||
/// _Note:_ Retries require a sleep implementation in order to work. When enabling retry, make
|
||||
|
@ -557,7 +506,6 @@ impl Builder {
|
|||
credentials_cache: self.credentials_cache,
|
||||
credentials_provider: self.credentials_provider,
|
||||
region: self.region,
|
||||
endpoint_resolver: self.endpoint_resolver,
|
||||
endpoint_url: self.endpoint_url,
|
||||
retry_config: self.retry_config,
|
||||
sleep_impl: self.sleep_impl,
|
||||
|
@ -575,11 +523,6 @@ impl SdkConfig {
|
|||
self.region.as_ref()
|
||||
}
|
||||
|
||||
/// Configured endpoint resolver
|
||||
pub fn endpoint_resolver(&self) -> Option<Arc<dyn ResolveAwsEndpoint>> {
|
||||
self.endpoint_resolver.clone()
|
||||
}
|
||||
|
||||
/// Configured endpoint URL
|
||||
pub fn endpoint_url(&self) -> Option<&str> {
|
||||
self.endpoint_url.as_deref()
|
||||
|
|
|
@ -20,9 +20,9 @@ import software.amazon.smithy.rustsdk.customize.s3.S3Decorator
|
|||
import software.amazon.smithy.rustsdk.customize.s3.S3ExtendedRequestIdDecorator
|
||||
import software.amazon.smithy.rustsdk.customize.s3control.S3ControlDecorator
|
||||
import software.amazon.smithy.rustsdk.customize.sts.STSDecorator
|
||||
import software.amazon.smithy.rustsdk.endpoints.AwsEndpointDecorator
|
||||
import software.amazon.smithy.rustsdk.endpoints.AwsEndpointsStdLib
|
||||
import software.amazon.smithy.rustsdk.endpoints.OperationInputTestDecorator
|
||||
import software.amazon.smithy.rustsdk.endpoints.RequireEndpointRules
|
||||
|
||||
val DECORATORS: List<ClientCodegenDecorator> = listOf(
|
||||
// General AWS Decorators
|
||||
|
@ -30,7 +30,7 @@ val DECORATORS: List<ClientCodegenDecorator> = listOf(
|
|||
CredentialsCacheDecorator(),
|
||||
CredentialsProviderDecorator(),
|
||||
RegionDecorator(),
|
||||
AwsEndpointDecorator(),
|
||||
RequireEndpointRules(),
|
||||
UserAgentDecorator(),
|
||||
SigV4SigningDecorator(),
|
||||
HttpRequestChecksumDecorator(),
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package software.amazon.smithy.rustsdk
|
||||
|
||||
import software.amazon.smithy.model.node.ObjectNode
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
|
||||
import software.amazon.smithy.rust.codegen.core.smithy.CoreRustSettings
|
||||
import software.amazon.smithy.rust.codegen.core.util.orNull
|
||||
import java.nio.file.Path
|
||||
|
@ -40,10 +41,17 @@ class SdkSettings private constructor(private val awsSdk: ObjectNode?) {
|
|||
awsSdk?.getStringMember("integrationTestPath")?.orNull()?.value ?: "aws/sdk/integration-tests"
|
||||
|
||||
/** Version number of the `aws-config` crate */
|
||||
val awsConfigVersion: String? get() =
|
||||
awsSdk?.getStringMember("awsConfigVersion")?.orNull()?.value
|
||||
val awsConfigVersion: String?
|
||||
get() =
|
||||
awsSdk?.getStringMember("awsConfigVersion")?.orNull()?.value
|
||||
|
||||
/** Whether to generate a README */
|
||||
val generateReadme: Boolean get() =
|
||||
awsSdk?.getBooleanMember("generateReadme")?.orNull()?.value ?: false
|
||||
val generateReadme: Boolean
|
||||
get() =
|
||||
awsSdk?.getBooleanMember("generateReadme")?.orNull()?.value ?: false
|
||||
|
||||
val requireEndpointResolver: Boolean
|
||||
get() = awsSdk?.getBooleanMember("requireEndpointResolver")?.orNull()?.value ?: true
|
||||
}
|
||||
|
||||
fun ClientCodegenContext.sdkSettings() = SdkSettings.from(this.settings)
|
||||
|
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package software.amazon.smithy.rustsdk.endpoints
|
||||
|
||||
import software.amazon.smithy.codegen.core.CodegenException
|
||||
import software.amazon.smithy.rulesengine.language.syntax.parameters.Builtins
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.EndpointTypesGenerator
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.featureGatedConfigModule
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
|
||||
import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency
|
||||
import software.amazon.smithy.rust.codegen.core.rustlang.rust
|
||||
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
|
||||
import software.amazon.smithy.rust.codegen.core.rustlang.writable
|
||||
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
|
||||
import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization
|
||||
import software.amazon.smithy.rust.codegen.core.smithy.customize.adhocCustomization
|
||||
import software.amazon.smithy.rust.codegen.core.util.extendIf
|
||||
import software.amazon.smithy.rust.codegen.core.util.thenSingletonListOf
|
||||
import software.amazon.smithy.rustsdk.AwsRuntimeType
|
||||
import software.amazon.smithy.rustsdk.SdkConfigSection
|
||||
import software.amazon.smithy.rustsdk.getBuiltIn
|
||||
|
||||
class AwsEndpointDecorator : ClientCodegenDecorator {
|
||||
override val name: String = "AwsEndpoint"
|
||||
override val order: Byte = 100
|
||||
|
||||
override fun configCustomizations(
|
||||
codegenContext: ClientCodegenContext,
|
||||
baseCustomizations: List<ConfigCustomization>,
|
||||
): List<ConfigCustomization> {
|
||||
return baseCustomizations.extendIf(codegenContext.isRegionalized()) {
|
||||
AwsEndpointShimCustomization(codegenContext)
|
||||
}
|
||||
}
|
||||
|
||||
override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
|
||||
rustCrate.withModule(codegenContext.featureGatedConfigModule()) {
|
||||
rust(
|
||||
"pub use #T::endpoint::Endpoint;",
|
||||
CargoDependency.smithyHttp(codegenContext.runtimeConfig).toType(),
|
||||
)
|
||||
}
|
||||
|
||||
val epTypes = EndpointTypesGenerator.fromContext(codegenContext)
|
||||
if (epTypes.defaultResolver() == null) {
|
||||
throw CodegenException(
|
||||
"${codegenContext.serviceShape} did not provide endpoint rules. " +
|
||||
"This is a bug and the generated client will not work. All AWS services MUST define endpoint rules.",
|
||||
)
|
||||
}
|
||||
// generate a region converter if params has a region
|
||||
if (!codegenContext.isRegionalized()) {
|
||||
println("not generating a resolver for ${codegenContext.serviceShape}")
|
||||
return
|
||||
}
|
||||
rustCrate.withModule(ClientRustModule.Endpoint) {
|
||||
// TODO(https://github.com/awslabs/smithy-rs/issues/1784) cleanup task
|
||||
rustTemplate(
|
||||
"""
|
||||
/// Temporary shim to allow new and old endpoint resolvers to co-exist
|
||||
///
|
||||
/// This enables converting from the actual parameters type to the placeholder parameters type that
|
||||
/// contains a region
|
||||
##[doc(hidden)]
|
||||
impl From<#{Params}> for #{PlaceholderParams} {
|
||||
fn from(params: #{Params}) -> Self {
|
||||
Self::new(params.region().map(|r|#{Region}::new(r.to_string())))
|
||||
}
|
||||
}
|
||||
""",
|
||||
"Params" to epTypes.paramsStruct(),
|
||||
"Region" to AwsRuntimeType.awsTypes(codegenContext.runtimeConfig).resolve("region::Region"),
|
||||
"PlaceholderParams" to AwsRuntimeType.awsEndpoint(codegenContext.runtimeConfig).resolve("Params"),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun extraSections(codegenContext: ClientCodegenContext): List<AdHocCustomization> {
|
||||
return codegenContext.isRegionalized().thenSingletonListOf {
|
||||
adhocCustomization<SdkConfigSection.CopySdkConfigToClientConfig> { section ->
|
||||
rust(
|
||||
"""
|
||||
${section.serviceConfigBuilder}.set_aws_endpoint_resolver(${section.sdkConfig}.endpoint_resolver().clone());
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AwsEndpointShimCustomization(codegenContext: ClientCodegenContext) : ConfigCustomization() {
|
||||
private val moduleUseName = codegenContext.moduleUseName()
|
||||
private val runtimeConfig = codegenContext.runtimeConfig
|
||||
private val resolveAwsEndpoint = AwsRuntimeType.awsEndpoint(runtimeConfig).resolve("ResolveAwsEndpoint")
|
||||
private val endpointShim = AwsRuntimeType.awsEndpoint(runtimeConfig).resolve("EndpointShim")
|
||||
private val codegenScope = arrayOf(
|
||||
"ResolveAwsEndpoint" to resolveAwsEndpoint,
|
||||
"EndpointShim" to endpointShim,
|
||||
"aws_types" to AwsRuntimeType.awsTypes(runtimeConfig),
|
||||
)
|
||||
|
||||
override fun section(section: ServiceConfig) = writable {
|
||||
when (section) {
|
||||
ServiceConfig.BuilderImpl -> rustTemplate(
|
||||
"""
|
||||
/// Overrides the endpoint resolver to use when making requests.
|
||||
///
|
||||
/// This method is deprecated, use [`Builder::endpoint_url`] or [`Builder::endpoint_resolver`] instead.
|
||||
///
|
||||
/// When unset, the client will used a generated endpoint resolver based on the endpoint metadata
|
||||
/// for `$moduleUseName`.
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```no_run
|
||||
/// ## fn wrapper() -> Result<(), aws_smithy_http::endpoint::error::InvalidEndpointError> {
|
||||
/// use $moduleUseName::config::{Config, Endpoint, Region};
|
||||
///
|
||||
/// let config = Config::builder()
|
||||
/// .endpoint_resolver(Endpoint::immutable("http://localhost:8080")?)
|
||||
/// .build();
|
||||
/// ## Ok(())
|
||||
/// ## }
|
||||
/// ```
|
||||
##[deprecated(note = "use endpoint_url or set the endpoint resolver directly")]
|
||||
pub fn aws_endpoint_resolver(mut self, endpoint_resolver: impl #{ResolveAwsEndpoint} + 'static) -> Self {
|
||||
self.endpoint_resolver = Some(std::sync::Arc::new(#{EndpointShim}::from_resolver(endpoint_resolver)) as _);
|
||||
self
|
||||
}
|
||||
|
||||
##[deprecated(note = "use endpoint_url or set the endpoint resolver directly")]
|
||||
/// Sets the endpoint resolver to use when making requests.
|
||||
///
|
||||
/// This method is deprecated, use [`Builder::endpoint_url`] or [`Builder::endpoint_resolver`] instead.
|
||||
pub fn set_aws_endpoint_resolver(&mut self, endpoint_resolver: Option<std::sync::Arc<dyn #{ResolveAwsEndpoint}>>) -> &mut Self {
|
||||
self.endpoint_resolver = endpoint_resolver.map(|res|std::sync::Arc::new(#{EndpointShim}::from_arc(res) ) as _);
|
||||
self
|
||||
}
|
||||
|
||||
""",
|
||||
*codegenScope,
|
||||
)
|
||||
|
||||
else -> emptySection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun ClientCodegenContext.isRegionalized() = getBuiltIn(Builtins.REGION) != null
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package software.amazon.smithy.rustsdk.endpoints
|
||||
|
||||
import software.amazon.smithy.codegen.core.CodegenException
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
|
||||
import software.amazon.smithy.rust.codegen.client.smithy.endpoint.EndpointTypesGenerator
|
||||
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
|
||||
import software.amazon.smithy.rustsdk.sdkSettings
|
||||
|
||||
class RequireEndpointRules : ClientCodegenDecorator {
|
||||
override val name: String = "RequireEndpointRules"
|
||||
override val order: Byte = 100
|
||||
override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
|
||||
if (!codegenContext.sdkSettings().requireEndpointResolver) {
|
||||
return
|
||||
}
|
||||
val epTypes = EndpointTypesGenerator.fromContext(codegenContext)
|
||||
if (epTypes.defaultResolver() == null) {
|
||||
throw CodegenException(
|
||||
"${codegenContext.serviceShape} did not provide endpoint rules. To explicitly allow this, set `awsSdk.requireEndpointResolver: false` in smithy-build.json.",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -523,7 +523,7 @@ Changes checklist
|
|||
- [x] Add a Smithy endpoint resolver to the service config, with a default that loads the default endpoint resolver.
|
||||
- [x] Update `SdkConfig` to accept a URI instead of an implementation of `ResolveAwsEndpoint`. This change can be done
|
||||
standalone.
|
||||
- [ ] Remove/deprecate the `ResolveAwsEndpoint` trait and replace it with the vanilla Smithy trait. Potentially, provide
|
||||
- [x] Remove/deprecate the `ResolveAwsEndpoint` trait and replace it with the vanilla Smithy trait. Potentially, provide
|
||||
a bridge.
|
||||
- [x] Update `make_operation` to write a [`smithy::Endpoint`](#the-endpoint-struct) into the property bag
|
||||
- [x] Update AWS Endpoint middleware to work off of a [`smithy::Endpoint`](#the-endpoint-struct)
|
||||
|
|
Loading…
Reference in New Issue