Client Test

Client Test

rev. a562638cb954071808c8908a73292885a41137c0 (ignoring whitespace)

Files changed:

tmp-codegen-diff/codegen-client-test/Cargo.lock

@@ -285,285 +345,345 @@
  305    305   
dependencies = [
  306    306   
 "bindgen",
  307    307   
 "cc",
  308    308   
 "cmake",
  309    309   
 "dunce",
  310    310   
 "fs_extra",
  311    311   
]
  312    312   
  313    313   
[[package]]
  314    314   
name = "aws-smithy-async"
  315         -
version = "1.2.5"
         315  +
version = "1.3.0"
  316    316   
dependencies = [
  317    317   
 "futures-util",
  318    318   
 "pin-project-lite",
  319    319   
 "pin-utils",
  320    320   
 "tokio",
  321    321   
 "tokio-test",
  322    322   
]
  323    323   
  324    324   
[[package]]
  325    325   
name = "aws-smithy-cbor"
@@ -586,586 +674,674 @@
  606    606   
[[package]]
  607    607   
name = "aws-smithy-query"
  608    608   
version = "0.60.7"
  609    609   
dependencies = [
  610    610   
 "aws-smithy-types",
  611    611   
 "urlencoding",
  612    612   
]
  613    613   
  614    614   
[[package]]
  615    615   
name = "aws-smithy-runtime"
  616         -
version = "1.8.4"
         616  +
version = "1.8.5"
  617    617   
dependencies = [
  618    618   
 "approx",
  619    619   
 "aws-smithy-async",
  620    620   
 "aws-smithy-http",
  621    621   
 "aws-smithy-http-client",
  622    622   
 "aws-smithy-observability",
  623    623   
 "aws-smithy-runtime-api",
  624    624   
 "aws-smithy-types",
  625    625   
 "bytes",
  626    626   
 "fastrand",
  627    627   
 "futures-util",
  628    628   
 "http 0.2.12",
  629    629   
 "http 1.3.1",
  630    630   
 "http-body 0.4.6",
  631    631   
 "http-body 1.0.1",
  632    632   
 "hyper 0.14.32",
  633    633   
 "pin-project-lite",
  634    634   
 "pin-utils",
  635    635   
 "pretty_assertions",
  636    636   
 "tokio",
  637    637   
 "tracing",
  638    638   
 "tracing-subscriber",
  639    639   
 "tracing-test",
  640    640   
]
  641    641   
  642    642   
[[package]]
  643    643   
name = "aws-smithy-runtime-api"
  644         -
version = "1.8.3"
         644  +
version = "1.8.4"
  645    645   
dependencies = [
  646    646   
 "aws-smithy-async",
  647    647   
 "aws-smithy-types",
  648    648   
 "bytes",
  649    649   
 "http 0.2.12",
  650    650   
 "http 1.3.1",
  651    651   
 "pin-project-lite",
  652    652   
 "proptest",
  653    653   
 "tokio",
  654    654   
 "tracing",

tmp-codegen-diff/codegen-client-test/aws_query/rust-client-codegen/src/config.rs

@@ -23,23 +82,86 @@
   43     43   
    }
   44     44   
    /// Return the auth schemes configured on this service config
   45     45   
    pub fn auth_schemes(&self) -> impl Iterator<Item = ::aws_smithy_runtime_api::client::auth::SharedAuthScheme> + '_ {
   46     46   
        self.runtime_components.auth_schemes()
   47     47   
    }
   48     48   
   49     49   
    /// Return the auth scheme resolver configured on this service config
   50     50   
    pub fn auth_scheme_resolver(&self) -> ::std::option::Option<::aws_smithy_runtime_api::client::auth::SharedAuthSchemeOptionResolver> {
   51     51   
        self.runtime_components.auth_scheme_option_resolver()
   52     52   
    }
          53  +
    /// Returns the configured auth scheme preference
          54  +
    pub fn auth_scheme_preference(&self) -> ::std::option::Option<&::aws_smithy_runtime_api::client::auth::AuthSchemePreference> {
          55  +
        self.config.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
          56  +
    }
   53     57   
    /// Returns the endpoint resolver.
   54     58   
    pub fn endpoint_resolver(&self) -> ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver {
   55     59   
        self.runtime_components.endpoint_resolver().expect("resolver defaulted if not set")
   56     60   
    }
   57     61   
    /// Return a reference to the retry configuration contained in this config, if any.
   58     62   
    pub fn retry_config(&self) -> ::std::option::Option<&::aws_smithy_types::retry::RetryConfig> {
   59     63   
        self.config.load::<::aws_smithy_types::retry::RetryConfig>()
   60     64   
    }
   61     65   
   62     66   
    /// Return a cloned shared async sleep implementation from this config, if any.
@@ -101,105 +160,165 @@
  121    125   
    ///
  122    126   
    pub fn new() -> Self {
  123    127   
        Self::default()
  124    128   
    }
  125    129   
    /// Constructs a config builder from the given `config_bag`, setting only fields stored in the config bag,
  126    130   
    /// but not those in runtime components.
  127    131   
    #[allow(unused)]
  128    132   
    pub(crate) fn from_config_bag(config_bag: &::aws_smithy_types::config_bag::ConfigBag) -> Self {
  129    133   
        let mut builder = Self::new();
  130    134   
        builder.set_stalled_stream_protection(config_bag.load::<crate::config::StalledStreamProtectionConfig>().cloned());
         135  +
        builder.set_auth_scheme_preference(config_bag.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>().cloned());
  131    136   
        builder.set_retry_config(config_bag.load::<::aws_smithy_types::retry::RetryConfig>().cloned());
  132    137   
        builder.set_timeout_config(config_bag.load::<::aws_smithy_types::timeout::TimeoutConfig>().cloned());
  133    138   
        builder.set_retry_partition(config_bag.load::<::aws_smithy_runtime::client::retries::RetryPartition>().cloned());
  134    139   
        builder
  135    140   
    }
  136    141   
    /// Set the [`StalledStreamProtectionConfig`](crate::config::StalledStreamProtectionConfig)
  137    142   
    /// to configure protection for stalled streams.
  138    143   
    pub fn stalled_stream_protection(mut self, stalled_stream_protection_config: crate::config::StalledStreamProtectionConfig) -> Self {
  139    144   
        self.set_stalled_stream_protection(::std::option::Option::Some(stalled_stream_protection_config));
  140    145   
        self
@@ -361,366 +420,482 @@
  381    386   
  382    387   
    /// Set the auth scheme resolver for the builder
  383    388   
    ///
  384    389   
    /// # Examples
  385    390   
    /// See an example for [`Self::auth_scheme_resolver`].
  386    391   
    pub fn set_auth_scheme_resolver(&mut self, auth_scheme_resolver: impl crate::config::auth::ResolveAuthScheme + 'static) -> &mut Self {
  387    392   
        self.runtime_components
  388    393   
            .set_auth_scheme_option_resolver(::std::option::Option::Some(auth_scheme_resolver.into_shared_resolver()));
  389    394   
        self
  390    395   
    }
         396  +
    /// Set the auth scheme preference for an auth scheme resolver
         397  +
    /// (typically the default auth scheme resolver).
         398  +
    ///
         399  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         400  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         401  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         402  +
    ///
         403  +
    /// The preference list is intended as a hint rather than a strict override.
         404  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         405  +
    ///
         406  +
    /// # Examples
         407  +
    ///
         408  +
    /// ```no_run
         409  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         410  +
    /// let config = aws_query::Config::builder()
         411  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         412  +
    ///     // ...
         413  +
    ///     .build();
         414  +
    /// let client = aws_query::Client::from_conf(config);
         415  +
    /// ```
         416  +
         417  +
    pub fn auth_scheme_preference(
         418  +
        mut self,
         419  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         420  +
    ) -> Self {
         421  +
        self.set_auth_scheme_preference(::std::option::Option::Some(preference.into()));
         422  +
        self
         423  +
    }
         424  +
         425  +
    /// Set the auth scheme preference for an auth scheme resolver
         426  +
    /// (typically the default auth scheme resolver).
         427  +
    ///
         428  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         429  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         430  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         431  +
    ///
         432  +
    /// The preference list is intended as a hint rather than a strict override.
         433  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         434  +
    ///
         435  +
    /// # Examples
         436  +
    ///
         437  +
    /// ```no_run
         438  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         439  +
    /// let config = aws_query::Config::builder()
         440  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         441  +
    ///     // ...
         442  +
    ///     .build();
         443  +
    /// let client = aws_query::Client::from_conf(config);
         444  +
    /// ```
         445  +
         446  +
    pub fn set_auth_scheme_preference(
         447  +
        &mut self,
         448  +
        preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         449  +
    ) -> &mut Self {
         450  +
        self.config.store_or_unset(preference);
         451  +
        self
         452  +
    }
  391    453   
    /// Set the endpoint URL to use when making requests.
  392    454   
    ///
  393    455   
    /// Note: setting an endpoint URL will replace any endpoint resolver that has been set.
  394    456   
    ///
  395    457   
    /// # Panics
  396    458   
    /// Panics if an invalid URL is given.
  397    459   
    pub fn endpoint_url(mut self, endpoint_url: impl ::std::convert::Into<::std::string::String>) -> Self {
  398    460   
        self.set_endpoint_url(::std::option::Option::Some(endpoint_url.into()));
  399    461   
        self
  400    462   
    }
@@ -1126,1188 +1186,1258 @@
 1146   1208   
    pub fn new(_service_config: crate::config::Config) -> Self {
 1147   1209   
        let config = {
 1148   1210   
            let mut cfg = ::aws_smithy_types::config_bag::Layer::new("AwsQuery");
 1149   1211   
            cfg.store_put(crate::idempotency_token::default_provider());
 1150   1212   
            cfg.store_put(::aws_smithy_runtime::client::orchestrator::AuthSchemeAndEndpointOrchestrationV2);
 1151   1213   
            ::std::option::Option::Some(cfg.freeze())
 1152   1214   
        };
 1153   1215   
        let mut runtime_components = ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder::new("ServiceRuntimePlugin");
 1154   1216   
        runtime_components.set_auth_scheme_option_resolver(::std::option::Option::Some({
 1155   1217   
            use crate::config::auth::ResolveAuthScheme;
        1218  +
            if let Some(preference) = _service_config
        1219  +
                .config
        1220  +
                .load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
        1221  +
                .cloned()
        1222  +
            {
        1223  +
                crate::config::auth::DefaultAuthSchemeResolver::default()
        1224  +
                    .with_auth_scheme_preference(preference)
        1225  +
                    .into_shared_resolver()
        1226  +
            } else {
 1156   1227   
                crate::config::auth::DefaultAuthSchemeResolver::default().into_shared_resolver()
        1228  +
            }
 1157   1229   
        }));
 1158   1230   
        runtime_components.push_interceptor(::aws_smithy_runtime::client::http::connection_poisoning::ConnectionPoisoningInterceptor::new());
 1159   1231   
        runtime_components.push_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::HttpStatusCodeClassifier::default());
 1160   1232   
        runtime_components.push_interceptor(crate::sdk_feature_tracker::retry_mode::RetryModeFeatureTrackerInterceptor::new());
 1161   1233   
        Self { config, runtime_components }
 1162   1234   
    }
 1163   1235   
}
 1164   1236   
 1165   1237   
impl ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin for ServiceRuntimePlugin {
 1166   1238   
    fn config(&self) -> ::std::option::Option<::aws_smithy_types::config_bag::FrozenLayer> {

tmp-codegen-diff/codegen-client-test/aws_query/rust-client-codegen/src/config/auth.rs

@@ -18,18 +110,140 @@
   38     38   
        }
   39     39   
    }
   40     40   
}
   41     41   
   42     42   
