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:
Russell Cohen 2023-03-21 08:43:04 -04:00 committed by GitHub
parent 05f920f672
commit de97b3d7f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 53 additions and 520 deletions

View File

@ -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"]

View File

@ -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);

View File

@ -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)]

View File

@ -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"))
);
}
}

View File

@ -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;

View File

@ -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()

View File

@ -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(),

View File

@ -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)

View File

@ -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

View File

@ -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.",
)
}
}
}

View File

@ -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)