/// The default auth scheme resolver
   43     43   
#[derive(Debug)]
   44     44   
#[allow(dead_code)]
   45     45   
pub struct DefaultAuthSchemeResolver {
   46     46   
    service_defaults: Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>,
   47     47   
    operation_overrides: ::std::collections::HashMap<&'static str, Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>>,
          48  +
    preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
   48     49   
}
   49     50   
   50     51   
// TODO(https://github.com/smithy-lang/smithy-rs/issues/4177): Remove `allow(...)` once the issue is addressed.
   51     52   
// When generating code for tests (e.g., `codegen-client-test`), this manual implementation
   52     53   
// of the `Default` trait may appear as if it could be derived automatically.
   53     54   
// However, that is not the case in production.
   54     55   
#[allow(clippy::derivable_impls)]
   55     56   
impl Default for DefaultAuthSchemeResolver {
   56     57   
    fn default() -> Self {
   57     58   
        Self {
   58     59   
            service_defaults: vec![],
   59     60   
            operation_overrides: ::std::collections::HashMap::new(),
          61  +
            preference: ::std::option::Option::None,
   60     62   
        }
   61     63   
    }
   62     64   
}
   63     65   
   64     66   
impl crate::config::auth::ResolveAuthScheme for DefaultAuthSchemeResolver {
   65     67   
    fn resolve_auth_scheme<'a>(
   66     68   
        &'a self,
   67     69   
        params: &'a crate::config::auth::Params,
   68     70   
        _cfg: &'a ::aws_smithy_types::config_bag::ConfigBag,
   69     71   
        _runtime_components: &'a ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponents,
   70     72   
    ) -> ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture<'a> {
   71     73   
        let operation_name = params.operation_name();
   72     74   
   73     75   
        let modeled_auth_options = match self.operation_overrides.get(operation_name) {
   74     76   
            Some(overrides) => overrides,
   75     77   
            None => &self.service_defaults,
   76     78   
        };
   77     79   
   78     80   
        let _fut = ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture::ready(Ok(modeled_auth_options.clone()));
   79     81   
   80         -
        _fut
          82  +
        match &self.preference {
          83  +
            ::std::option::Option::Some(preference) => {
          84  +
                _fut.map_ok({
          85  +
                    // maps auth scheme ID to the index in the preference list
          86  +
                    let preference_map: ::std::collections::HashMap<_, _> = preference.clone().into_iter().enumerate().map(|(i, s)| (s, i)).collect();
          87  +
                    move |auth_scheme_options| {
          88  +
                        let (mut preferred, non_preferred): (::std::vec::Vec<_>, ::std::vec::Vec<_>) = auth_scheme_options
          89  +
                            .into_iter()
          90  +
                            .partition(|auth_scheme_option| preference_map.contains_key(auth_scheme_option.scheme_id()));
          91  +
          92  +
                        preferred.sort_by_key(|opt| preference_map.get(opt.scheme_id()).expect("guaranteed by `partition`"));
          93  +
                        preferred.extend(non_preferred);
          94  +
                        preferred
          95  +
                    }
          96  +
                })
          97  +
            }
          98  +
            ::std::option::Option::None => _fut,
          99  +
        }
         100  +
    }
         101  +
}
         102  +
         103  +
impl DefaultAuthSchemeResolver {
         104  +
    /// Set auth scheme preference to the default auth scheme resolver
         105  +
    pub fn with_auth_scheme_preference(
         106  +
        mut self,
         107  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         108  +
    ) -> Self {
         109  +
        self.preference = ::std::option::Option::Some(preference.into());
         110  +
        self
   81    111   
    }
   82    112   
}
   83    113   
   84    114   
/// Configuration parameters for resolving the correct auth scheme
   85    115   
#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]
   86    116   
pub struct Params {
   87    117   
    operation_name: ::std::borrow::Cow<'static, str>,
   88    118   
}
   89    119   
impl Params {
   90    120   
    /// Create a builder for [`Params`]

tmp-codegen-diff/codegen-client-test/dynamo/rust-client-codegen/src/config.rs

@@ -23,23 +82,86 @@
   43     43   
    }
   44     44   
    /// Return the auth schemes configured on this service config
   45     45   
    pub fn auth_schemes(&self) -> impl Iterator<Item = ::aws_smithy_runtime_api::client::auth::SharedAuthScheme> + '_ {
   46     46   
        self.runtime_components.auth_schemes()
   47     47   
    }
   48     48   
   49     49   
    /// Return the auth scheme resolver configured on this service config
   50     50   
    pub fn auth_scheme_resolver(&self) -> ::std::option::Option<::aws_smithy_runtime_api::client::auth::SharedAuthSchemeOptionResolver> {
   51     51   
        self.runtime_components.auth_scheme_option_resolver()
   52     52   
    }
          53  +
    /// Returns the configured auth scheme preference
          54  +
    pub fn auth_scheme_preference(&self) -> ::std::option::Option<&::aws_smithy_runtime_api::client::auth::AuthSchemePreference> {
          55  +
        self.config.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
          56  +
    }
   53     57   
    /// Returns the endpoint resolver.
   54     58   
    pub fn endpoint_resolver(&self) -> ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver {
   55     59   
        self.runtime_components.endpoint_resolver().expect("resolver defaulted if not set")
   56     60   
    }
   57     61   
    /// Return a reference to the retry configuration contained in this config, if any.
   58     62   
    pub fn retry_config(&self) -> ::std::option::Option<&::aws_smithy_types::retry::RetryConfig> {
   59     63   
        self.config.load::<::aws_smithy_types::retry::RetryConfig>()
   60     64   
    }
   61     65   
   62     66   
    /// Return a cloned shared async sleep implementation from this config, if any.
@@ -101,105 +160,165 @@
  121    125   
    ///
  122    126   
    pub fn new() -> Self {
  123    127   
        Self::default()
  124    128   
    }
  125    129   
    /// Constructs a config builder from the given `config_bag`, setting only fields stored in the config bag,
  126    130   
    /// but not those in runtime components.
  127    131   
    #[allow(unused)]
  128    132   
    pub(crate) fn from_config_bag(config_bag: &::aws_smithy_types::config_bag::ConfigBag) -> Self {
  129    133   
        let mut builder = Self::new();
  130    134   
        builder.set_stalled_stream_protection(config_bag.load::<crate::config::StalledStreamProtectionConfig>().cloned());
         135  +
        builder.set_auth_scheme_preference(config_bag.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>().cloned());
  131    136   
        builder.set_retry_config(config_bag.load::<::aws_smithy_types::retry::RetryConfig>().cloned());
  132    137   
        builder.set_timeout_config(config_bag.load::<::aws_smithy_types::timeout::TimeoutConfig>().cloned());
  133    138   
        builder.set_retry_partition(config_bag.load::<::aws_smithy_runtime::client::retries::RetryPartition>().cloned());
  134    139   
        builder
  135    140   
    }
  136    141   
    /// Set the [`StalledStreamProtectionConfig`](crate::config::StalledStreamProtectionConfig)
  137    142   
    /// to configure protection for stalled streams.
  138    143   
    pub fn stalled_stream_protection(mut self, stalled_stream_protection_config: crate::config::StalledStreamProtectionConfig) -> Self {
  139    144   
        self.set_stalled_stream_protection(::std::option::Option::Some(stalled_stream_protection_config));
  140    145   
        self
@@ -361,366 +420,482 @@
  381    386   
  382    387   
    /// Set the auth scheme resolver for the builder
  383    388   
    ///
  384    389   
    /// # Examples
  385    390   
    /// See an example for [`Self::auth_scheme_resolver`].
  386    391   
    pub fn set_auth_scheme_resolver(&mut self, auth_scheme_resolver: impl crate::config::auth::ResolveAuthScheme + 'static) -> &mut Self {
  387    392   
        self.runtime_components
  388    393   
            .set_auth_scheme_option_resolver(::std::option::Option::Some(auth_scheme_resolver.into_shared_resolver()));
  389    394   
        self
  390    395   
    }
         396  +
    /// Set the auth scheme preference for an auth scheme resolver
         397  +
    /// (typically the default auth scheme resolver).
         398  +
    ///
         399  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         400  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         401  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         402  +
    ///
         403  +
    /// The preference list is intended as a hint rather than a strict override.
         404  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         405  +
    ///
         406  +
    /// # Examples
         407  +
    ///
         408  +
    /// ```no_run
         409  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         410  +
    /// let config = dynamo::Config::builder()
         411  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         412  +
    ///     // ...
         413  +
    ///     .build();
         414  +
    /// let client = dynamo::Client::from_conf(config);
         415  +
    /// ```
         416  +
         417  +
    pub fn auth_scheme_preference(
         418  +
        mut self,
         419  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         420  +
    ) -> Self {
         421  +
        self.set_auth_scheme_preference(::std::option::Option::Some(preference.into()));
         422  +
        self
         423  +
    }
         424  +
         425  +
    /// Set the auth scheme preference for an auth scheme resolver
         426  +
    /// (typically the default auth scheme resolver).
         427  +
    ///
         428  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         429  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         430  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         431  +
    ///
         432  +
    /// The preference list is intended as a hint rather than a strict override.
         433  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         434  +
    ///
         435  +
    /// # Examples
         436  +
    ///
         437  +
    /// ```no_run
         438  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         439  +
    /// let config = dynamo::Config::builder()
         440  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         441  +
    ///     // ...
         442  +
    ///     .build();
         443  +
    /// let client = dynamo::Client::from_conf(config);
         444  +
    /// ```
         445  +
         446  +
    pub fn set_auth_scheme_preference(
         447  +
        &mut self,
         448  +
        preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         449  +
    ) -> &mut Self {
         450  +
        self.config.store_or_unset(preference);
         451  +
        self
         452  +
    }
  391    453   
    /// Set the endpoint URL to use when making requests.
  392    454   
    ///
  393    455   
    /// Note: setting an endpoint URL will replace any endpoint resolver that has been set.
  394    456   
    ///
  395    457   
    /// # Panics
  396    458   
    /// Panics if an invalid URL is given.
  397    459   
    pub fn endpoint_url(mut self, endpoint_url: impl ::std::convert::Into<::std::string::String>) -> Self {
  398    460   
        self.set_endpoint_url(::std::option::Option::Some(endpoint_url.into()));
  399    461   
        self
  400    462   
    }
@@ -1126,1188 +1186,1258 @@
 1146   1208   
    pub fn new(_service_config: crate::config::Config) -> Self {
 1147   1209   
        let config = {
 1148   1210   
            let mut cfg = ::aws_smithy_types::config_bag::Layer::new("DynamoDB_20120810");
 1149   1211   
            cfg.store_put(crate::idempotency_token::default_provider());
 1150   1212   
            cfg.store_put(::aws_smithy_runtime::client::orchestrator::AuthSchemeAndEndpointOrchestrationV2);
 1151   1213   
            ::std::option::Option::Some(cfg.freeze())
 1152   1214   
        };
 1153   1215   
        let mut runtime_components = ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder::new("ServiceRuntimePlugin");
 1154   1216   
        runtime_components.set_auth_scheme_option_resolver(::std::option::Option::Some({
 1155   1217   
            use crate::config::auth::ResolveAuthScheme;
        1218  +
            if let Some(preference) = _service_config
        1219  +
                .config
        1220  +
                .load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
        1221  +
                .cloned()
        1222  +
            {
        1223  +
                crate::config::auth::DefaultAuthSchemeResolver::default()
        1224  +
                    .with_auth_scheme_preference(preference)
        1225  +
                    .into_shared_resolver()
        1226  +
            } else {
 1156   1227   
                crate::config::auth::DefaultAuthSchemeResolver::default().into_shared_resolver()
        1228  +
            }
 1157   1229   
        }));
 1158   1230   
        runtime_components.push_interceptor(::aws_smithy_runtime::client::http::connection_poisoning::ConnectionPoisoningInterceptor::new());
 1159   1231   
        runtime_components.push_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::HttpStatusCodeClassifier::default());
 1160   1232   
        runtime_components.push_interceptor(crate::sdk_feature_tracker::retry_mode::RetryModeFeatureTrackerInterceptor::new());
 1161   1233   
        Self { config, runtime_components }
 1162   1234   
    }
 1163   1235   
}
 1164   1236   
 1165   1237   
impl ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin for ServiceRuntimePlugin {
 1166   1238   
    fn config(&self) -> ::std::option::Option<::aws_smithy_types::config_bag::FrozenLayer> {

tmp-codegen-diff/codegen-client-test/dynamo/rust-client-codegen/src/config/auth.rs

@@ -18,18 +110,140 @@
   38     38   
        }
   39     39   
    }
   40     40   
}
   41     41   
   42     42   
/// The default auth scheme resolver
   43     43   
#[derive(Debug)]
   44     44   
#[allow(dead_code)]
   45     45   
pub struct DefaultAuthSchemeResolver {
   46     46   
    service_defaults: Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>,
   47     47   
    operation_overrides: ::std::collections::HashMap<&'static str, Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>>,
          48  +
    preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
   48     49   
}
   49     50   
   50     51   
// TODO(https://github.com/smithy-lang/smithy-rs/issues/4177): Remove `allow(...)` once the issue is addressed.
   51     52   
// When generating code for tests (e.g., `codegen-client-test`), this manual implementation
   52     53   
// of the `Default` trait may appear as if it could be derived automatically.
   53     54   
// However, that is not the case in production.
   54     55   
#[allow(clippy::derivable_impls)]
   55     56   
impl Default for DefaultAuthSchemeResolver {
   56     57   
    fn default() -> Self {
   57     58   
        Self {
   58     59   
            service_defaults: vec![],
   59     60   
            operation_overrides: ::std::collections::HashMap::new(),
          61  +
            preference: ::std::option::Option::None,
   60     62   
        }
   61     63   
    }
   62     64   
}
   63     65   
   64     66   
impl crate::config::auth::ResolveAuthScheme for DefaultAuthSchemeResolver {
   65     67   
    fn resolve_auth_scheme<'a>(
   66     68   
        &'a self,
   67     69   
        params: &'a crate::config::auth::Params,
   68     70   
        _cfg: &'a ::aws_smithy_types::config_bag::ConfigBag,
   69     71   
        _runtime_components: &'a ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponents,
   70     72   
    ) -> ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture<'a> {
   71     73   
        let operation_name = params.operation_name();
   72     74   
   73     75   
        let modeled_auth_options = match self.operation_overrides.get(operation_name) {
   74     76   
            Some(overrides) => overrides,
   75     77   
            None => &self.service_defaults,
   76     78   
        };
   77     79   
   78     80   
        let _fut = ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture::ready(Ok(modeled_auth_options.clone()));
   79     81   
   80         -
        _fut
          82  +
        match &self.preference {
          83  +
            ::std::option::Option::Some(preference) => {
          84  +
                _fut.map_ok({
          85  +
                    // maps auth scheme ID to the index in the preference list
          86  +
                    let preference_map: ::std::collections::HashMap<_, _> = preference.clone().into_iter().enumerate().map(|(i, s)| (s, i)).collect();
          87  +
                    move |auth_scheme_options| {
          88  +
                        let (mut preferred, non_preferred): (::std::vec::Vec<_>, ::std::vec::Vec<_>) = auth_scheme_options
          89  +
                            .into_iter()
          90  +
                            .partition(|auth_scheme_option| preference_map.contains_key(auth_scheme_option.scheme_id()));
          91  +
          92  +
                        preferred.sort_by_key(|opt| preference_map.get(opt.scheme_id()).expect("guaranteed by `partition`"));
          93  +
                        preferred.extend(non_preferred);
          94  +
                        preferred
          95  +
                    }
          96  +
                })
          97  +
            }
          98  +
            ::std::option::Option::None => _fut,
          99  +
        }
         100  +
    }
         101  +
}
         102  +
         103  +
impl DefaultAuthSchemeResolver {
         104  +
    /// Set auth scheme preference to the default auth scheme resolver
         105  +
    pub fn with_auth_scheme_preference(
         106  +
        mut self,
         107  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         108  +
    ) -> Self {
         109  +
        self.preference = ::std::option::Option::Some(preference.into());
         110  +
        self
   81    111   
    }
   82    112   
}
   83    113   
   84    114   
/// Configuration parameters for resolving the correct auth scheme
   85    115   
#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]
   86    116   
pub struct Params {
   87    117   
    operation_name: ::std::borrow::Cow<'static, str>,
   88    118   
}
   89    119   
impl Params {
   90    120   
    /// Create a builder for [`Params`]

tmp-codegen-diff/codegen-client-test/ebs/rust-client-codegen/src/config.rs

@@ -23,23 +82,86 @@
   43     43   
    }
   44     44   
    /// Return the auth schemes configured on this service config
   45     45   
    pub fn auth_schemes(&self) -> impl Iterator<Item = ::aws_smithy_runtime_api::client::auth::SharedAuthScheme> + '_ {
   46     46   
        self.runtime_components.auth_schemes()
   47     47   
    }
   48     48   
   49     49   
    /// Return the auth scheme resolver configured on this service config
   50     50   
    pub fn auth_scheme_resolver(&self) -> ::std::option::Option<::aws_smithy_runtime_api::client::auth::SharedAuthSchemeOptionResolver> {
   51     51   
        self.runtime_components.auth_scheme_option_resolver()
   52     52   
    }
          53  +
    /// Returns the configured auth scheme preference
          54  +
    pub fn auth_scheme_preference(&self) -> ::std::option::Option<&::aws_smithy_runtime_api::client::auth::AuthSchemePreference> {
          55  +
        self.config.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
          56  +
    }
   53     57   
    /// Returns the endpoint resolver.
   54     58   
    pub fn endpoint_resolver(&self) -> ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver {
   55     59   
        self.runtime_components.endpoint_resolver().expect("resolver defaulted if not set")
   56     60   
    }
   57     61   
    /// Return a reference to the retry configuration contained in this config, if any.
   58     62   
    pub fn retry_config(&self) -> ::std::option::Option<&::aws_smithy_types::retry::RetryConfig> {
   59     63   
        self.config.load::<::aws_smithy_types::retry::RetryConfig>()
   60     64   
    }
   61     65   
   62     66   
    /// Return a cloned shared async sleep implementation from this config, if any.
@@ -101,105 +160,165 @@
  121    125   
    ///
  122    126   
    pub fn new() -> Self {
  123    127   
        Self::default()
  124    128   
    }
  125    129   
    /// Constructs a config builder from the given `config_bag`, setting only fields stored in the config bag,
  126    130   
    /// but not those in runtime components.
  127    131   
    #[allow(unused)]
  128    132   
    pub(crate) fn from_config_bag(config_bag: &::aws_smithy_types::config_bag::ConfigBag) -> Self {
  129    133   
        let mut builder = Self::new();
  130    134   
        builder.set_stalled_stream_protection(config_bag.load::<crate::config::StalledStreamProtectionConfig>().cloned());
         135  +
        builder.set_auth_scheme_preference(config_bag.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>().cloned());
  131    136   
        builder.set_retry_config(config_bag.load::<::aws_smithy_types::retry::RetryConfig>().cloned());
  132    137   
        builder.set_timeout_config(config_bag.load::<::aws_smithy_types::timeout::TimeoutConfig>().cloned());
  133    138   
        builder.set_retry_partition(config_bag.load::<::aws_smithy_runtime::client::retries::RetryPartition>().cloned());
  134    139   
        builder
  135    140   
    }
  136    141   
    /// Set the [`StalledStreamProtectionConfig`](crate::config::StalledStreamProtectionConfig)
  137    142   
    /// to configure protection for stalled streams.
  138    143   
    pub fn stalled_stream_protection(mut self, stalled_stream_protection_config: crate::config::StalledStreamProtectionConfig) -> Self {
  139    144   
        self.set_stalled_stream_protection(::std::option::Option::Some(stalled_stream_protection_config));
  140    145   
        self
@@ -361,366 +420,482 @@
  381    386   
  382    387   
    /// Set the auth scheme resolver for the builder
  383    388   
    ///
  384    389   
    /// # Examples
  385    390   
    /// See an example for [`Self::auth_scheme_resolver`].
  386    391   
    pub fn set_auth_scheme_resolver(&mut self, auth_scheme_resolver: impl crate::config::auth::ResolveAuthScheme + 'static) -> &mut Self {
  387    392   
        self.runtime_components
  388    393   
            .set_auth_scheme_option_resolver(::std::option::Option::Some(auth_scheme_resolver.into_shared_resolver()));
  389    394   
        self
  390    395   
    }
         396  +
    /// Set the auth scheme preference for an auth scheme resolver
         397  +
    /// (typically the default auth scheme resolver).
         398  +
    ///
         399  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         400  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         401  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         402  +
    ///
         403  +
    /// The preference list is intended as a hint rather than a strict override.
         404  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         405  +
    ///
         406  +
    /// # Examples
         407  +
    ///
         408  +
    /// ```no_run
         409  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         410  +
    /// let config = ebs::Config::builder()
         411  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         412  +
    ///     // ...
         413  +
    ///     .build();
         414  +
    /// let client = ebs::Client::from_conf(config);
         415  +
    /// ```
         416  +
         417  +
    pub fn auth_scheme_preference(
         418  +
        mut self,
         419  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         420  +
    ) -> Self {
         421  +
        self.set_auth_scheme_preference(::std::option::Option::Some(preference.into()));
         422  +
        self
         423  +
    }
         424  +
         425  +
    /// Set the auth scheme preference for an auth scheme resolver
         426  +
    /// (typically the default auth scheme resolver).
         427  +
    ///
         428  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         429  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         430  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         431  +
    ///
         432  +
    /// The preference list is intended as a hint rather than a strict override.
         433  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         434  +
    ///
         435  +
    /// # Examples
         436  +
    ///
         437  +
    /// ```no_run
         438  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         439  +
    /// let config = ebs::Config::builder()
         440  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         441  +
    ///     // ...
         442  +
    ///     .build();
         443  +
    /// let client = ebs::Client::from_conf(config);
         444  +
    /// ```
         445  +
         446  +
    pub fn set_auth_scheme_preference(
         447  +
        &mut self,
         448  +
        preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         449  +
    ) -> &mut Self {
         450  +
        self.config.store_or_unset(preference);
         451  +
        self
         452  +
    }
  391    453   
    /// Set the endpoint URL to use when making requests.
  392    454   
    ///
  393    455   
    /// Note: setting an endpoint URL will replace any endpoint resolver that has been set.
  394    456   
    ///
  395    457   
    /// # Panics
  396    458   
    /// Panics if an invalid URL is given.
  397    459   
    pub fn endpoint_url(mut self, endpoint_url: impl ::std::convert::Into<::std::string::String>) -> Self {
  398    460   
        self.set_endpoint_url(::std::option::Option::Some(endpoint_url.into()));
  399    461   
        self
  400    462   
    }
@@ -1126,1188 +1186,1258 @@
 1146   1208   
    pub fn new(_service_config: crate::config::Config) -> Self {
 1147   1209   
        let config = {
 1148   1210   
            let mut cfg = ::aws_smithy_types::config_bag::Layer::new("Ebs");
 1149   1211   
            cfg.store_put(crate::idempotency_token::default_provider());
 1150   1212   
            cfg.store_put(::aws_smithy_runtime::client::orchestrator::AuthSchemeAndEndpointOrchestrationV2);
 1151   1213   
            ::std::option::Option::Some(cfg.freeze())
 1152   1214   
        };
 1153   1215   
        let mut runtime_components = ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder::new("ServiceRuntimePlugin");
 1154   1216   
        runtime_components.set_auth_scheme_option_resolver(::std::option::Option::Some({
 1155   1217   
            use crate::config::auth::ResolveAuthScheme;
        1218  +
            if let Some(preference) = _service_config
        1219  +
                .config
        1220  +
                .load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
        1221  +
                .cloned()
        1222  +
            {
        1223  +
                crate::config::auth::DefaultAuthSchemeResolver::default()
        1224  +
                    .with_auth_scheme_preference(preference)
        1225  +
                    .into_shared_resolver()
        1226  +
            } else {
 1156   1227   
                crate::config::auth::DefaultAuthSchemeResolver::default().into_shared_resolver()
        1228  +
            }
 1157   1229   
        }));
 1158   1230   
        runtime_components.push_interceptor(::aws_smithy_runtime::client::http::connection_poisoning::ConnectionPoisoningInterceptor::new());
 1159   1231   
        runtime_components.push_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::HttpStatusCodeClassifier::default());
 1160   1232   
        runtime_components.push_interceptor(crate::sdk_feature_tracker::retry_mode::RetryModeFeatureTrackerInterceptor::new());
 1161   1233   
        Self { config, runtime_components }
 1162   1234   
    }
 1163   1235   
}
 1164   1236   
 1165   1237   
impl ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin for ServiceRuntimePlugin {
 1166   1238   
    fn config(&self) -> ::std::option::Option<::aws_smithy_types::config_bag::FrozenLayer> {

tmp-codegen-diff/codegen-client-test/ebs/rust-client-codegen/src/config/auth.rs

@@ -18,18 +110,140 @@
   38     38   
        }
   39     39   
    }
   40     40   
}
   41     41   
   42     42   
/// The default auth scheme resolver
   43     43   
#[derive(Debug)]
   44     44   
#[allow(dead_code)]
   45     45   
pub struct DefaultAuthSchemeResolver {
   46     46   
    service_defaults: Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>,
   47     47   
    operation_overrides: ::std::collections::HashMap<&'static str, Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>>,
          48  +
    preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
   48     49   
}
   49     50   
   50     51   
// TODO(https://github.com/smithy-lang/smithy-rs/issues/4177): Remove `allow(...)` once the issue is addressed.
   51     52   
// When generating code for tests (e.g., `codegen-client-test`), this manual implementation
   52     53   
// of the `Default` trait may appear as if it could be derived automatically.
   53     54   
// However, that is not the case in production.
   54     55   
#[allow(clippy::derivable_impls)]
   55     56   
impl Default for DefaultAuthSchemeResolver {
   56     57   
    fn default() -> Self {
   57     58   
        Self {
   58     59   
            service_defaults: vec![],
   59     60   
            operation_overrides: [].into(),
          61  +
            preference: ::std::option::Option::None,
   60     62   
        }
   61     63   
    }
   62     64   
}
   63     65   
   64     66   
impl crate::config::auth::ResolveAuthScheme for DefaultAuthSchemeResolver {
   65     67   
    fn resolve_auth_scheme<'a>(
   66     68   
        &'a self,
   67     69   
        params: &'a crate::config::auth::Params,
   68     70   
        _cfg: &'a ::aws_smithy_types::config_bag::ConfigBag,
   69     71   
        _runtime_components: &'a ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponents,
   70     72   
    ) -> ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture<'a> {
   71     73   
        let operation_name = params.operation_name();
   72     74   
   73     75   
        let modeled_auth_options = match self.operation_overrides.get(operation_name) {
   74     76   
            Some(overrides) => overrides,
   75     77   
            None => &self.service_defaults,
   76     78   
        };
   77     79   
   78     80   
        let _fut = ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture::ready(Ok(modeled_auth_options.clone()));
   79     81   
   80         -
        _fut
          82  +
        match &self.preference {
          83  +
            ::std::option::Option::Some(preference) => {
          84  +
                _fut.map_ok({
          85  +
                    // maps auth scheme ID to the index in the preference list
          86  +
                    let preference_map: ::std::collections::HashMap<_, _> = preference.clone().into_iter().enumerate().map(|(i, s)| (s, i)).collect();
          87  +
                    move |auth_scheme_options| {
          88  +
                        let (mut preferred, non_preferred): (::std::vec::Vec<_>, ::std::vec::Vec<_>) = auth_scheme_options
          89  +
                            .into_iter()
          90  +
                            .partition(|auth_scheme_option| preference_map.contains_key(auth_scheme_option.scheme_id()));
          91  +
          92  +
                        preferred.sort_by_key(|opt| preference_map.get(opt.scheme_id()).expect("guaranteed by `partition`"));
          93  +
                        preferred.extend(non_preferred);
          94  +
                        preferred
          95  +
                    }
          96  +
                })
          97  +
            }
          98  +
            ::std::option::Option::None => _fut,
          99  +
        }
         100  +
    }
         101  +
}
         102  +
         103  +
impl DefaultAuthSchemeResolver {
         104  +
    /// Set auth scheme preference to the default auth scheme resolver
         105  +
    pub fn with_auth_scheme_preference(
         106  +
        mut self,
         107  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         108  +
    ) -> Self {
         109  +
        self.preference = ::std::option::Option::Some(preference.into());
         110  +
        self
   81    111   
    }
   82    112   
}
   83    113   
   84    114   
/// Configuration parameters for resolving the correct auth scheme
   85    115   
#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]
   86    116   
pub struct Params {
   87    117   
    operation_name: ::std::borrow::Cow<'static, str>,
   88    118   
}
   89    119   
impl Params {
   90    120   
    /// Create a builder for [`Params`]

tmp-codegen-diff/codegen-client-test/ec2_query/rust-client-codegen/src/config.rs

@@ -23,23 +82,86 @@
   43     43   
    }
   44     44   
    /// Return the auth schemes configured on this service config
   45     45   
    pub fn auth_schemes(&self) -> impl Iterator<Item = ::aws_smithy_runtime_api::client::auth::SharedAuthScheme> + '_ {
   46     46   
        self.runtime_components.auth_schemes()
   47     47   
    }
   48     48   
   49     49   
    /// Return the auth scheme resolver configured on this service config
   50     50   
    pub fn auth_scheme_resolver(&self) -> ::std::option::Option<::aws_smithy_runtime_api::client::auth::SharedAuthSchemeOptionResolver> {
   51     51   
        self.runtime_components.auth_scheme_option_resolver()
   52     52   
    }
          53  +
    /// Returns the configured auth scheme preference
          54  +
    pub fn auth_scheme_preference(&self) -> ::std::option::Option<&::aws_smithy_runtime_api::client::auth::AuthSchemePreference> {
          55  +
        self.config.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
          56  +
    }
   53     57   
    /// Returns the endpoint resolver.
   54     58   
    pub fn endpoint_resolver(&self) -> ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver {
   55     59   
        self.runtime_components.endpoint_resolver().expect("resolver defaulted if not set")
   56     60   
    }
   57     61   
    /// Return a reference to the retry configuration contained in this config, if any.
   58     62   
    pub fn retry_config(&self) -> ::std::option::Option<&::aws_smithy_types::retry::RetryConfig> {
   59     63   
        self.config.load::<::aws_smithy_types::retry::RetryConfig>()
   60     64   
    }
   61     65   
   62     66   
    /// Return a cloned shared async sleep implementation from this config, if any.
@@ -101,105 +160,165 @@
  121    125   
    ///
  122    126   
    pub fn new() -> Self {
  123    127   
        Self::default()
  124    128   
    }
  125    129   
    /// Constructs a config builder from the given `config_bag`, setting only fields stored in the config bag,
  126    130   
    /// but not those in runtime components.
  127    131   
    #[allow(unused)]
  128    132   
    pub(crate) fn from_config_bag(config_bag: &::aws_smithy_types::config_bag::ConfigBag) -> Self {
  129    133   
        let mut builder = Self::new();
  130    134   
        builder.set_stalled_stream_protection(config_bag.load::<crate::config::StalledStreamProtectionConfig>().cloned());
         135  +
        builder.set_auth_scheme_preference(config_bag.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>().cloned());
  131    136   
        builder.set_retry_config(config_bag.load::<::aws_smithy_types::retry::RetryConfig>().cloned());
  132    137   
        builder.set_timeout_config(config_bag.load::<::aws_smithy_types::timeout::TimeoutConfig>().cloned());
  133    138   
        builder.set_retry_partition(config_bag.load::<::aws_smithy_runtime::client::retries::RetryPartition>().cloned());
  134    139   
        builder
  135    140   
    }
  136    141   
    /// Set the [`StalledStreamProtectionConfig`](crate::config::StalledStreamProtectionConfig)
  137    142   
    /// to configure protection for stalled streams.
  138    143   
    pub fn stalled_stream_protection(mut self, stalled_stream_protection_config: crate::config::StalledStreamProtectionConfig) -> Self {
  139    144   
        self.set_stalled_stream_protection(::std::option::Option::Some(stalled_stream_protection_config));
  140    145   
        self
@@ -361,366 +420,482 @@
  381    386   
  382    387   
    /// Set the auth scheme resolver for the builder
  383    388   
    ///
  384    389   
    /// # Examples
  385    390   
    /// See an example for [`Self::auth_scheme_resolver`].
  386    391   
    pub fn set_auth_scheme_resolver(&mut self, auth_scheme_resolver: impl crate::config::auth::ResolveAuthScheme + 'static) -> &mut Self {
  387    392   
        self.runtime_components
  388    393   
            .set_auth_scheme_option_resolver(::std::option::Option::Some(auth_scheme_resolver.into_shared_resolver()));
  389    394   
        self
  390    395   
    }
         396  +
    /// Set the auth scheme preference for an auth scheme resolver
         397  +
    /// (typically the default auth scheme resolver).
         398  +
    ///
         399  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         400  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         401  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         402  +
    ///
         403  +
    /// The preference list is intended as a hint rather than a strict override.
         404  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         405  +
    ///
         406  +
    /// # Examples
         407  +
    ///
         408  +
    /// ```no_run
         409  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         410  +
    /// let config = ec2_query::Config::builder()
         411  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         412  +
    ///     // ...
         413  +
    ///     .build();
         414  +
    /// let client = ec2_query::Client::from_conf(config);
         415  +
    /// ```
         416  +
         417  +
    pub fn auth_scheme_preference(
         418  +
        mut self,
         419  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         420  +
    ) -> Self {
         421  +
        self.set_auth_scheme_preference(::std::option::Option::Some(preference.into()));
         422  +
        self
         423  +
    }
         424  +
         425  +
    /// Set the auth scheme preference for an auth scheme resolver
         426  +
    /// (typically the default auth scheme resolver).
         427  +
    ///
         428  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         429  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         430  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         431  +
    ///
         432  +
    /// The preference list is intended as a hint rather than a strict override.
         433  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         434  +
    ///
         435  +
    /// # Examples
         436  +
    ///
         437  +
    /// ```no_run
         438  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         439  +
    /// let config = ec2_query::Config::builder()
         440  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         441  +
    ///     // ...
         442  +
    ///     .build();
         443  +
    /// let client = ec2_query::Client::from_conf(config);
         444  +
    /// ```
         445  +
         446  +
    pub fn set_auth_scheme_preference(
         447  +
        &mut self,
         448  +
        preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         449  +
    ) -> &mut Self {
         450  +
        self.config.store_or_unset(preference);
         451  +
        self
         452  +
    }
  391    453   
    /// Set the endpoint URL to use when making requests.
  392    454   
    ///
  393    455   
    /// Note: setting an endpoint URL will replace any endpoint resolver that has been set.
  394    456   
    ///
  395    457   
    /// # Panics
  396    458   
    /// Panics if an invalid URL is given.
  397    459   
    pub fn endpoint_url(mut self, endpoint_url: impl ::std::convert::Into<::std::string::String>) -> Self {
  398    460   
        self.set_endpoint_url(::std::option::Option::Some(endpoint_url.into()));
  399    461   
        self
  400    462   
    }
@@ -1126,1188 +1186,1258 @@
 1146   1208   
    pub fn new(_service_config: crate::config::Config) -> Self {
 1147   1209   
        let config = {
 1148   1210   
            let mut cfg = ::aws_smithy_types::config_bag::Layer::new("AwsEc2");
 1149   1211   
            cfg.store_put(crate::idempotency_token::default_provider());
 1150   1212   
            cfg.store_put(::aws_smithy_runtime::client::orchestrator::AuthSchemeAndEndpointOrchestrationV2);
 1151   1213   
            ::std::option::Option::Some(cfg.freeze())
 1152   1214   
        };
 1153   1215   
        let mut runtime_components = ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder::new("ServiceRuntimePlugin");
 1154   1216   
        runtime_components.set_auth_scheme_option_resolver(::std::option::Option::Some({
 1155   1217   
            use crate::config::auth::ResolveAuthScheme;
        1218  +
            if let Some(preference) = _service_config
        1219  +
                .config
        1220  +
                .load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
        1221  +
                .cloned()
        1222  +
            {
        1223  +
                crate::config::auth::DefaultAuthSchemeResolver::default()
        1224  +
                    .with_auth_scheme_preference(preference)
        1225  +
                    .into_shared_resolver()
        1226  +
            } else {
 1156   1227   
                crate::config::auth::DefaultAuthSchemeResolver::default().into_shared_resolver()
        1228  +
            }
 1157   1229   
        }));
 1158   1230   
        runtime_components.push_interceptor(::aws_smithy_runtime::client::http::connection_poisoning::ConnectionPoisoningInterceptor::new());
 1159   1231   
        runtime_components.push_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::HttpStatusCodeClassifier::default());
 1160   1232   
        runtime_components.push_interceptor(crate::sdk_feature_tracker::retry_mode::RetryModeFeatureTrackerInterceptor::new());
 1161   1233   
        Self { config, runtime_components }
 1162   1234   
    }
 1163   1235   
}
 1164   1236   
 1165   1237   
impl ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin for ServiceRuntimePlugin {
 1166   1238   
    fn config(&self) -> ::std::option::Option<::aws_smithy_types::config_bag::FrozenLayer> {

tmp-codegen-diff/codegen-client-test/ec2_query/rust-client-codegen/src/config/auth.rs

@@ -18,18 +110,140 @@
   38     38   
        }
   39     39   
    }
   40     40   
}
   41     41   
   42     42   
/// The default auth scheme resolver
   43     43   
#[derive(Debug)]
   44     44   
#[allow(dead_code)]
   45     45   
pub struct DefaultAuthSchemeResolver {
   46     46   
    service_defaults: Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>,
   47     47   
    operation_overrides: ::std::collections::HashMap<&'static str, Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>>,
          48  +
    preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
   48     49   
}
   49     50   
   50     51   
// TODO(https://github.com/smithy-lang/smithy-rs/issues/4177): Remove `allow(...)` once the issue is addressed.
   51     52   
// When generating code for tests (e.g., `codegen-client-test`), this manual implementation
   52     53   
// of the `Default` trait may appear as if it could be derived automatically.
   53     54   
// However, that is not the case in production.
   54     55   
#[allow(clippy::derivable_impls)]
   55     56   
impl Default for DefaultAuthSchemeResolver {
   56     57   
    fn default() -> Self {
   57     58   
        Self {
   58     59   
            service_defaults: vec![],
   59     60   
            operation_overrides: ::std::collections::HashMap::new(),
          61  +
            preference: ::std::option::Option::None,
   60     62   
        }
   61     63   
    }
   62     64   
}
   63     65   
   64     66   
impl crate::config::auth::ResolveAuthScheme for DefaultAuthSchemeResolver {
   65     67   
    fn resolve_auth_scheme<'a>(
   66     68   
        &'a self,
   67     69   
        params: &'a crate::config::auth::Params,
   68     70   
        _cfg: &'a ::aws_smithy_types::config_bag::ConfigBag,
   69     71   
        _runtime_components: &'a ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponents,
   70     72   
    ) -> ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture<'a> {
   71     73   
        let operation_name = params.operation_name();
   72     74   
   73     75   
        let modeled_auth_options = match self.operation_overrides.get(operation_name) {
   74     76   
            Some(overrides) => overrides,
   75     77   
            None => &self.service_defaults,
   76     78   
        };
   77     79   
   78     80   
        let _fut = ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture::ready(Ok(modeled_auth_options.clone()));
   79     81   
   80         -
        _fut
          82  +
        match &self.preference {
          83  +
            ::std::option::Option::Some(preference) => {
          84  +
                _fut.map_ok({
          85  +
                    // maps auth scheme ID to the index in the preference list
          86  +
                    let preference_map: ::std::collections::HashMap<_, _> = preference.clone().into_iter().enumerate().map(|(i, s)| (s, i)).collect();
          87  +
                    move |auth_scheme_options| {
          88  +
                        let (mut preferred, non_preferred): (::std::vec::Vec<_>, ::std::vec::Vec<_>) = auth_scheme_options
          89  +
                            .into_iter()
          90  +
                            .partition(|auth_scheme_option| preference_map.contains_key(auth_scheme_option.scheme_id()));
          91  +
          92  +
                        preferred.sort_by_key(|opt| preference_map.get(opt.scheme_id()).expect("guaranteed by `partition`"));
          93  +
                        preferred.extend(non_preferred);
          94  +
                        preferred
          95  +
                    }
          96  +
                })
          97  +
            }
          98  +
            ::std::option::Option::None => _fut,
          99  +
        }
         100  +
    }
         101  +
}
         102  +
         103  +
impl DefaultAuthSchemeResolver {
         104  +
    /// Set auth scheme preference to the default auth scheme resolver
         105  +
    pub fn with_auth_scheme_preference(
         106  +
        mut self,
         107  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         108  +
    ) -> Self {
         109  +
        self.preference = ::std::option::Option::Some(preference.into());
         110  +
        self
   81    111   
    }
   82    112   
}
   83    113   
   84    114   
/// Configuration parameters for resolving the correct auth scheme
   85    115   
#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]
   86    116   
pub struct Params {
   87    117   
    operation_name: ::std::borrow::Cow<'static, str>,
   88    118   
}
   89    119   
impl Params {
   90    120   
    /// Create a builder for [`Params`]

tmp-codegen-diff/codegen-client-test/endpoint-rules/rust-client-codegen/src/config.rs

@@ -23,23 +82,86 @@
   43     43   
    }
   44     44   
    /// Return the auth schemes configured on this service config
   45     45   
    pub fn auth_schemes(&self) -> impl Iterator<Item = ::aws_smithy_runtime_api::client::auth::SharedAuthScheme> + '_ {
   46     46   
        self.runtime_components.auth_schemes()
   47     47   
    }
   48     48   
   49     49   
    /// Return the auth scheme resolver configured on this service config
   50     50   
    pub fn auth_scheme_resolver(&self) -> ::std::option::Option<::aws_smithy_runtime_api::client::auth::SharedAuthSchemeOptionResolver> {
   51     51   
        self.runtime_components.auth_scheme_option_resolver()
   52     52   
    }
          53  +
    /// Returns the configured auth scheme preference
          54  +
    pub fn auth_scheme_preference(&self) -> ::std::option::Option<&::aws_smithy_runtime_api::client::auth::AuthSchemePreference> {
          55  +
        self.config.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
          56  +
    }
   53     57   
    /// Returns the endpoint resolver.
   54     58   
    pub fn endpoint_resolver(&self) -> ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver {
   55     59   
        self.runtime_components.endpoint_resolver().expect("resolver defaulted if not set")
   56     60   
    }
   57     61   
    /// Return a reference to the retry configuration contained in this config, if any.
   58     62   
    pub fn retry_config(&self) -> ::std::option::Option<&::aws_smithy_types::retry::RetryConfig> {
   59     63   
        self.config.load::<::aws_smithy_types::retry::RetryConfig>()
   60     64   
    }
   61     65   
   62     66   
    /// Return a cloned shared async sleep implementation from this config, if any.
@@ -101,105 +160,165 @@
  121    125   
    ///
  122    126   
    pub fn new() -> Self {
  123    127   
        Self::default()
  124    128   
    }
  125    129   
    /// Constructs a config builder from the given `config_bag`, setting only fields stored in the config bag,
  126    130   
    /// but not those in runtime components.
  127    131   
    #[allow(unused)]
  128    132   
    pub(crate) fn from_config_bag(config_bag: &::aws_smithy_types::config_bag::ConfigBag) -> Self {
  129    133   
        let mut builder = Self::new();
  130    134   
        builder.set_stalled_stream_protection(config_bag.load::<crate::config::StalledStreamProtectionConfig>().cloned());
         135  +
        builder.set_auth_scheme_preference(config_bag.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>().cloned());
  131    136   
        builder.set_retry_config(config_bag.load::<::aws_smithy_types::retry::RetryConfig>().cloned());
  132    137   
        builder.set_timeout_config(config_bag.load::<::aws_smithy_types::timeout::TimeoutConfig>().cloned());
  133    138   
        builder.set_retry_partition(config_bag.load::<::aws_smithy_runtime::client::retries::RetryPartition>().cloned());
  134    139   
        builder
  135    140   
    }
  136    141   
    /// Set the [`StalledStreamProtectionConfig`](crate::config::StalledStreamProtectionConfig)
  137    142   
    /// to configure protection for stalled streams.
  138    143   
    pub fn stalled_stream_protection(mut self, stalled_stream_protection_config: crate::config::StalledStreamProtectionConfig) -> Self {
  139    144   
        self.set_stalled_stream_protection(::std::option::Option::Some(stalled_stream_protection_config));
  140    145   
        self
@@ -345,350 +404,466 @@
  365    370   
  366    371   
    /// Set the auth scheme resolver for the builder
  367    372   
    ///
  368    373   
    /// # Examples
  369    374   
    /// See an example for [`Self::auth_scheme_resolver`].
  370    375   
    pub fn set_auth_scheme_resolver(&mut self, auth_scheme_resolver: impl crate::config::auth::ResolveAuthScheme + 'static) -> &mut Self {
  371    376   
        self.runtime_components
  372    377   
            .set_auth_scheme_option_resolver(::std::option::Option::Some(auth_scheme_resolver.into_shared_resolver()));
  373    378   
        self
  374    379   
    }
         380  +
    /// Set the auth scheme preference for an auth scheme resolver
         381  +
    /// (typically the default auth scheme resolver).
         382  +
    ///
         383  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         384  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         385  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         386  +
    ///
         387  +
    /// The preference list is intended as a hint rather than a strict override.
         388  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         389  +
    ///
         390  +
    /// # Examples
         391  +
    ///
         392  +
    /// ```no_run
         393  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         394  +
    /// let config = endpoint_rules::Config::builder()
         395  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         396  +
    ///     // ...
         397  +
    ///     .build();
         398  +
    /// let client = endpoint_rules::Client::from_conf(config);
         399  +
    /// ```
         400  +
         401  +
    pub fn auth_scheme_preference(
         402  +
        mut self,
         403  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         404  +
    ) -> Self {
         405  +
        self.set_auth_scheme_preference(::std::option::Option::Some(preference.into()));
         406  +
        self
         407  +
    }
         408  +
         409  +
    /// Set the auth scheme preference for an auth scheme resolver
         410  +
    /// (typically the default auth scheme resolver).
         411  +
    ///
         412  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         413  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         414  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         415  +
    ///
         416  +
    /// The preference list is intended as a hint rather than a strict override.
         417  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         418  +
    ///
         419  +
    /// # Examples
         420  +
    ///
         421  +
    /// ```no_run
         422  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         423  +
    /// let config = endpoint_rules::Config::builder()
         424  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         425  +
    ///     // ...
         426  +
    ///     .build();
         427  +
    /// let client = endpoint_rules::Client::from_conf(config);
         428  +
    /// ```
         429  +
         430  +
    pub fn set_auth_scheme_preference(
         431  +
        &mut self,
         432  +
        preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         433  +
    ) -> &mut Self {
         434  +
        self.config.store_or_unset(preference);
         435  +
        self
         436  +
    }
  375    437   
    /// Set the endpoint URL to use when making requests.
  376    438   
    ///
  377    439   
    /// Note: setting an endpoint URL will replace any endpoint resolver that has been set.
  378    440   
    ///
  379    441   
    /// # Panics
  380    442   
    /// Panics if an invalid URL is given.
  381    443   
    pub fn endpoint_url(mut self, endpoint_url: impl ::std::convert::Into<::std::string::String>) -> Self {
  382    444   
        self.set_endpoint_url(::std::option::Option::Some(endpoint_url.into()));
  383    445   
        self
  384    446   
    }
@@ -1116,1178 +1176,1248 @@
 1136   1198   
impl ServiceRuntimePlugin {
 1137   1199   
    pub fn new(_service_config: crate::config::Config) -> Self {
 1138   1200   
        let config = {
 1139   1201   
            let mut cfg = ::aws_smithy_types::config_bag::Layer::new("TestService");
 1140   1202   
            cfg.store_put(::aws_smithy_runtime::client::orchestrator::AuthSchemeAndEndpointOrchestrationV2);
 1141   1203   
            ::std::option::Option::Some(cfg.freeze())
 1142   1204   
        };
 1143   1205   
        let mut runtime_components = ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder::new("ServiceRuntimePlugin");
 1144   1206   
        runtime_components.set_auth_scheme_option_resolver(::std::option::Option::Some({
 1145   1207   
            use crate::config::auth::ResolveAuthScheme;
        1208  +
            if let Some(preference) = _service_config
        1209  +
                .config
        1210  +
                .load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
        1211  +
                .cloned()
        1212  +
            {
        1213  +
                crate::config::auth::DefaultAuthSchemeResolver::default()
        1214  +
                    .with_auth_scheme_preference(preference)
        1215  +
                    .into_shared_resolver()
        1216  +
            } else {
 1146   1217   
                crate::config::auth::DefaultAuthSchemeResolver::default().into_shared_resolver()
        1218  +
            }
 1147   1219   
        }));
 1148   1220   
        runtime_components.set_endpoint_resolver(::std::option::Option::Some({
 1149   1221   
            use crate::config::endpoint::ResolveEndpoint;
 1150   1222   
            crate::config::endpoint::DefaultResolver::new().into_shared_resolver()
 1151   1223   
        }));
 1152   1224   
        runtime_components.push_interceptor(::aws_smithy_runtime::client::http::connection_poisoning::ConnectionPoisoningInterceptor::new());
 1153   1225   
        runtime_components.push_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::HttpStatusCodeClassifier::default());
 1154   1226   
        runtime_components.push_interceptor(crate::sdk_feature_tracker::retry_mode::RetryModeFeatureTrackerInterceptor::new());
 1155   1227   
        Self { config, runtime_components }
 1156   1228   
    }

tmp-codegen-diff/codegen-client-test/endpoint-rules/rust-client-codegen/src/config/auth.rs

@@ -18,18 +112,142 @@
   38     38   
        }
   39     39   
    }
   40     40   
}
   41     41   
   42     42   
/// The default auth scheme resolver
   43     43   
#[derive(Debug)]
   44     44   
#[allow(dead_code)]
   45     45   
pub struct DefaultAuthSchemeResolver {
   46     46   
    service_defaults: Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>,
   47     47   
    operation_overrides: ::std::collections::HashMap<&'static str, Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>>,
          48  +
    preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
   48     49   
}
   49     50   
   50     51   
// TODO(https://github.com/smithy-lang/smithy-rs/issues/4177): Remove `allow(...)` once the issue is addressed.
   51     52   
// When generating code for tests (e.g., `codegen-client-test`), this manual implementation
   52     53   
// of the `Default` trait may appear as if it could be derived automatically.
   53     54   
// However, that is not the case in production.
   54     55   
#[allow(clippy::derivable_impls)]
   55     56   
impl Default for DefaultAuthSchemeResolver {
   56     57   
    fn default() -> Self {
   57     58   
        Self {
   58     59   
            service_defaults: vec![::aws_smithy_runtime_api::client::auth::AuthSchemeOption::from(
   59     60   
                ::aws_smithy_runtime::client::auth::no_auth::NO_AUTH_SCHEME_ID,
   60     61   
            )],
   61     62   
            operation_overrides: ::std::collections::HashMap::new(),
          63  +
            preference: ::std::option::Option::None,
   62     64   
        }
   63     65   
    }
   64     66   
}
   65     67   
   66     68   
impl crate::config::auth::ResolveAuthScheme for DefaultAuthSchemeResolver {
   67     69   
    fn resolve_auth_scheme<'a>(
   68     70   
        &'a self,
   69     71   
        params: &'a crate::config::auth::Params,
   70     72   
        _cfg: &'a ::aws_smithy_types::config_bag::ConfigBag,
   71     73   
        _runtime_components: &'a ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponents,
   72     74   
    ) -> ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture<'a> {
   73     75   
        let operation_name = params.operation_name();
   74     76   
   75     77   
        let modeled_auth_options = match self.operation_overrides.get(operation_name) {
   76     78   
            Some(overrides) => overrides,
   77     79   
            None => &self.service_defaults,
   78     80   
        };
   79     81   
   80     82   
        let _fut = ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture::ready(Ok(modeled_auth_options.clone()));
   81     83   
   82         -
        _fut
          84  +
        match &self.preference {
          85  +
            ::std::option::Option::Some(preference) => {
          86  +
                _fut.map_ok({
          87  +
                    // maps auth scheme ID to the index in the preference list
          88  +
                    let preference_map: ::std::collections::HashMap<_, _> = preference.clone().into_iter().enumerate().map(|(i, s)| (s, i)).collect();
          89  +
                    move |auth_scheme_options| {
          90  +
                        let (mut preferred, non_preferred): (::std::vec::Vec<_>, ::std::vec::Vec<_>) = auth_scheme_options
          91  +
                            .into_iter()
          92  +
                            .partition(|auth_scheme_option| preference_map.contains_key(auth_scheme_option.scheme_id()));
          93  +
          94  +
                        preferred.sort_by_key(|opt| preference_map.get(opt.scheme_id()).expect("guaranteed by `partition`"));
          95  +
                        preferred.extend(non_preferred);
          96  +
                        preferred
          97  +
                    }
          98  +
                })
          99  +
            }
         100  +
            ::std::option::Option::None => _fut,
         101  +
        }
         102  +
    }
         103  +
}
         104  +
         105  +
impl DefaultAuthSchemeResolver {
         106  +
    /// Set auth scheme preference to the default auth scheme resolver
         107  +
    pub fn with_auth_scheme_preference(
         108  +
        mut self,
         109  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         110  +
    ) -> Self {
         111  +
        self.preference = ::std::option::Option::Some(preference.into());
         112  +
        self
   83    113   
    }
   84    114   
}
   85    115   
   86    116   
/// Configuration parameters for resolving the correct auth scheme
   87    117   
#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]
   88    118   
pub struct Params {
   89    119   
    operation_name: ::std::borrow::Cow<'static, str>,
   90    120   
}
   91    121   
impl Params {
   92    122   
    /// Create a builder for [`Params`]

tmp-codegen-diff/codegen-client-test/json_rpc10/rust-client-codegen/src/config.rs

@@ -23,23 +82,86 @@
   43     43   
    }
   44     44   
    /// Return the auth schemes configured on this service config
   45     45   
    pub fn auth_schemes(&self) -> impl Iterator<Item = ::aws_smithy_runtime_api::client::auth::SharedAuthScheme> + '_ {
   46     46   
        self.runtime_components.auth_schemes()
   47     47   
    }
   48     48   
   49     49   
    /// Return the auth scheme resolver configured on this service config
   50     50   
    pub fn auth_scheme_resolver(&self) -> ::std::option::Option<::aws_smithy_runtime_api::client::auth::SharedAuthSchemeOptionResolver> {
   51     51   
        self.runtime_components.auth_scheme_option_resolver()
   52     52   
    }
          53  +
    /// Returns the configured auth scheme preference
          54  +
    pub fn auth_scheme_preference(&self) -> ::std::option::Option<&::aws_smithy_runtime_api::client::auth::AuthSchemePreference> {
          55  +
        self.config.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
          56  +
    }
   53     57   
    /// Returns the endpoint resolver.
   54     58   
    pub fn endpoint_resolver(&self) -> ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver {
   55     59   
        self.runtime_components.endpoint_resolver().expect("resolver defaulted if not set")
   56     60   
    }
   57     61   
    /// Return a reference to the retry configuration contained in this config, if any.
   58     62   
    pub fn retry_config(&self) -> ::std::option::Option<&::aws_smithy_types::retry::RetryConfig> {
   59     63   
        self.config.load::<::aws_smithy_types::retry::RetryConfig>()
   60     64   
    }
   61     65   
   62     66   
    /// Return a cloned shared async sleep implementation from this config, if any.
@@ -101,105 +160,165 @@
  121    125   
    ///
  122    126   
    pub fn new() -> Self {
  123    127   
        Self::default()
  124    128   
    }
  125    129   
    /// Constructs a config builder from the given `config_bag`, setting only fields stored in the config bag,
  126    130   
    /// but not those in runtime components.
  127    131   
    #[allow(unused)]
  128    132   
    pub(crate) fn from_config_bag(config_bag: &::aws_smithy_types::config_bag::ConfigBag) -> Self {
  129    133   
        let mut builder = Self::new();
  130    134   
        builder.set_stalled_stream_protection(config_bag.load::<crate::config::StalledStreamProtectionConfig>().cloned());
         135  +
        builder.set_auth_scheme_preference(config_bag.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>().cloned());
  131    136   
        builder.set_retry_config(config_bag.load::<::aws_smithy_types::retry::RetryConfig>().cloned());
  132    137   
        builder.set_timeout_config(config_bag.load::<::aws_smithy_types::timeout::TimeoutConfig>().cloned());
  133    138   
        builder.set_retry_partition(config_bag.load::<::aws_smithy_runtime::client::retries::RetryPartition>().cloned());
  134    139   
        builder
  135    140   
    }
  136    141   
    /// Set the [`StalledStreamProtectionConfig`](crate::config::StalledStreamProtectionConfig)
  137    142   
    /// to configure protection for stalled streams.
  138    143   
    pub fn stalled_stream_protection(mut self, stalled_stream_protection_config: crate::config::StalledStreamProtectionConfig) -> Self {
  139    144   
        self.set_stalled_stream_protection(::std::option::Option::Some(stalled_stream_protection_config));
  140    145   
        self
@@ -345,350 +404,466 @@
  365    370   
  366    371   
    /// Set the auth scheme resolver for the builder
  367    372   
    ///
  368    373   
    /// # Examples
  369    374   
    /// See an example for [`Self::auth_scheme_resolver`].
  370    375   
    pub fn set_auth_scheme_resolver(&mut self, auth_scheme_resolver: impl crate::config::auth::ResolveAuthScheme + 'static) -> &mut Self {
  371    376   
        self.runtime_components
  372    377   
            .set_auth_scheme_option_resolver(::std::option::Option::Some(auth_scheme_resolver.into_shared_resolver()));
  373    378   
        self
  374    379   
    }
         380  +
    /// Set the auth scheme preference for an auth scheme resolver
         381  +
    /// (typically the default auth scheme resolver).
         382  +
    ///
         383  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         384  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         385  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         386  +
    ///
         387  +
    /// The preference list is intended as a hint rather than a strict override.
         388  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         389  +
    ///
         390  +
    /// # Examples
         391  +
    ///
         392  +
    /// ```no_run
         393  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         394  +
    /// let config = json_rpc10::Config::builder()
         395  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         396  +
    ///     // ...
         397  +
    ///     .build();
         398  +
    /// let client = json_rpc10::Client::from_conf(config);
         399  +
    /// ```
         400  +
         401  +
    pub fn auth_scheme_preference(
         402  +
        mut self,
         403  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         404  +
    ) -> Self {
         405  +
        self.set_auth_scheme_preference(::std::option::Option::Some(preference.into()));
         406  +
        self
         407  +
    }
         408  +
         409  +
    /// Set the auth scheme preference for an auth scheme resolver
         410  +
    /// (typically the default auth scheme resolver).
         411  +
    ///
         412  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         413  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         414  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         415  +
    ///
         416  +
    /// The preference list is intended as a hint rather than a strict override.
         417  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         418  +
    ///
         419  +
    /// # Examples
         420  +
    ///
         421  +
    /// ```no_run
         422  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         423  +
    /// let config = json_rpc10::Config::builder()
         424  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         425  +
    ///     // ...
         426  +
    ///     .build();
         427  +
    /// let client = json_rpc10::Client::from_conf(config);
         428  +
    /// ```
         429  +
         430  +
    pub fn set_auth_scheme_preference(
         431  +
        &mut self,
         432  +
        preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         433  +
    ) -> &mut Self {
         434  +
        self.config.store_or_unset(preference);
         435  +
        self
         436  +
    }
  375    437   
    /// Set the endpoint URL to use when making requests.
  376    438   
    ///
  377    439   
    /// Note: setting an endpoint URL will replace any endpoint resolver that has been set.
  378    440   
    ///
  379    441   
    /// # Panics
  380    442   
    /// Panics if an invalid URL is given.
  381    443   
    pub fn endpoint_url(mut self, endpoint_url: impl ::std::convert::Into<::std::string::String>) -> Self {
  382    444   
        self.set_endpoint_url(::std::option::Option::Some(endpoint_url.into()));
  383    445   
        self
  384    446   
    }
@@ -1108,1170 +1168,1240 @@
 1128   1190   
impl ServiceRuntimePlugin {
 1129   1191   
    pub fn new(_service_config: crate::config::Config) -> Self {
 1130   1192   
        let config = {
 1131   1193   
            let mut cfg = ::aws_smithy_types::config_bag::Layer::new("JsonRpc10");
 1132   1194   
            cfg.store_put(::aws_smithy_runtime::client::orchestrator::AuthSchemeAndEndpointOrchestrationV2);
 1133   1195   
            ::std::option::Option::Some(cfg.freeze())
 1134   1196   
        };
 1135   1197   
        let mut runtime_components = ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder::new("ServiceRuntimePlugin");
 1136   1198   
        runtime_components.set_auth_scheme_option_resolver(::std::option::Option::Some({
 1137   1199   
            use crate::config::auth::ResolveAuthScheme;
        1200  +
            if let Some(preference) = _service_config
        1201  +
                .config
        1202  +
                .load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
        1203  +
                .cloned()
        1204  +
            {
        1205  +
                crate::config::auth::DefaultAuthSchemeResolver::default()
        1206  +
                    .with_auth_scheme_preference(preference)
        1207  +
                    .into_shared_resolver()
        1208  +
            } else {
 1138   1209   
                crate::config::auth::DefaultAuthSchemeResolver::default().into_shared_resolver()
        1210  +
            }
 1139   1211   
        }));
 1140   1212   
        runtime_components.push_interceptor(::aws_smithy_runtime::client::http::connection_poisoning::ConnectionPoisoningInterceptor::new());
 1141   1213   
        runtime_components.push_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::HttpStatusCodeClassifier::default());
 1142   1214   
        runtime_components.push_interceptor(crate::sdk_feature_tracker::retry_mode::RetryModeFeatureTrackerInterceptor::new());
 1143   1215   
        Self { config, runtime_components }
 1144   1216   
    }
 1145   1217   
}
 1146   1218   
 1147   1219   
impl ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin for ServiceRuntimePlugin {
 1148   1220   
    fn config(&self) -> ::std::option::Option<::aws_smithy_types::config_bag::FrozenLayer> {

tmp-codegen-diff/codegen-client-test/json_rpc10/rust-client-codegen/src/config/auth.rs

@@ -18,18 +110,140 @@
   38     38   
        }
   39     39   
    }
   40     40   
}
   41     41   
   42     42   
/// The default auth scheme resolver
   43     43   
#[derive(Debug)]
   44     44   
#[allow(dead_code)]
   45     45   
pub struct DefaultAuthSchemeResolver {
   46     46   
    service_defaults: Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>,
   47     47   
    operation_overrides: ::std::collections::HashMap<&'static str, Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>>,
          48  +
    preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
   48     49   
}
   49     50   
   50     51   
// TODO(https://github.com/smithy-lang/smithy-rs/issues/4177): Remove `allow(...)` once the issue is addressed.
   51     52   
// When generating code for tests (e.g., `codegen-client-test`), this manual implementation
   52     53   
// of the `Default` trait may appear as if it could be derived automatically.
   53     54   
// However, that is not the case in production.
   54     55   
#[allow(clippy::derivable_impls)]
   55     56   
impl Default for DefaultAuthSchemeResolver {
   56     57   
    fn default() -> Self {
   57     58   
        Self {
   58     59   
            service_defaults: vec![],
   59     60   
            operation_overrides: ::std::collections::HashMap::new(),
          61  +
            preference: ::std::option::Option::None,
   60     62   
        }
   61     63   
    }
   62     64   
}
   63     65   
   64     66   
impl crate::config::auth::ResolveAuthScheme for DefaultAuthSchemeResolver {
   65     67   
    fn resolve_auth_scheme<'a>(
   66     68   
        &'a self,
   67     69   
        params: &'a crate::config::auth::Params,
   68     70   
        _cfg: &'a ::aws_smithy_types::config_bag::ConfigBag,
   69     71   
        _runtime_components: &'a ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponents,
   70     72   
    ) -> ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture<'a> {
   71     73   
        let operation_name = params.operation_name();
   72     74   
   73     75   
        let modeled_auth_options = match self.operation_overrides.get(operation_name) {
   74     76   
            Some(overrides) => overrides,
   75     77   
            None => &self.service_defaults,
   76     78   
        };
   77     79   
   78     80   
        let _fut = ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture::ready(Ok(modeled_auth_options.clone()));
   79     81   
   80         -
        _fut
          82  +
        match &self.preference {
          83  +
            ::std::option::Option::Some(preference) => {
          84  +
                _fut.map_ok({
          85  +
                    // maps auth scheme ID to the index in the preference list
          86  +
                    let preference_map: ::std::collections::HashMap<_, _> = preference.clone().into_iter().enumerate().map(|(i, s)| (s, i)).collect();
          87  +
                    move |auth_scheme_options| {
          88  +
                        let (mut preferred, non_preferred): (::std::vec::Vec<_>, ::std::vec::Vec<_>) = auth_scheme_options
          89  +
                            .into_iter()
          90  +
                            .partition(|auth_scheme_option| preference_map.contains_key(auth_scheme_option.scheme_id()));
          91  +
          92  +
                        preferred.sort_by_key(|opt| preference_map.get(opt.scheme_id()).expect("guaranteed by `partition`"));
          93  +
                        preferred.extend(non_preferred);
          94  +
                        preferred
          95  +
                    }
          96  +
                })
          97  +
            }
          98  +
            ::std::option::Option::None => _fut,
          99  +
        }
         100  +
    }
         101  +
}
         102  +
         103  +
impl DefaultAuthSchemeResolver {
         104  +
    /// Set auth scheme preference to the default auth scheme resolver
         105  +
    pub fn with_auth_scheme_preference(
         106  +
        mut self,
         107  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         108  +
    ) -> Self {
         109  +
        self.preference = ::std::option::Option::Some(preference.into());
         110  +
        self
   81    111   
    }
   82    112   
}
   83    113   
   84    114   
/// Configuration parameters for resolving the correct auth scheme
   85    115   
#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]
   86    116   
pub struct Params {
   87    117   
    operation_name: ::std::borrow::Cow<'static, str>,
   88    118   
}
   89    119   
impl Params {
   90    120   
    /// Create a builder for [`Params`]

tmp-codegen-diff/codegen-client-test/json_rpc11/rust-client-codegen/src/config.rs

@@ -23,23 +82,86 @@
   43     43   
    }
   44     44   
    /// Return the auth schemes configured on this service config
   45     45   
    pub fn auth_schemes(&self) -> impl Iterator<Item = ::aws_smithy_runtime_api::client::auth::SharedAuthScheme> + '_ {
   46     46   
        self.runtime_components.auth_schemes()
   47     47   
    }
   48     48   
   49     49   
    /// Return the auth scheme resolver configured on this service config
   50     50   
    pub fn auth_scheme_resolver(&self) -> ::std::option::Option<::aws_smithy_runtime_api::client::auth::SharedAuthSchemeOptionResolver> {
   51     51   
        self.runtime_components.auth_scheme_option_resolver()
   52     52   
    }
          53  +
    /// Returns the configured auth scheme preference
          54  +
    pub fn auth_scheme_preference(&self) -> ::std::option::Option<&::aws_smithy_runtime_api::client::auth::AuthSchemePreference> {
          55  +
        self.config.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
          56  +
    }
   53     57   
    /// Returns the endpoint resolver.
   54     58   
    pub fn endpoint_resolver(&self) -> ::aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver {
   55     59   
        self.runtime_components.endpoint_resolver().expect("resolver defaulted if not set")
   56     60   
    }
   57     61   
    /// Return a reference to the retry configuration contained in this config, if any.
   58     62   
    pub fn retry_config(&self) -> ::std::option::Option<&::aws_smithy_types::retry::RetryConfig> {
   59     63   
        self.config.load::<::aws_smithy_types::retry::RetryConfig>()
   60     64   
    }
   61     65   
   62     66   
    /// Return a cloned shared async sleep implementation from this config, if any.
@@ -101,105 +160,165 @@
  121    125   
    ///
  122    126   
    pub fn new() -> Self {
  123    127   
        Self::default()
  124    128   
    }
  125    129   
    /// Constructs a config builder from the given `config_bag`, setting only fields stored in the config bag,
  126    130   
    /// but not those in runtime components.
  127    131   
    #[allow(unused)]
  128    132   
    pub(crate) fn from_config_bag(config_bag: &::aws_smithy_types::config_bag::ConfigBag) -> Self {
  129    133   
        let mut builder = Self::new();
  130    134   
        builder.set_stalled_stream_protection(config_bag.load::<crate::config::StalledStreamProtectionConfig>().cloned());
         135  +
        builder.set_auth_scheme_preference(config_bag.load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>().cloned());
  131    136   
        builder.set_retry_config(config_bag.load::<::aws_smithy_types::retry::RetryConfig>().cloned());
  132    137   
        builder.set_timeout_config(config_bag.load::<::aws_smithy_types::timeout::TimeoutConfig>().cloned());
  133    138   
        builder.set_retry_partition(config_bag.load::<::aws_smithy_runtime::client::retries::RetryPartition>().cloned());
  134    139   
        builder
  135    140   
    }
  136    141   
    /// Set the [`StalledStreamProtectionConfig`](crate::config::StalledStreamProtectionConfig)
  137    142   
    /// to configure protection for stalled streams.
  138    143   
    pub fn stalled_stream_protection(mut self, stalled_stream_protection_config: crate::config::StalledStreamProtectionConfig) -> Self {
  139    144   
        self.set_stalled_stream_protection(::std::option::Option::Some(stalled_stream_protection_config));
  140    145   
        self
@@ -345,350 +404,466 @@
  365    370   
  366    371   
    /// Set the auth scheme resolver for the builder
  367    372   
    ///
  368    373   
    /// # Examples
  369    374   
    /// See an example for [`Self::auth_scheme_resolver`].
  370    375   
    pub fn set_auth_scheme_resolver(&mut self, auth_scheme_resolver: impl crate::config::auth::ResolveAuthScheme + 'static) -> &mut Self {
  371    376   
        self.runtime_components
  372    377   
            .set_auth_scheme_option_resolver(::std::option::Option::Some(auth_scheme_resolver.into_shared_resolver()));
  373    378   
        self
  374    379   
    }
         380  +
    /// Set the auth scheme preference for an auth scheme resolver
         381  +
    /// (typically the default auth scheme resolver).
         382  +
    ///
         383  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         384  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         385  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         386  +
    ///
         387  +
    /// The preference list is intended as a hint rather than a strict override.
         388  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         389  +
    ///
         390  +
    /// # Examples
         391  +
    ///
         392  +
    /// ```no_run
         393  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         394  +
    /// let config = json_rpc11::Config::builder()
         395  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         396  +
    ///     // ...
         397  +
    ///     .build();
         398  +
    /// let client = json_rpc11::Client::from_conf(config);
         399  +
    /// ```
         400  +
         401  +
    pub fn auth_scheme_preference(
         402  +
        mut self,
         403  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         404  +
    ) -> Self {
         405  +
        self.set_auth_scheme_preference(::std::option::Option::Some(preference.into()));
         406  +
        self
         407  +
    }
         408  +
         409  +
    /// Set the auth scheme preference for an auth scheme resolver
         410  +
    /// (typically the default auth scheme resolver).
         411  +
    ///
         412  +
    /// Each operation has a predefined order of auth schemes, as determined by the service,
         413  +
    /// for auth scheme resolution. By using the auth scheme preference, customers
         414  +
    /// can reorder the schemes resolved by the auth scheme resolver.
         415  +
    ///
         416  +
    /// The preference list is intended as a hint rather than a strict override.
         417  +
    /// Any schemes not present in the originally resolved auth schemes will be ignored.
         418  +
    ///
         419  +
    /// # Examples
         420  +
    ///
         421  +
    /// ```no_run
         422  +
    /// # use aws_smithy_runtime_api::client::auth::AuthSchemeId;
         423  +
    /// let config = json_rpc11::Config::builder()
         424  +
    ///     .auth_scheme_preference([AuthSchemeId::from("scheme1"), AuthSchemeId::from("scheme2")])
         425  +
    ///     // ...
         426  +
    ///     .build();
         427  +
    /// let client = json_rpc11::Client::from_conf(config);
         428  +
    /// ```
         429  +
         430  +
    pub fn set_auth_scheme_preference(
         431  +
        &mut self,
         432  +
        preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         433  +
    ) -> &mut Self {
         434  +
        self.config.store_or_unset(preference);
         435  +
        self
         436  +
    }
  375    437   
    /// Set the endpoint URL to use when making requests.
  376    438   
    ///
  377    439   
    /// Note: setting an endpoint URL will replace any endpoint resolver that has been set.
  378    440   
    ///
  379    441   
    /// # Panics
  380    442   
    /// Panics if an invalid URL is given.
  381    443   
    pub fn endpoint_url(mut self, endpoint_url: impl ::std::convert::Into<::std::string::String>) -> Self {
  382    444   
        self.set_endpoint_url(::std::option::Option::Some(endpoint_url.into()));
  383    445   
        self
  384    446   
    }
@@ -1108,1170 +1168,1240 @@
 1128   1190   
impl ServiceRuntimePlugin {
 1129   1191   
    pub fn new(_service_config: crate::config::Config) -> Self {
 1130   1192   
        let config = {
 1131   1193   
            let mut cfg = ::aws_smithy_types::config_bag::Layer::new("JsonProtocol");
 1132   1194   
            cfg.store_put(::aws_smithy_runtime::client::orchestrator::AuthSchemeAndEndpointOrchestrationV2);
 1133   1195   
            ::std::option::Option::Some(cfg.freeze())
 1134   1196   
        };
 1135   1197   
        let mut runtime_components = ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder::new("ServiceRuntimePlugin");
 1136   1198   
        runtime_components.set_auth_scheme_option_resolver(::std::option::Option::Some({
 1137   1199   
            use crate::config::auth::ResolveAuthScheme;
        1200  +
            if let Some(preference) = _service_config
        1201  +
                .config
        1202  +
                .load::<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>()
        1203  +
                .cloned()
        1204  +
            {
        1205  +
                crate::config::auth::DefaultAuthSchemeResolver::default()
        1206  +
                    .with_auth_scheme_preference(preference)
        1207  +
                    .into_shared_resolver()
        1208  +
            } else {
 1138   1209   
                crate::config::auth::DefaultAuthSchemeResolver::default().into_shared_resolver()
        1210  +
            }
 1139   1211   
        }));
 1140   1212   
        runtime_components.push_interceptor(::aws_smithy_runtime::client::http::connection_poisoning::ConnectionPoisoningInterceptor::new());
 1141   1213   
        runtime_components.push_retry_classifier(::aws_smithy_runtime::client::retries::classifiers::HttpStatusCodeClassifier::default());
 1142   1214   
        runtime_components.push_interceptor(crate::sdk_feature_tracker::retry_mode::RetryModeFeatureTrackerInterceptor::new());
 1143   1215   
        Self { config, runtime_components }
 1144   1216   
    }
 1145   1217   
}
 1146   1218   
 1147   1219   
impl ::aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin for ServiceRuntimePlugin {
 1148   1220   
    fn config(&self) -> ::std::option::Option<::aws_smithy_types::config_bag::FrozenLayer> {

tmp-codegen-diff/codegen-client-test/json_rpc11/rust-client-codegen/src/config/auth.rs

@@ -18,18 +110,140 @@
   38     38   
        }
   39     39   
    }
   40     40   
}
   41     41   
   42     42   
/// The default auth scheme resolver
   43     43   
#[derive(Debug)]
   44     44   
#[allow(dead_code)]
   45     45   
pub struct DefaultAuthSchemeResolver {
   46     46   
    service_defaults: Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>,
   47     47   
    operation_overrides: ::std::collections::HashMap<&'static str, Vec<::aws_smithy_runtime_api::client::auth::AuthSchemeOption>>,
          48  +
    preference: ::std::option::Option<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
   48     49   
}
   49     50   
   50     51   
// TODO(https://github.com/smithy-lang/smithy-rs/issues/4177): Remove `allow(...)` once the issue is addressed.
   51     52   
// When generating code for tests (e.g., `codegen-client-test`), this manual implementation
   52     53   
// of the `Default` trait may appear as if it could be derived automatically.
   53     54   
// However, that is not the case in production.
   54     55   
#[allow(clippy::derivable_impls)]
   55     56   
impl Default for DefaultAuthSchemeResolver {
   56     57   
    fn default() -> Self {
   57     58   
        Self {
   58     59   
            service_defaults: vec![],
   59     60   
            operation_overrides: ::std::collections::HashMap::new(),
          61  +
            preference: ::std::option::Option::None,
   60     62   
        }
   61     63   
    }
   62     64   
}
   63     65   
   64     66   
impl crate::config::auth::ResolveAuthScheme for DefaultAuthSchemeResolver {
   65     67   
    fn resolve_auth_scheme<'a>(
   66     68   
        &'a self,
   67     69   
        params: &'a crate::config::auth::Params,
   68     70   
        _cfg: &'a ::aws_smithy_types::config_bag::ConfigBag,
   69     71   
        _runtime_components: &'a ::aws_smithy_runtime_api::client::runtime_components::RuntimeComponents,
   70     72   
    ) -> ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture<'a> {
   71     73   
        let operation_name = params.operation_name();
   72     74   
   73     75   
        let modeled_auth_options = match self.operation_overrides.get(operation_name) {
   74     76   
            Some(overrides) => overrides,
   75     77   
            None => &self.service_defaults,
   76     78   
        };
   77     79   
   78     80   
        let _fut = ::aws_smithy_runtime_api::client::auth::AuthSchemeOptionsFuture::ready(Ok(modeled_auth_options.clone()));
   79     81   
   80         -
        _fut
          82  +
        match &self.preference {
          83  +
            ::std::option::Option::Some(preference) => {
          84  +
                _fut.map_ok({
          85  +
                    // maps auth scheme ID to the index in the preference list
          86  +
                    let preference_map: ::std::collections::HashMap<_, _> = preference.clone().into_iter().enumerate().map(|(i, s)| (s, i)).collect();
          87  +
                    move |auth_scheme_options| {
          88  +
                        let (mut preferred, non_preferred): (::std::vec::Vec<_>, ::std::vec::Vec<_>) = auth_scheme_options
          89  +
                            .into_iter()
          90  +
                            .partition(|auth_scheme_option| preference_map.contains_key(auth_scheme_option.scheme_id()));
          91  +
          92  +
                        preferred.sort_by_key(|opt| preference_map.get(opt.scheme_id()).expect("guaranteed by `partition`"));
          93  +
                        preferred.extend(non_preferred);
          94  +
                        preferred
          95  +
                    }
          96  +
                })
          97  +
            }
          98  +
            ::std::option::Option::None => _fut,
          99  +
        }
         100  +
    }
         101  +
}
         102  +
         103  +
impl DefaultAuthSchemeResolver {
         104  +
    /// Set auth scheme preference to the default auth scheme resolver
         105  +
    pub fn with_auth_scheme_preference(
         106  +
        mut self,
         107  +
        preference: impl ::std::convert::Into<::aws_smithy_runtime_api::client::auth::AuthSchemePreference>,
         108  +
    ) -> Self {
         109  +
        self.preference = ::std::option::Option::Some(preference.into());
         110  +
        self
   81    111   
    }
   82    112   
}
   83    113   
   84    114   
/// Configuration parameters for resolving the correct auth scheme
   85    115   
#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]
   86    116   
pub struct Params {
   87    117   
    operation_name: ::std::borrow::Cow<'static, str>,
   88    118   
}
   89    119   
impl Params {
   90    120   
    /// Create a builder for [`Params`]