AWS SDK

AWS SDK

rev. 80d9b4c9aa38f40a6d033a9f956fdf3576cff60f

Files changed:

tmp-codegen-diff/aws-sdk/sdk/aws-config/Cargo.toml

@@ -13,13 +157,157 @@
   33     33   
   34     34   
[dependencies]
   35     35   
bytes = "1.1.0"
   36     36   
http = "1"
   37     37   
url = "2.5.4"
   38     38   
fastrand = "2.3.0"
   39     39   
   40     40   
[dependencies.aws-credential-types]
   41     41   
path = "../aws-credential-types"
   42     42   
features = ["test-util"]
   43         -
version = "1.2.9"
          43  +
version = "1.2.10"
   44     44   
   45     45   
[dependencies.aws-runtime]
   46     46   
path = "../aws-runtime"
   47     47   
version = "1.5.16"
   48     48   
   49     49   
[dependencies.aws-sdk-sts]
   50     50   
path = "../sts"
   51     51   
default-features = false
   52     52   
version = "0.0.0-local"
   53     53   
   54     54   
[dependencies.aws-smithy-async]
   55     55   
path = "../aws-smithy-async"
   56     56   
version = "1.2.6"
   57     57   
   58     58   
[dependencies.aws-smithy-http]
   59     59   
path = "../aws-smithy-http"
   60     60   
version = "0.62.5"
   61     61   
   62     62   
[dependencies.aws-smithy-json]
   63     63   
path = "../aws-smithy-json"
   64     64   
version = "0.61.7"
   65     65   
   66     66   
[dependencies.aws-smithy-runtime]
   67     67   
path = "../aws-smithy-runtime"
   68     68   
features = ["client"]
   69         -
version = "1.9.4"
          69  +
version = "1.9.5"
   70     70   
   71     71   
[dependencies.aws-smithy-runtime-api]
   72     72   
path = "../aws-smithy-runtime-api"
   73     73   
features = ["client"]
   74     74   
version = "1.9.2"
   75     75   
   76     76   
[dependencies.aws-smithy-types]
   77     77   
path = "../aws-smithy-types"
   78     78   
version = "1.3.4"
   79     79   
   80     80   
[dependencies.aws-types]
   81     81   
path = "../aws-types"
   82         -
version = "1.3.10"
          82  +
version = "1.3.11"
   83     83   
   84     84   
[dependencies.time]
   85     85   
version = "0.3.4"
   86     86   
features = ["parsing"]
   87     87   
   88     88   
[dependencies.tokio]
   89     89   
version = "1.13.1"
   90     90   
features = ["sync"]
   91     91   
   92     92   
[dependencies.tracing]
   93     93   
version = "0.1"
   94     94   
   95     95   
[dependencies.aws-sdk-sso]
   96     96   
path = "../sso"
   97     97   
default-features = false
   98     98   
optional = true
   99     99   
version = "0.0.0-local"
  100    100   
  101    101   
[dependencies.ring]
  102    102   
version = "0.17.5"
  103    103   
optional = true
  104    104   
  105    105   
[dependencies.hex]
  106    106   
version = "0.4.3"
  107    107   
optional = true
  108    108   
  109    109   
[dependencies.zeroize]
  110    110   
version = "1"
  111    111   
optional = true
  112    112   
  113    113   
[dependencies.aws-sdk-ssooidc]
  114    114   
path = "../ssooidc"
  115    115   
default-features = false
  116    116   
optional = true
  117    117   
version = "0.0.0-local"
  118    118   
  119    119   
[dev-dependencies]
  120    120   
tracing-test = "0.2.4"
  121    121   
serde_json = "1"
  122    122   
  123    123   
[dev-dependencies.aws-smithy-async]
  124    124   
path = "../aws-smithy-async"
  125    125   
features = ["rt-tokio", "test-util"]
  126    126   
version = "1.2.6"
  127    127   
  128    128   
[dev-dependencies.aws-smithy-http-client]
  129    129   
path = "../aws-smithy-http-client"
  130    130   
features = ["default-client", "test-util"]
  131         -
version = "1.1.4"
         131  +
version = "1.1.5"
  132    132   
  133    133   
[dev-dependencies.aws-smithy-runtime]
  134    134   
path = "../aws-smithy-runtime"
  135    135   
features = ["client", "test-util"]
  136         -
version = "1.9.4"
         136  +
version = "1.9.5"
  137    137   
  138    138   
[dev-dependencies.aws-smithy-runtime-api]
  139    139   
path = "../aws-smithy-runtime-api"
  140    140   
features = ["test-util"]
  141    141   
version = "1.9.2"
  142    142   
  143    143   
[dev-dependencies.futures-util]
  144    144   
version = "0.3.29"
  145    145   
default-features = false
  146    146   

tmp-codegen-diff/aws-sdk/sdk/aws-config/fuzz/Cargo.toml

@@ -1,1 +30,30 @@
   17     17   
   18     18   
[dependencies]
   19     19   
libfuzzer-sys = "=0.4.7"
   20     20   
   21     21   
[dependencies.aws-config]
   22     22   
path = ".."
   23     23   
version = "1.8.10"
   24     24   
   25     25   
[dependencies.aws-types]
   26     26   
path = "../../../sdk/build/aws-sdk/sdk/aws-types"
   27         -
version = "1.3.10"
          27  +
version = "1.3.11"
   28     28   
   29     29   
[workspace]
   30     30   
members = ["."]

tmp-codegen-diff/aws-sdk/sdk/aws-credential-types/Cargo.toml

@@ -1,1 +34,34 @@
    1      1   
# Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
    2      2   
[package]
    3      3   
name = "aws-credential-types"
    4         -
version = "1.2.9"
           4  +
version = "1.2.10"
    5      5   
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>"]
    6      6   
description = "Types for AWS SDK credentials."
    7      7   
edition = "2021"
    8      8   
license = "Apache-2.0"
    9      9   
repository = "https://github.com/smithy-lang/smithy-rs"
   10     10   
[package.metadata.docs.rs]
   11     11   
all-features = true
   12     12   
targets = ["x86_64-unknown-linux-gnu"]
   13     13   
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
   14     14   
rustdoc-args = ["--cfg", "docsrs"]

tmp-codegen-diff/aws-sdk/sdk/aws-credential-types/src/credentials_impl.rs

@@ -404,404 +478,478 @@
  424    424   
    #[test]
  425    425   
    fn debug_impl() {
  426    426   
        let creds = Credentials::new(
  427    427   
            "akid",
  428    428   
            "secret",
  429    429   
            Some("token".into()),
  430    430   
            Some(UNIX_EPOCH + Duration::from_secs(1234567890)),
  431    431   
            "debug tester",
  432    432   
        );
  433    433   
        assert_eq!(
  434         -
            format!("{:?}", creds),
         434  +
            format!("{creds:?}"),
  435    435   
            r#"Credentials { provider_name: "debug tester", access_key_id: "akid", secret_access_key: "** redacted **", expires_after: "2009-02-13T23:31:30Z" }"#
  436    436   
        );
  437    437   
  438    438   
        // with account ID
  439    439   
        let creds = Credentials::builder()
  440    440   
            .access_key_id("akid")
  441    441   
            .secret_access_key("secret")
  442    442   
            .session_token("token")
  443    443   
            .expiry(UNIX_EPOCH + Duration::from_secs(1234567890))
  444    444   
            .account_id("012345678901")
  445    445   
            .provider_name("debug tester")
  446    446   
            .build();
  447    447   
        assert_eq!(
  448         -
            format!("{:?}", creds),
         448  +
            format!("{creds:?}"),
  449    449   
            r#"Credentials { provider_name: "debug tester", access_key_id: "akid", secret_access_key: "** redacted **", expires_after: "2009-02-13T23:31:30Z", account_id: "012345678901" }"#
  450    450   
        );
  451    451   
    }
  452    452   
  453    453   
    #[cfg(feature = "test-util")]
  454    454   
    #[test]
  455    455   
    fn equality_ignores_properties() {
  456    456   
        #[derive(Clone, Debug)]
  457    457   
        struct Foo;
  458    458   
        let mut creds1 = Credentials::for_tests_with_session_token();

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/Cargo.toml

@@ -5,5 +139,150 @@
   25     25   
   26     26   
[dependencies]
   27     27   
bytes = "1.10.0"
   28     28   
fastrand = "2.3.0"
   29     29   
percent-encoding = "2.3.1"
   30     30   
pin-project-lite = "0.2.14"
   31     31   
tracing = "0.1.40"
   32     32   
   33     33   
[dependencies.aws-credential-types]
   34     34   
path = "../aws-credential-types"
   35         -
version = "1.2.9"
          35  +
version = "1.2.10"
   36     36   
   37     37   
[dependencies.aws-sigv4]
   38     38   
path = "../aws-sigv4"
   39     39   
features = ["http0-compat"]
   40         -
version = "1.3.6"
          40  +
version = "1.3.8"
   41     41   
   42     42   
[dependencies.aws-smithy-async]
   43     43   
path = "../aws-smithy-async"
   44     44   
version = "1.2.6"
   45     45   
   46     46   
[dependencies.aws-smithy-eventstream]
   47     47   
path = "../aws-smithy-eventstream"
   48     48   
optional = true
   49     49   
version = "0.60.13"
   50     50   
   51     51   
[dependencies.aws-smithy-http]
   52     52   
path = "../aws-smithy-http"
   53     53   
version = "0.62.5"
   54     54   
          55  +
[dependencies.aws-smithy-observability]
          56  +
path = "../aws-smithy-observability"
          57  +
version = "0.2.0"
          58  +
   55     59   
[dependencies.aws-smithy-runtime]
   56     60   
path = "../aws-smithy-runtime"
   57     61   
features = ["client"]
   58         -
version = "1.9.4"
          62  +
version = "1.9.5"
   59     63   
   60     64   
[dependencies.aws-smithy-runtime-api]
   61     65   
path = "../aws-smithy-runtime-api"
   62     66   
features = ["client"]
   63     67   
version = "1.9.2"
   64     68   
   65     69   
[dependencies.aws-smithy-types]
   66     70   
path = "../aws-smithy-types"
   67     71   
version = "1.3.4"
   68     72   
   69     73   
[dependencies.aws-types]
   70     74   
path = "../aws-types"
   71         -
version = "1.3.10"
          75  +
version = "1.3.11"
   72     76   
   73     77   
[dependencies.http-02x]
   74     78   
package = "http"
   75     79   
version = "0.2.9"
   76     80   
   77     81   
[dependencies.http-body-04x]
   78     82   
package = "http-body"
   79     83   
version = "0.4.5"
   80     84   
   81     85   
[dependencies.http-1x]
   82     86   
package = "http"
   83     87   
version = "1.1.0"
   84     88   
optional = true
   85     89   
   86     90   
[dependencies.http-body-1x]
   87     91   
package = "http-body"
   88     92   
version = "1.0.0"
   89     93   
optional = true
   90     94   
   91     95   
[dependencies.regex-lite]
   92     96   
version = "0.1.5"
   93     97   
optional = true
   94     98   
   95     99   
[dependencies.uuid]
   96    100   
version = "1"
         101  +
[target."cfg(all(not(target_arch = \"powerpc\"), not(target_family = \"wasm\")))".dependencies.aws-smithy-observability-otel]
         102  +
version = "0.1.3"
         103  +
path = "../aws-smithy-observability-otel"
         104  +
[target."cfg(all(not(target_arch = \"powerpc\"), not(target_family = \"wasm\")))".dev-dependencies.opentelemetry_sdk]
         105  +
version = "0.27.1"
         106  +
features = ["metrics"]
   97    107   
   98    108   
[dev-dependencies]
   99    109   
arbitrary = "1.3"
  100    110   
bytes-utils = "0.1.2"
  101    111   
convert_case = "0.6.0"
  102    112   
proptest = "1.2"
  103    113   
serde_json = "1"
         114  +
serial_test = "3"
  104    115   
tracing-test = "0.2.4"
  105    116   
  106    117   
[dev-dependencies.aws-credential-types]
  107    118   
path = "../aws-credential-types"
  108    119   
features = ["test-util"]
  109         -
version = "1.2.9"
         120  +
version = "1.2.10"
  110    121   
  111    122   
[dev-dependencies.aws-smithy-async]
  112    123   
path = "../aws-smithy-async"
  113    124   
features = ["test-util"]
  114    125   
version = "1.2.6"
  115    126   
  116    127   
[dev-dependencies.aws-smithy-protocol-test]
  117    128   
path = "../aws-smithy-protocol-test"
  118    129   
version = "0.63.6"
  119    130   

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/src/endpoint_override.rs

@@ -0,1 +0,159 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! Endpoint override detection for business metrics tracking
           7  +
           8  +
use aws_smithy_runtime_api::box_error::BoxError;
           9  +
use aws_smithy_runtime_api::client::interceptors::context::BeforeTransmitInterceptorContextRef;
          10  +
use aws_smithy_runtime_api::client::interceptors::Intercept;
          11  +
use aws_smithy_runtime_api::client::runtime_components::RuntimeComponents;
          12  +
use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin;
          13  +
use aws_smithy_types::config_bag::{ConfigBag, FrozenLayer, Layer};
          14  +
          15  +
use crate::sdk_feature::AwsSdkFeature;
          16  +
          17  +
/// Interceptor that detects custom endpoint URLs for business metrics
          18  +
///
          19  +
/// This interceptor checks at runtime if a `StaticUriEndpointResolver` is configured,
          20  +
/// which indicates that `.endpoint_url()` was called. When detected, it stores the
          21  +
/// `AwsSdkFeature::EndpointOverride` feature flag for business metrics tracking.
          22  +
#[derive(Debug, Default)]
          23  +
#[non_exhaustive]
          24  +
pub struct EndpointOverrideInterceptor;
          25  +
          26  +
impl EndpointOverrideInterceptor {
          27  +
    /// Creates a new EndpointOverrideInterceptor
          28  +
    pub fn new() -> Self {
          29  +
        Self
          30  +
    }
          31  +
}
          32  +
          33  +
impl Intercept for EndpointOverrideInterceptor {
          34  +
    fn name(&self) -> &'static str {
          35  +
        "EndpointOverrideInterceptor"
          36  +
    }
          37  +
          38  +
    fn read_after_serialization(
          39  +
        &self,
          40  +
        _context: &BeforeTransmitInterceptorContextRef<'_>,
          41  +
        runtime_components: &RuntimeComponents,
          42  +
        cfg: &mut ConfigBag,
          43  +
    ) -> Result<(), BoxError> {
          44  +
        // Check if the endpoint resolver is a StaticUriEndpointResolver
          45  +
        // This indicates that .endpoint_url() was called
          46  +
        let resolver = runtime_components.endpoint_resolver();
          47  +
          48  +
        // Check the resolver's debug string to see if it's StaticUriEndpointResolver
          49  +
        let debug_str = format!("{:?}", resolver);
          50  +
          51  +
        if debug_str.contains("StaticUriEndpointResolver") {
          52  +
            // Store in interceptor_state
          53  +
            cfg.interceptor_state()
          54  +
                .store_append(AwsSdkFeature::EndpointOverride);
          55  +
        }
          56  +
          57  +
        Ok(())
          58  +
    }
          59  +
}
          60  +
          61  +
/// Runtime plugin that detects when a custom endpoint URL has been configured
          62  +
/// and tracks it for business metrics.
          63  +
///
          64  +
/// This plugin is created by the codegen decorator when a user explicitly
          65  +
/// sets an endpoint URL via `.endpoint_url()`. It stores the
          66  +
/// `AwsSdkFeature::EndpointOverride` feature flag in the ConfigBag for
          67  +
/// business metrics tracking.
          68  +
#[derive(Debug, Default)]
          69  +
#[non_exhaustive]
          70  +
pub struct EndpointOverrideRuntimePlugin {
          71  +
    config: Option<FrozenLayer>,
          72  +
}
          73  +
          74  +
impl EndpointOverrideRuntimePlugin {
          75  +
    /// Creates a new `EndpointOverrideRuntimePlugin` with the given config layer
          76  +
    pub fn new(config: Option<FrozenLayer>) -> Self {
          77  +
        Self { config }
          78  +
    }
          79  +
          80  +
    /// Creates a new `EndpointOverrideRuntimePlugin` and marks that endpoint override is enabled
          81  +
    pub fn new_with_feature_flag() -> Self {
          82  +
        let mut layer = Layer::new("endpoint_override");
          83  +
        layer.store_append(AwsSdkFeature::EndpointOverride);
          84  +
        Self {
          85  +
            config: Some(layer.freeze()),
          86  +
        }
          87  +
    }
          88  +
}
          89  +
          90  +
impl RuntimePlugin for EndpointOverrideRuntimePlugin {
          91  +
    fn config(&self) -> Option<FrozenLayer> {
          92  +
        self.config.clone()
          93  +
    }
          94  +
}
          95  +
          96  +
#[cfg(test)]
          97  +
mod tests {
          98  +
    use super::*;
          99  +
    use crate::sdk_feature::AwsSdkFeature;
         100  +
         101  +
    #[test]
         102  +
    fn test_plugin_with_no_config() {
         103  +
        let plugin = EndpointOverrideRuntimePlugin::default();
         104  +
        assert!(plugin.config().is_none());
         105  +
    }
         106  +
         107  +
    #[test]
         108  +
    fn test_plugin_with_feature_flag() {
         109  +
        let plugin = EndpointOverrideRuntimePlugin::new_with_feature_flag();
         110  +
        let config = plugin.config().expect("config should be set");
         111  +
         112  +
        // Verify the feature flag is present in the config
         113  +
        let features: Vec<_> = config.load::<AwsSdkFeature>().cloned().collect();
         114  +
        assert_eq!(features.len(), 1);
         115  +
        assert_eq!(features[0], AwsSdkFeature::EndpointOverride);
         116  +
    }
         117  +
         118  +
    #[test]
         119  +
    fn test_interceptor_detects_static_uri_resolver() {
         120  +
        use aws_smithy_runtime::client::orchestrator::endpoints::StaticUriEndpointResolver;
         121  +
        use aws_smithy_runtime_api::client::endpoint::SharedEndpointResolver;
         122  +
        use aws_smithy_runtime_api::client::interceptors::context::{Input, InterceptorContext};
         123  +
        use aws_smithy_runtime_api::client::orchestrator::HttpRequest;
         124  +
        use aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder;
         125  +
        use aws_smithy_types::config_bag::ConfigBag;
         126  +
         127  +
        // Create a StaticUriEndpointResolver
         128  +
        let endpoint_resolver = SharedEndpointResolver::new(StaticUriEndpointResolver::uri(
         129  +
            "https://custom.example.com",
         130  +
        ));
         131  +
         132  +
        let mut context = InterceptorContext::new(Input::doesnt_matter());
         133  +
        context.enter_serialization_phase();
         134  +
        context.set_request(HttpRequest::empty());
         135  +
        let _ = context.take_input();
         136  +
        context.enter_before_transmit_phase();
         137  +
         138  +
        let rc = RuntimeComponentsBuilder::for_tests()
         139  +
            .with_endpoint_resolver(Some(endpoint_resolver))
         140  +
            .build()
         141  +
            .unwrap();
         142  +
        let mut cfg = ConfigBag::base();
         143  +
         144  +
        let interceptor = EndpointOverrideInterceptor::new();
         145  +
        let ctx = Into::into(&context);
         146  +
        interceptor
         147  +
            .read_after_serialization(&ctx, &rc, &mut cfg)
         148  +
            .unwrap();
         149  +
         150  +
        // Verify the feature flag was set
         151  +
        let features: Vec<_> = cfg
         152  +
            .interceptor_state()
         153  +
            .load::<AwsSdkFeature>()
         154  +
            .cloned()
         155  +
            .collect();
         156  +
        assert_eq!(features.len(), 1, "Expected 1 feature, got: {features:?}");
         157  +
        assert_eq!(features[0], AwsSdkFeature::EndpointOverride);
         158  +
    }
         159  +
}

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/src/env_config/section.rs

@@ -265,265 +325,325 @@
  285    285   
  286    286   
    /// Run all tests from `test-data/profile-parser-tests.json`
  287    287   
    ///
  288    288   
    /// These represent the bulk of the test cases and reach 100% coverage of the parser.
  289    289   
    #[test]
  290    290   
    #[traced_test]
  291    291   
    fn run_tests() -> Result<(), Box<dyn Error>> {
  292    292   
        let tests = fs::read_to_string("test-data/profile-parser-tests.json")?;
  293    293   
        let tests: ParserTests = serde_json::from_str(&tests)?;
  294    294   
        for (i, test) in tests.tests.into_iter().enumerate() {
  295         -
            eprintln!("test: {}", i);
         295  +
            eprintln!("test: {i}");
  296    296   
            check(test);
  297    297   
        }
  298    298   
        Ok(())
  299    299   
    }
  300    300   
  301    301   
    #[test]
  302    302   
    fn empty_source_empty_profile() {
  303    303   
        let source = make_source(ParserInput {
  304    304   
            config_file: Some("".to_string()),
  305    305   
            credentials_file: Some("".to_string()),
@@ -405,405 +480,480 @@
  425    425   
                    ))
  426    426   
                } else if sso_sessions != &actual_sso_sessions {
  427    427   
                    Err(format!(
  428    428   
                        "mismatched sso_sessions:\nExpected: {sso_sessions:#?}\nActual: {actual_sso_sessions:#?}",
  429    429   
                    ))
  430    430   
                } else {
  431    431   
                    Ok(())
  432    432   
                }
  433    433   
            }
  434    434   
            (Err(msg), ParserOutput::ErrorContaining(substr)) => {
  435         -
                if format!("{}", msg).contains(substr) {
         435  +
                if format!("{msg}").contains(substr) {
  436    436   
                    Ok(())
  437    437   
                } else {
  438         -
                    Err(format!("Expected {} to contain {}", msg, substr))
         438  +
                    Err(format!("Expected {msg} to contain {substr}"))
  439    439   
                }
  440    440   
            }
  441    441   
            (Ok(output), ParserOutput::ErrorContaining(err)) => Err(format!(
  442    442   
                "expected an error: {err} but parse succeeded:\n{output:#?}",
  443    443   
            )),
  444    444   
            (Err(err), ParserOutput::Config { .. }) => {
  445         -
                Err(format!("Expected to succeed but got: {}", err))
         445  +
                Err(format!("Expected to succeed but got: {err}"))
  446    446   
            }
  447    447   
        };
  448    448   
        if let Err(e) = res {
  449         -
            eprintln!("Test case failed: {:#?}", copy);
  450         -
            eprintln!("failure: {}", e);
         449  +
            eprintln!("Test case failed: {copy:#?}");
         450  +
            eprintln!("failure: {e}");
  451    451   
            panic!("test failed")
  452    452   
        }
  453    453   
    }
  454    454   
  455    455   
    #[derive(Deserialize, Debug)]
  456    456   
    #[serde(rename_all = "camelCase")]
  457    457   
    struct ParserTests {
  458    458   
        tests: Vec<ParserTest>,
  459    459   
    }
  460    460   

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/src/env_config/source.rs

@@ -218,218 +278,278 @@
  238    238   
        config_location: String,
  239    239   
        credentials_location: String,
  240    240   
    }
  241    241   
  242    242   
    /// Run all tests from file-location-tests.json
  243    243   
    #[test]
  244    244   
    fn run_tests() -> Result<(), Box<dyn Error>> {
  245    245   
        let tests = fs::read_to_string("test-data/file-location-tests.json")?;
  246    246   
        let tests: SourceTests = serde_json::from_str(&tests)?;
  247    247   
        for (i, test) in tests.tests.into_iter().enumerate() {
  248         -
            eprintln!("test: {}", i);
         248  +
            eprintln!("test: {i}");
  249    249   
            check(test)
  250    250   
                .now_or_never()
  251    251   
                .expect("these futures should never poll");
  252    252   
        }
  253    253   
        Ok(())
  254    254   
    }
  255    255   
  256    256   
    #[traced_test]
  257    257   
    #[test]
  258    258   
    fn logs_produced_default() {

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/src/lib.rs

@@ -1,1 +53,59 @@
   19     19   
/// Supporting code for authentication in the AWS SDK.
   20     20   
pub mod auth;
   21     21   
   22     22   
/// AWS-specific content-encoding tools
   23     23   
#[cfg(feature = "http-02x")]
   24     24   
pub mod content_encoding;
   25     25   
   26     26   
/// Supporting code for recursion detection in the AWS SDK.
   27     27   
pub mod recursion_detection;
   28     28   
          29  +
/// Supporting code for endpoint override detection in the AWS SDK.
          30  +
pub mod endpoint_override;
          31  +
          32  +
/// Supporting code for observability feature detection in the AWS SDK.
          33  +
pub mod observability_detection;
          34  +
   29     35   
/// Supporting code for user agent headers in the AWS SDK.
   30     36   
pub mod user_agent;
   31     37   
   32     38   
/// Supporting code for retry behavior specific to the AWS SDK.
   33     39   
pub mod retries;
   34     40   
   35     41   
/// Supporting code for invocation ID headers in the AWS SDK.
   36     42   
pub mod invocation_id;
   37     43   
   38     44   
/// Supporting code for request metadata headers in the AWS SDK.

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/src/observability_detection.rs

@@ -0,1 +0,602 @@
           1  +
/*
           2  +
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
           3  +
 * SPDX-License-Identifier: Apache-2.0
           4  +
 */
           5  +
           6  +
//! Observability feature detection for business metrics tracking
           7  +
//!
           8  +
//! This module provides an interceptor for detecting observability features in the AWS SDK:
           9  +
//!
          10  +
//! - [`ObservabilityDetectionInterceptor`]: Detects observability features during
          11  +
//!   request processing and tracks them for business metrics in the User-Agent header.
          12  +
          13  +
#[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
          14  +
use crate::sdk_feature::AwsSdkFeature;
          15  +
#[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
          16  +
use aws_smithy_observability_otel::meter::OtelMeterProvider;
          17  +
#[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
          18  +
use aws_smithy_runtime::client::sdk_feature::SmithySdkFeature;
          19  +
use aws_smithy_runtime_api::box_error::BoxError;
          20  +
use aws_smithy_runtime_api::client::interceptors::context::BeforeTransmitInterceptorContextRef;
          21  +
use aws_smithy_runtime_api::client::interceptors::Intercept;
          22  +
use aws_smithy_runtime_api::client::runtime_components::RuntimeComponents;
          23  +
use aws_smithy_types::config_bag::ConfigBag;
          24  +
          25  +
/// Interceptor that detects when observability features are being used
          26  +
/// and tracks them for business metrics.
          27  +
#[derive(Debug, Default)]
          28  +
#[non_exhaustive]
          29  +
pub struct ObservabilityDetectionInterceptor;
          30  +
          31  +
impl ObservabilityDetectionInterceptor {
          32  +
    /// Creates a new `ObservabilityDetectionInterceptor`
          33  +
    pub fn new() -> Self {
          34  +
        Self
          35  +
    }
          36  +
}
          37  +
          38  +
impl Intercept for ObservabilityDetectionInterceptor {
          39  +
    fn name(&self) -> &'static str {
          40  +
        "ObservabilityDetectionInterceptor"
          41  +
    }
          42  +
          43  +
    fn read_before_signing(
          44  +
        &self,
          45  +
        _context: &BeforeTransmitInterceptorContextRef<'_>,
          46  +
        _runtime_components: &RuntimeComponents,
          47  +
        _cfg: &mut ConfigBag,
          48  +
    ) -> Result<(), BoxError> {
          49  +
        #[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
          50  +
        {
          51  +
            // Try to get the global telemetry provider
          52  +
            if let Ok(provider) = aws_smithy_observability::global::get_telemetry_provider() {
          53  +
                let meter_provider = provider.meter_provider();
          54  +
          55  +
                // Check if this is an OpenTelemetry meter provider
          56  +
                let is_otel = meter_provider
          57  +
                    .as_any()
          58  +
                    .downcast_ref::<OtelMeterProvider>()
          59  +
                    .is_some();
          60  +
          61  +
                // Check if this is a noop provider (we don't want to track noop)
          62  +
                let is_noop = meter_provider
          63  +
                    .as_any()
          64  +
                    .downcast_ref::<aws_smithy_observability::noop::NoopMeterProvider>()
          65  +
                    .is_some();
          66  +
          67  +
                if !is_noop {
          68  +
                    // Track generic observability metrics (for any non-noop provider)
          69  +
                    _cfg.interceptor_state()
          70  +
                        .store_append(SmithySdkFeature::ObservabilityMetrics);
          71  +
          72  +
                    // If it's specifically OpenTelemetry, track that too
          73  +
                    if is_otel {
          74  +
                        _cfg.interceptor_state()
          75  +
                            .store_append(AwsSdkFeature::ObservabilityOtelMetrics);
          76  +
                    }
          77  +
                }
          78  +
            }
          79  +
        }
          80  +
          81  +
        Ok(())
          82  +
    }
          83  +
}
          84  +
          85  +
#[cfg(test)]
          86  +
mod tests {
          87  +
    use super::*;
          88  +
    use crate::sdk_feature::AwsSdkFeature;
          89  +
    use aws_smithy_observability::TelemetryProvider;
          90  +
    use aws_smithy_runtime_api::client::interceptors::context::{Input, InterceptorContext};
          91  +
    use aws_smithy_runtime_api::client::orchestrator::HttpRequest;
          92  +
    use aws_smithy_runtime_api::client::runtime_components::RuntimeComponentsBuilder;
          93  +
    use aws_smithy_types::config_bag::ConfigBag;
          94  +
          95  +
    #[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
          96  +
    #[test]
          97  +
    #[serial_test::serial]
          98  +
    fn test_detects_noop_provider() {
          99  +
        let mut context = InterceptorContext::new(Input::doesnt_matter());
         100  +
        context.enter_serialization_phase();
         101  +
        context.set_request(HttpRequest::empty());
         102  +
        let _ = context.take_input();
         103  +
        context.enter_before_transmit_phase();
         104  +
         105  +
        let rc = RuntimeComponentsBuilder::for_tests().build().unwrap();
         106  +
        let mut cfg = ConfigBag::base();
         107  +
         108  +
        // Set a noop provider (ignore error if already set by another test)
         109  +
        let _ = aws_smithy_observability::global::set_telemetry_provider(TelemetryProvider::noop());
         110  +
         111  +
        let interceptor = ObservabilityDetectionInterceptor::new();
         112  +
        let ctx = Into::into(&context);
         113  +
        interceptor
         114  +
            .read_before_signing(&ctx, &rc, &mut cfg)
         115  +
            .unwrap();
         116  +
         117  +
        // Should not track any features for noop provider
         118  +
        let smithy_features: Vec<_> = cfg
         119  +
            .interceptor_state()
         120  +
            .load::<SmithySdkFeature>()
         121  +
            .cloned()
         122  +
            .collect();
         123  +
        assert_eq!(
         124  +
            smithy_features.len(),
         125  +
            0,
         126  +
            "Should not track Smithy features for noop provider"
         127  +
        );
         128  +
         129  +
        let aws_features: Vec<_> = cfg
         130  +
            .interceptor_state()
         131  +
            .load::<AwsSdkFeature>()
         132  +
            .cloned()
         133  +
            .collect();
         134  +
        assert_eq!(
         135  +
            aws_features.len(),
         136  +
            0,
         137  +
            "Should not track AWS features for noop provider"
         138  +
        );
         139  +
    }
         140  +
         141  +
    #[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
         142  +
    #[test]
         143  +
    #[serial_test::serial]
         144  +
    fn test_custom_provider_not_detected_as_otel() {
         145  +
        use aws_smithy_observability::meter::{Meter, ProvideMeter};
         146  +
        use aws_smithy_observability::noop::NoopMeterProvider;
         147  +
        use aws_smithy_observability::Attributes;
         148  +
        use std::sync::Arc;
         149  +
         150  +
        // Create a custom (non-OTel, non-noop) meter provider
         151  +
        // This simulates a user implementing their own metrics provider
         152  +
        #[derive(Debug)]
         153  +
        struct CustomMeterProvider {
         154  +
            inner: NoopMeterProvider,
         155  +
        }
         156  +
         157  +
        impl ProvideMeter for CustomMeterProvider {
         158  +
            fn get_meter(&self, scope: &'static str, attributes: Option<&Attributes>) -> Meter {
         159  +
                // Delegate to noop for simplicity, but this is a distinct type
         160  +
                self.inner.get_meter(scope, attributes)
         161  +
            }
         162  +
         163  +
            fn as_any(&self) -> &dyn std::any::Any {
         164  +
                self
         165  +
            }
         166  +
        }
         167  +
         168  +
        let mut context = InterceptorContext::new(Input::doesnt_matter());
         169  +
        context.enter_serialization_phase();
         170  +
        context.set_request(HttpRequest::empty());
         171  +
        let _ = context.take_input();
         172  +
        context.enter_before_transmit_phase();
         173  +
         174  +
        let rc = RuntimeComponentsBuilder::for_tests().build().unwrap();
         175  +
        let mut cfg = ConfigBag::base();
         176  +
         177  +
        // Set the custom provider
         178  +
        let custom_provider = Arc::new(CustomMeterProvider {
         179  +
            inner: NoopMeterProvider,
         180  +
        });
         181  +
        let telemetry_provider = TelemetryProvider::builder()
         182  +
            .meter_provider(custom_provider)
         183  +
            .build();
         184  +
        let _ = aws_smithy_observability::global::set_telemetry_provider(telemetry_provider);
         185  +
         186  +
        let interceptor = ObservabilityDetectionInterceptor::new();
         187  +
        let ctx = Into::into(&context);
         188  +
        interceptor
         189  +
            .read_before_signing(&ctx, &rc, &mut cfg)
         190  +
            .unwrap();
         191  +
         192  +
        // Should track generic observability metrics for custom provider
         193  +
        let smithy_features: Vec<_> = cfg
         194  +
            .interceptor_state()
         195  +
            .load::<SmithySdkFeature>()
         196  +
            .cloned()
         197  +
            .collect();
         198  +
        assert!(
         199  +
            smithy_features.contains(&SmithySdkFeature::ObservabilityMetrics),
         200  +
            "Should detect custom provider as having observability metrics"
         201  +
        );
         202  +
         203  +
        // Should NOT track AWS-specific observability metrics for custom provider
         204  +
        let aws_features: Vec<_> = cfg
         205  +
            .interceptor_state()
         206  +
            .load::<AwsSdkFeature>()
         207  +
            .cloned()
         208  +
            .collect();
         209  +
        assert!(
         210  +
            !aws_features.contains(&AwsSdkFeature::ObservabilityOtelMetrics),
         211  +
            "Should NOT track OTel-specific metrics for custom provider"
         212  +
        );
         213  +
        assert_eq!(
         214  +
            aws_features.len(),
         215  +
            0,
         216  +
            "Should not track any AWS-specific features for custom provider"
         217  +
        );
         218  +
    }
         219  +
         220  +
    #[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
         221  +
    #[test]
         222  +
    #[serial_test::serial]
         223  +
    fn test_detects_otel_provider() {
         224  +
        use aws_smithy_observability_otel::meter::OtelMeterProvider;
         225  +
        use opentelemetry_sdk::metrics::SdkMeterProvider;
         226  +
        use std::sync::Arc;
         227  +
         228  +
        let mut context = InterceptorContext::new(Input::doesnt_matter());
         229  +
        context.enter_serialization_phase();
         230  +
        context.set_request(HttpRequest::empty());
         231  +
        let _ = context.take_input();
         232  +
        context.enter_before_transmit_phase();
         233  +
         234  +
        let rc = RuntimeComponentsBuilder::for_tests().build().unwrap();
         235  +
        let mut cfg = ConfigBag::base();
         236  +
         237  +
        // Create an actual OpenTelemetry meter provider
         238  +
        let otel_sdk_provider = SdkMeterProvider::builder().build();
         239  +
        let otel_provider = Arc::new(OtelMeterProvider::new(otel_sdk_provider));
         240  +
        let telemetry_provider = TelemetryProvider::builder()
         241  +
            .meter_provider(otel_provider)
         242  +
            .build();
         243  +
        let _ = aws_smithy_observability::global::set_telemetry_provider(telemetry_provider);
         244  +
         245  +
        let interceptor = ObservabilityDetectionInterceptor::new();
         246  +
        let ctx = Into::into(&context);
         247  +
        interceptor
         248  +
            .read_before_signing(&ctx, &rc, &mut cfg)
         249  +
            .unwrap();
         250  +
         251  +
        // Should track generic observability metrics for OTel provider
         252  +
        let smithy_features: Vec<_> = cfg
         253  +
            .interceptor_state()
         254  +
            .load::<SmithySdkFeature>()
         255  +
            .cloned()
         256  +
            .collect();
         257  +
        assert!(
         258  +
            smithy_features.contains(&SmithySdkFeature::ObservabilityMetrics),
         259  +
            "Should detect OTel provider as having observability metrics"
         260  +
        );
         261  +
         262  +
        // Should ALSO track AWS-specific OTel observability metrics
         263  +
        let aws_features: Vec<_> = cfg
         264  +
            .interceptor_state()
         265  +
            .load::<AwsSdkFeature>()
         266  +
            .cloned()
         267  +
            .collect();
         268  +
        assert!(
         269  +
            aws_features.contains(&AwsSdkFeature::ObservabilityOtelMetrics),
         270  +
            "Should track OTel-specific metrics for OTel provider"
         271  +
        );
         272  +
    }
         273  +
         274  +
    // Edge case tests
         275  +
         276  +
    #[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
         277  +
    #[test]
         278  +
    #[serial_test::serial]
         279  +
    fn test_multiple_provider_changes() {
         280  +
        use aws_smithy_observability::meter::{Meter, ProvideMeter};
         281  +
        use aws_smithy_observability::noop::NoopMeterProvider;
         282  +
        use aws_smithy_observability::Attributes;
         283  +
        use aws_smithy_observability_otel::meter::OtelMeterProvider;
         284  +
        use opentelemetry_sdk::metrics::SdkMeterProvider;
         285  +
        use std::sync::Arc;
         286  +
         287  +
        #[derive(Debug)]
         288  +
        struct CustomMeterProvider {
         289  +
            inner: NoopMeterProvider,
         290  +
        }
         291  +
         292  +
        impl ProvideMeter for CustomMeterProvider {
         293  +
            fn get_meter(&self, scope: &'static str, attributes: Option<&Attributes>) -> Meter {
         294  +
                self.inner.get_meter(scope, attributes)
         295  +
            }
         296  +
         297  +
            fn as_any(&self) -> &dyn std::any::Any {
         298  +
                self
         299  +
            }
         300  +
        }
         301  +
         302  +
        let interceptor = ObservabilityDetectionInterceptor::new();
         303  +
        let rc = RuntimeComponentsBuilder::for_tests().build().unwrap();
         304  +
         305  +
        // Test 1: Start with noop provider
         306  +
        let _ = aws_smithy_observability::global::set_telemetry_provider(TelemetryProvider::noop());
         307  +
         308  +
        let mut context1 = InterceptorContext::new(Input::doesnt_matter());
         309  +
        context1.enter_serialization_phase();
         310  +
        context1.set_request(HttpRequest::empty());
         311  +
        let _ = context1.take_input();
         312  +
        context1.enter_before_transmit_phase();
         313  +
        let mut cfg1 = ConfigBag::base();
         314  +
         315  +
        interceptor
         316  +
            .read_before_signing(&Into::into(&context1), &rc, &mut cfg1)
         317  +
            .unwrap();
         318  +
         319  +
        let smithy_features: Vec<_> = cfg1
         320  +
            .interceptor_state()
         321  +
            .load::<SmithySdkFeature>()
         322  +
            .cloned()
         323  +
            .collect();
         324  +
        assert_eq!(
         325  +
            smithy_features.len(),
         326  +
            0,
         327  +
            "Noop provider should not be tracked"
         328  +
        );
         329  +
         330  +
        // Test 2: Switch to custom provider
         331  +
        let custom_provider = Arc::new(CustomMeterProvider {
         332  +
            inner: NoopMeterProvider,
         333  +
        });
         334  +
        let telemetry_provider = TelemetryProvider::builder()
         335  +
            .meter_provider(custom_provider)
         336  +
            .build();
         337  +
        let _ = aws_smithy_observability::global::set_telemetry_provider(telemetry_provider);
         338  +
         339  +
        let mut context2 = InterceptorContext::new(Input::doesnt_matter());
         340  +
        context2.enter_serialization_phase();
         341  +
        context2.set_request(HttpRequest::empty());
         342  +
        let _ = context2.take_input();
         343  +
        context2.enter_before_transmit_phase();
         344  +
        let mut cfg2 = ConfigBag::base();
         345  +
         346  +
        interceptor
         347  +
            .read_before_signing(&Into::into(&context2), &rc, &mut cfg2)
         348  +
            .unwrap();
         349  +
         350  +
        let smithy_features: Vec<_> = cfg2
         351  +
            .interceptor_state()
         352  +
            .load::<SmithySdkFeature>()
         353  +
            .cloned()
         354  +
            .collect();
         355  +
        assert!(
         356  +
            smithy_features.contains(&SmithySdkFeature::ObservabilityMetrics),
         357  +
            "Custom provider should be tracked"
         358  +
        );
         359  +
        let aws_features: Vec<_> = cfg2
         360  +
            .interceptor_state()
         361  +
            .load::<AwsSdkFeature>()
         362  +
            .cloned()
         363  +
            .collect();
         364  +
        assert_eq!(
         365  +
            aws_features.len(),
         366  +
            0,
         367  +
            "Custom provider should not have OTel features"
         368  +
        );
         369  +
         370  +
        // Test 3: Switch to OTel provider
         371  +
        let otel_sdk_provider = SdkMeterProvider::builder().build();
         372  +
        let otel_provider = Arc::new(OtelMeterProvider::new(otel_sdk_provider));
         373  +
        let telemetry_provider = TelemetryProvider::builder()
         374  +
            .meter_provider(otel_provider)
         375  +
            .build();
         376  +
        let _ = aws_smithy_observability::global::set_telemetry_provider(telemetry_provider);
         377  +
         378  +
        let mut context3 = InterceptorContext::new(Input::doesnt_matter());
         379  +
        context3.enter_serialization_phase();
         380  +
        context3.set_request(HttpRequest::empty());
         381  +
        let _ = context3.take_input();
         382  +
        context3.enter_before_transmit_phase();
         383  +
        let mut cfg3 = ConfigBag::base();
         384  +
         385  +
        interceptor
         386  +
            .read_before_signing(&Into::into(&context3), &rc, &mut cfg3)
         387  +
            .unwrap();
         388  +
         389  +
        let smithy_features: Vec<_> = cfg3
         390  +
            .interceptor_state()
         391  +
            .load::<SmithySdkFeature>()
         392  +
            .cloned()
         393  +
            .collect();
         394  +
        assert!(
         395  +
            smithy_features.contains(&SmithySdkFeature::ObservabilityMetrics),
         396  +
            "OTel provider should be tracked"
         397  +
        );
         398  +
        let aws_features: Vec<_> = cfg3
         399  +
            .interceptor_state()
         400  +
            .load::<AwsSdkFeature>()
         401  +
            .cloned()
         402  +
            .collect();
         403  +
        assert!(
         404  +
            aws_features.contains(&AwsSdkFeature::ObservabilityOtelMetrics),
         405  +
            "OTel provider should have OTel features"
         406  +
        );
         407  +
    }
         408  +
         409  +
    #[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
         410  +
    #[test]
         411  +
    #[serial_test::serial]
         412  +
    fn test_multiple_invocations_same_provider() {
         413  +
        use aws_smithy_observability::meter::{Meter, ProvideMeter};
         414  +
        use aws_smithy_observability::noop::NoopMeterProvider;
         415  +
        use aws_smithy_observability::Attributes;
         416  +
        use std::sync::Arc;
         417  +
         418  +
        #[derive(Debug)]
         419  +
        struct CustomMeterProvider {
         420  +
            inner: NoopMeterProvider,
         421  +
        }
         422  +
         423  +
        impl ProvideMeter for CustomMeterProvider {
         424  +
            fn get_meter(&self, scope: &'static str, attributes: Option<&Attributes>) -> Meter {
         425  +
                self.inner.get_meter(scope, attributes)
         426  +
            }
         427  +
         428  +
            fn as_any(&self) -> &dyn std::any::Any {
         429  +
                self
         430  +
            }
         431  +
        }
         432  +
         433  +
        // Set up a custom provider
         434  +
        let custom_provider = Arc::new(CustomMeterProvider {
         435  +
            inner: NoopMeterProvider,
         436  +
        });
         437  +
        let telemetry_provider = TelemetryProvider::builder()
         438  +
            .meter_provider(custom_provider)
         439  +
            .build();
         440  +
        let _ = aws_smithy_observability::global::set_telemetry_provider(telemetry_provider);
         441  +
         442  +
        let interceptor = ObservabilityDetectionInterceptor::new();
         443  +
        let rc = RuntimeComponentsBuilder::for_tests().build().unwrap();
         444  +
         445  +
        // Invoke interceptor multiple times with the same provider
         446  +
        for i in 0..3 {
         447  +
            let mut context = InterceptorContext::new(Input::doesnt_matter());
         448  +
            context.enter_serialization_phase();
         449  +
            context.set_request(HttpRequest::empty());
         450  +
            let _ = context.take_input();
         451  +
            context.enter_before_transmit_phase();
         452  +
            let mut cfg = ConfigBag::base();
         453  +
         454  +
            interceptor
         455  +
                .read_before_signing(&Into::into(&context), &rc, &mut cfg)
         456  +
                .unwrap();
         457  +
         458  +
            // Each invocation should detect the provider consistently
         459  +
            let smithy_features: Vec<_> = cfg
         460  +
                .interceptor_state()
         461  +
                .load::<SmithySdkFeature>()
         462  +
                .cloned()
         463  +
                .collect();
         464  +
            assert!(
         465  +
                smithy_features.contains(&SmithySdkFeature::ObservabilityMetrics),
         466  +
                "Invocation {} should detect custom provider",
         467  +
                i
         468  +
            );
         469  +
            let aws_features: Vec<_> = cfg
         470  +
                .interceptor_state()
         471  +
                .load::<AwsSdkFeature>()
         472  +
                .cloned()
         473  +
                .collect();
         474  +
            assert_eq!(
         475  +
                aws_features.len(),
         476  +
                0,
         477  +
                "Invocation {} should not have OTel features for custom provider",
         478  +
                i
         479  +
            );
         480  +
        }
         481  +
    }
         482  +
         483  +
    #[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
         484  +
    #[test]
         485  +
    #[serial_test::serial]
         486  +
    fn test_interceptor_handles_errors_gracefully() {
         487  +
        // This test verifies that the interceptor doesn't panic or fail
         488  +
        // when the global provider is in various states
         489  +
         490  +
        let interceptor = ObservabilityDetectionInterceptor::new();
         491  +
        let rc = RuntimeComponentsBuilder::for_tests().build().unwrap();
         492  +
         493  +
        // Test with noop provider (should succeed without tracking)
         494  +
        let _ = aws_smithy_observability::global::set_telemetry_provider(TelemetryProvider::noop());
         495  +
         496  +
        let mut context = InterceptorContext::new(Input::doesnt_matter());
         497  +
        context.enter_serialization_phase();
         498  +
        context.set_request(HttpRequest::empty());
         499  +
        let _ = context.take_input();
         500  +
        context.enter_before_transmit_phase();
         501  +
        let mut cfg = ConfigBag::base();
         502  +
         503  +
        // Should not return an error
         504  +
        let result = interceptor.read_before_signing(&Into::into(&context), &rc, &mut cfg);
         505  +
        assert!(
         506  +
            result.is_ok(),
         507  +
            "Interceptor should handle noop provider gracefully"
         508  +
        );
         509  +
         510  +
        // Verify no features were tracked
         511  +
        let smithy_features: Vec<_> = cfg
         512  +
            .interceptor_state()
         513  +
            .load::<SmithySdkFeature>()
         514  +
            .cloned()
         515  +
            .collect();
         516  +
        assert_eq!(
         517  +
            smithy_features.len(),
         518  +
            0,
         519  +
            "Should not track features for noop provider"
         520  +
        );
         521  +
    }
         522  +
         523  +
    #[cfg(all(not(target_arch = "powerpc"), not(target_family = "wasm")))]
         524  +
    #[test]
         525  +
    #[serial_test::serial]
         526  +
    fn test_interceptor_with_default_constructor() {
         527  +
        use aws_smithy_observability::meter::{Meter, ProvideMeter};
         528  +
        use aws_smithy_observability::noop::NoopMeterProvider;
         529  +
        use aws_smithy_observability::Attributes;
         530  +
        use std::sync::Arc;
         531  +
         532  +
        #[derive(Debug)]
         533  +
        struct CustomMeterProvider {
         534  +
            inner: NoopMeterProvider,
         535  +
        }
         536  +
         537  +
        impl ProvideMeter for CustomMeterProvider {
         538  +
            fn get_meter(&self, scope: &'static str, attributes: Option<&Attributes>) -> Meter {
         539  +
                self.inner.get_meter(scope, attributes)
         540  +
            }
         541  +
         542  +
            fn as_any(&self) -> &dyn std::any::Any {
         543  +
                self
         544  +
            }
         545  +
        }
         546  +
         547  +
        // Set up a custom provider
         548  +
        let custom_provider = Arc::new(CustomMeterProvider {
         549  +
            inner: NoopMeterProvider,
         550  +
        });
         551  +
        let telemetry_provider = TelemetryProvider::builder()
         552  +
            .meter_provider(custom_provider)
         553  +
            .build();
         554  +
        let _ = aws_smithy_observability::global::set_telemetry_provider(telemetry_provider);
         555  +
         556  +
        // Test both constructors produce equivalent behavior
         557  +
        let interceptor_new = ObservabilityDetectionInterceptor::new();
         558  +
        let interceptor_default = ObservabilityDetectionInterceptor::default();
         559  +
         560  +
        let rc = RuntimeComponentsBuilder::for_tests().build().unwrap();
         561  +
         562  +
        // Test with new()
         563  +
        let mut context1 = InterceptorContext::new(Input::doesnt_matter());
         564  +
        context1.enter_serialization_phase();
         565  +
        context1.set_request(HttpRequest::empty());
         566  +
        let _ = context1.take_input();
         567  +
        context1.enter_before_transmit_phase();
         568  +
        let mut cfg1 = ConfigBag::base();
         569  +
         570  +
        interceptor_new
         571  +
            .read_before_signing(&Into::into(&context1), &rc, &mut cfg1)
         572  +
            .unwrap();
         573  +
         574  +
        // Test with default()
         575  +
        let mut context2 = InterceptorContext::new(Input::doesnt_matter());
         576  +
        context2.enter_serialization_phase();
         577  +
        context2.set_request(HttpRequest::empty());
         578  +
        let _ = context2.take_input();
         579  +
        context2.enter_before_transmit_phase();
         580  +
        let mut cfg2 = ConfigBag::base();
         581  +
         582  +
        interceptor_default
         583  +
            .read_before_signing(&Into::into(&context2), &rc, &mut cfg2)
         584  +
            .unwrap();
         585  +
         586  +
        // Both should produce the same results
         587  +
        let smithy_features1: Vec<_> = cfg1
         588  +
            .interceptor_state()
         589  +
            .load::<SmithySdkFeature>()
         590  +
            .cloned()
         591  +
            .collect();
         592  +
        let smithy_features2: Vec<_> = cfg2
         593  +
            .interceptor_state()
         594  +
            .load::<SmithySdkFeature>()
         595  +
            .cloned()
         596  +
            .collect();
         597  +
        assert_eq!(
         598  +
            smithy_features1, smithy_features2,
         599  +
            "Both constructors should produce identical behavior"
         600  +
        );
         601  +
    }
         602  +
}

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/src/sdk_feature.rs

@@ -1,1 +31,37 @@
   17     17   
    /// An operation called with account ID mode set to disabled
   18     18   
    AccountIdModeDisabled,
   19     19   
    /// An operation called with account ID mode set to required
   20     20   
    AccountIdModeRequired,
   21     21   
    /// Indicates that an operation was called by the S3 Transfer Manager
   22     22   
    S3Transfer,
   23     23   
    /// Calling an SSO-OIDC operation as part of the SSO login flow, when using the OAuth2.0 device code grant
   24     24   
    SsoLoginDevice,
   25     25   
    /// Calling an SSO-OIDC operation as part of the SSO login flow, when using the OAuth2.0 authorization code grant
   26     26   
    SsoLoginAuth,
          27  +
    /// An operation called using a user provided endpoint URL
          28  +
    EndpointOverride,
          29  +
    /// An operation called with OpenTelemetry tracing integration enabled
          30  +
    ObservabilityOtelTracing,
          31  +
    /// An operation called with OpenTelemetry metrics integration enabled
          32  +
    ObservabilityOtelMetrics,
   27     33   
}
   28     34   
   29     35   
impl Storable for AwsSdkFeature {
   30     36   
    type Storer = StoreAppend<Self>;
   31     37   
}

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/src/user_agent/interceptor.rs

@@ -136,136 +206,219 @@
  156    156   
        &self,
  157    157   
        context: &mut BeforeTransmitInterceptorContextMut<'_>,
  158    158   
        runtime_components: &RuntimeComponents,
  159    159   
        cfg: &mut ConfigBag,
  160    160   
    ) -> Result<(), BoxError> {
  161    161   
        let mut ua = cfg
  162    162   
            .load::<AwsUserAgent>()
  163    163   
            .expect("`AwsUserAgent should have been created in `read_before_execution`")
  164    164   
            .clone();
  165    165   
  166         -
        let mut added_metrics = std::collections::HashSet::new();
  167         -
  168         -
        add_metrics_unique!(cfg.load::<SmithySdkFeature>(), &mut ua, &mut added_metrics);
  169         -
        add_metrics_unique!(cfg.load::<AwsSdkFeature>(), &mut ua, &mut added_metrics);
  170         -
        // The order we emit credential features matters.
  171         -
        // Reverse to preserve emission order since StoreAppend pops backwards.
  172         -
        add_metrics_unique_reverse!(
  173         -
            cfg.load::<AwsCredentialFeature>(),
  174         -
            &mut ua,
  175         -
            &mut added_metrics
  176         -
        );
         166  +
        // Load features from ConfigBag. Note: cfg.load() automatically captures features
         167  +
        // from all layers in the ConfigBag, including the interceptor_state layer where
         168  +
        // interceptors store their features. There is no need to separately call
         169  +
        // cfg.interceptor_state().load() as that would be redundant.
         170  +
        let smithy_sdk_features = cfg.load::<SmithySdkFeature>();
         171  +
        for smithy_sdk_feature in smithy_sdk_features {
         172  +
            smithy_sdk_feature
         173  +
                .provide_business_metric()
         174  +
                .map(|m| ua.add_business_metric(m));
         175  +
        }
         176  +
         177  +
        let aws_sdk_features = cfg.load::<AwsSdkFeature>();
         178  +
        for aws_sdk_feature in aws_sdk_features {
         179  +
            aws_sdk_feature
         180  +
                .provide_business_metric()
         181  +
                .map(|m| ua.add_business_metric(m));
         182  +
        }
         183  +
         184  +
        let aws_credential_features = cfg.load::<AwsCredentialFeature>();
         185  +
        for aws_credential_feature in aws_credential_features {
         186  +
            aws_credential_feature
         187  +
                .provide_business_metric()
         188  +
                .map(|m| ua.add_business_metric(m));
         189  +
        }
  177    190   
  178    191   
        let maybe_connector_metadata = runtime_components
  179    192   
            .http_client()
  180    193   
            .and_then(|c| c.connector_metadata());
  181    194   
        if let Some(connector_metadata) = maybe_connector_metadata {
  182    195   
            let am = AdditionalMetadata::new(Cow::Owned(connector_metadata.to_string()))?;
  183    196   
            ua.add_additional_metadata(am);
  184    197   
        }
  185    198   
  186    199   
        let headers = context.request_mut().headers_mut();
@@ -410,423 +440,486 @@
  430    443   
  431    444   
        let header = expect_header(&context, "user-agent");
  432    445   
        assert_eq!(AwsUserAgent::for_tests().ua_header(), header);
  433    446   
        assert!(!header.contains("unused"));
  434    447   
  435    448   
        assert_eq!(
  436    449   
            AwsUserAgent::for_tests().aws_ua_header(),
  437    450   
            expect_header(&context, "x-amz-user-agent")
  438    451   
        );
  439    452   
    }
         453  +
         454  +
    #[test]
         455  +
    fn test_cfg_load_captures_all_feature_layers() {
         456  +
        use crate::sdk_feature::AwsSdkFeature;
         457  +
         458  +
        // Create a ConfigBag with features in both base layer and interceptor_state
         459  +
        let mut base_layer = Layer::new("base");
         460  +
        base_layer.store_append(AwsSdkFeature::EndpointOverride);
         461  +
         462  +
        let mut config = ConfigBag::of_layers(vec![base_layer]);
         463  +
         464  +
        // Store a feature in interceptor_state (simulating what interceptors do)
         465  +
        config
         466  +
            .interceptor_state()
         467  +
            .store_append(AwsSdkFeature::SsoLoginDevice);
         468  +
         469  +
        // Verify that cfg.load() captures features from all layers
         470  +
        let all_features: Vec<&AwsSdkFeature> = config.load::<AwsSdkFeature>().collect();
         471  +
         472  +
        assert_eq!(
         473  +
            all_features.len(),
         474  +
            2,
         475  +
            "cfg.load() should capture features from all layers"
         476  +
        );
         477  +
        assert!(
         478  +
            all_features.contains(&&AwsSdkFeature::EndpointOverride),
         479  +
            "should contain feature from base layer"
         480  +
        );
         481  +
        assert!(
         482  +
            all_features.contains(&&AwsSdkFeature::SsoLoginDevice),
         483  +
            "should contain feature from interceptor_state"
         484  +
        );
         485  +
    }
  440    486   
}

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/src/user_agent/metrics.rs

@@ -137,137 +254,263 @@
  157    157   
    CredentialsProfileSsoLegacy,
  158    158   
    CredentialsSsoLegacy,
  159    159   
    CredentialsProfileProcess,
  160    160   
    CredentialsProcess,
  161    161   
    CredentialsBoto2ConfigFile,
  162    162   
    CredentialsAwsSdkStore,
  163    163   
    CredentialsHttp,
  164    164   
    CredentialsImds,
  165    165   
    SsoLoginDevice,
  166    166   
    SsoLoginAuth,
  167         -
    BearerServiceEnvVars
         167  +
    BearerServiceEnvVars,
         168  +
    ObservabilityTracing,
         169  +
    ObservabilityMetrics,
         170  +
    ObservabilityOtelTracing,
         171  +
    ObservabilityOtelMetrics
  168    172   
);
  169    173   
  170    174   
pub(crate) trait ProvideBusinessMetric {
  171    175   
    fn provide_business_metric(&self) -> Option<BusinessMetric>;
  172    176   
}
  173    177   
  174    178   
impl ProvideBusinessMetric for SmithySdkFeature {
  175    179   
    fn provide_business_metric(&self) -> Option<BusinessMetric> {
  176    180   
        use SmithySdkFeature::*;
  177    181   
        match self {
  178    182   
            Waiter => Some(BusinessMetric::Waiter),
  179    183   
            Paginator => Some(BusinessMetric::Paginator),
  180    184   
            GzipRequestCompression => Some(BusinessMetric::GzipRequestCompression),
  181    185   
            ProtocolRpcV2Cbor => Some(BusinessMetric::ProtocolRpcV2Cbor),
  182    186   
            RetryModeStandard => Some(BusinessMetric::RetryModeStandard),
  183    187   
            RetryModeAdaptive => Some(BusinessMetric::RetryModeAdaptive),
  184    188   
            FlexibleChecksumsReqCrc32 => Some(BusinessMetric::FlexibleChecksumsReqCrc32),
  185    189   
            FlexibleChecksumsReqCrc32c => Some(BusinessMetric::FlexibleChecksumsReqCrc32c),
  186    190   
            FlexibleChecksumsReqCrc64 => Some(BusinessMetric::FlexibleChecksumsReqCrc64),
  187    191   
            FlexibleChecksumsReqSha1 => Some(BusinessMetric::FlexibleChecksumsReqSha1),
  188    192   
            FlexibleChecksumsReqSha256 => Some(BusinessMetric::FlexibleChecksumsReqSha256),
  189    193   
            FlexibleChecksumsReqWhenSupported => {
  190    194   
                Some(BusinessMetric::FlexibleChecksumsReqWhenSupported)
  191    195   
            }
  192    196   
            FlexibleChecksumsReqWhenRequired => {
  193    197   
                Some(BusinessMetric::FlexibleChecksumsReqWhenRequired)
  194    198   
            }
  195    199   
            FlexibleChecksumsResWhenSupported => {
  196    200   
                Some(BusinessMetric::FlexibleChecksumsResWhenSupported)
  197    201   
            }
  198    202   
            FlexibleChecksumsResWhenRequired => {
  199    203   
                Some(BusinessMetric::FlexibleChecksumsResWhenRequired)
  200    204   
            }
         205  +
            ObservabilityTracing => Some(BusinessMetric::ObservabilityTracing),
         206  +
            ObservabilityMetrics => Some(BusinessMetric::ObservabilityMetrics),
  201    207   
            otherwise => {
  202    208   
                // This may occur if a customer upgrades only the `aws-smithy-runtime-api` crate
  203    209   
                // while continuing to use an outdated version of an SDK crate or the `aws-runtime`
  204    210   
                // crate.
  205    211   
                tracing::warn!(
  206    212   
                    "Attempted to provide `BusinessMetric` for `{otherwise:?}`, which is not recognized in the current version of the `aws-runtime` crate. \
  207    213   
                    Consider upgrading to the latest version to ensure that all tracked features are properly reported in your metrics."
  208    214   
                );
  209    215   
                None
  210    216   
            }
  211    217   
        }
  212    218   
    }
  213    219   
}
  214    220   
  215    221   
impl ProvideBusinessMetric for AwsSdkFeature {
  216    222   
    fn provide_business_metric(&self) -> Option<BusinessMetric> {
  217    223   
        use AwsSdkFeature::*;
  218    224   
        match self {
  219    225   
            AccountIdModePreferred => Some(BusinessMetric::AccountIdModePreferred),
  220    226   
            AccountIdModeDisabled => Some(BusinessMetric::AccountIdModeDisabled),
  221    227   
            AccountIdModeRequired => Some(BusinessMetric::AccountIdModeRequired),
  222    228   
            S3Transfer => Some(BusinessMetric::S3Transfer),
  223    229   
            SsoLoginDevice => Some(BusinessMetric::SsoLoginDevice),
  224    230   
            SsoLoginAuth => Some(BusinessMetric::SsoLoginAuth),
         231  +
            EndpointOverride => Some(BusinessMetric::EndpointOverride),
         232  +
            ObservabilityOtelTracing => Some(BusinessMetric::ObservabilityOtelTracing),
         233  +
            ObservabilityOtelMetrics => Some(BusinessMetric::ObservabilityOtelMetrics),
  225    234   
        }
  226    235   
    }
  227    236   
}
  228    237   
  229    238   
impl ProvideBusinessMetric for AwsCredentialFeature {
  230    239   
    fn provide_business_metric(&self) -> Option<BusinessMetric> {
  231    240   
        use AwsCredentialFeature::*;
  232    241   
        match self {
  233    242   
            ResolvedAccountId => Some(BusinessMetric::ResolvedAccountId),
  234    243   
            CredentialsCode => Some(BusinessMetric::CredentialsCode),
@@ -309,318 +369,378 @@
  329    338   
        MAX_METRICS_ID_NUMBER,
  330    339   
    };
  331    340   
    use crate::user_agent::BusinessMetric;
  332    341   
    use convert_case::{Boundary, Case, Casing};
  333    342   
    use std::collections::HashMap;
  334    343   
    use std::fmt::{Display, Formatter};
  335    344   
  336    345   
    impl Display for BusinessMetric {
  337    346   
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
  338    347   
            f.write_str(
  339         -
                &format!("{:?}", self)
         348  +
                &format!("{self:?}")
  340    349   
                    .as_str()
  341    350   
                    .from_case(Case::Pascal)
  342    351   
                    .with_boundaries(&[Boundary::DigitUpper, Boundary::LowerUpper])
  343    352   
                    .to_case(Case::ScreamingSnake),
  344    353   
            )
  345    354   
        }
  346    355   
    }
  347    356   
  348    357   
    #[test]
  349    358   
    fn feature_id_to_metric_value() {
@@ -373,382 +403,487 @@
  393    402   
  394    403   
        let csv = "A10BCE";
  395    404   
        assert_eq!("A10BC", drop_unfinished_metrics_to_fit(csv, 5));
  396    405   
  397    406   
        let csv = "A";
  398    407   
        assert_eq!("A", drop_unfinished_metrics_to_fit(csv, 5));
  399    408   
  400    409   
        let csv = "A,B";
  401    410   
        assert_eq!("A,B", drop_unfinished_metrics_to_fit(csv, 5));
  402    411   
    }
         412  +
         413  +
    #[test]
         414  +
    fn test_aws_sdk_feature_mappings() {
         415  +
        use crate::sdk_feature::AwsSdkFeature;
         416  +
        use crate::user_agent::metrics::ProvideBusinessMetric;
         417  +
         418  +
        // Test SsoLoginDevice mapping
         419  +
        assert_eq!(
         420  +
            AwsSdkFeature::SsoLoginDevice.provide_business_metric(),
         421  +
            Some(BusinessMetric::SsoLoginDevice)
         422  +
        );
         423  +
         424  +
        // Test SsoLoginAuth mapping
         425  +
        assert_eq!(
         426  +
            AwsSdkFeature::SsoLoginAuth.provide_business_metric(),
         427  +
            Some(BusinessMetric::SsoLoginAuth)
         428  +
        );
         429  +
         430  +
        // Test EndpointOverride mapping
         431  +
        assert_eq!(
         432  +
            AwsSdkFeature::EndpointOverride.provide_business_metric(),
         433  +
            Some(BusinessMetric::EndpointOverride)
         434  +
        );
         435  +
    }
         436  +
         437  +
    #[test]
         438  +
    fn test_smithy_sdk_feature_observability_mappings() {
         439  +
        use crate::user_agent::metrics::ProvideBusinessMetric;
         440  +
        use aws_smithy_runtime::client::sdk_feature::SmithySdkFeature;
         441  +
         442  +
        // Test ObservabilityMetrics mapping
         443  +
        assert_eq!(
         444  +
            SmithySdkFeature::ObservabilityMetrics.provide_business_metric(),
         445  +
            Some(BusinessMetric::ObservabilityMetrics)
         446  +
        );
         447  +
    }
         448  +
         449  +
    #[test]
         450  +
    fn test_metric_id_values() {
         451  +
        // Test that metric IDs match the expected values from FEATURES.md specification
         452  +
         453  +
        // SSO Login metrics
         454  +
        assert_eq!(
         455  +
            FEATURE_ID_TO_METRIC_VALUE.get(&BusinessMetric::SsoLoginDevice),
         456  +
            Some(&"1".into())
         457  +
        );
         458  +
        assert_eq!(
         459  +
            FEATURE_ID_TO_METRIC_VALUE.get(&BusinessMetric::SsoLoginAuth),
         460  +
            Some(&"2".into())
         461  +
        );
         462  +
         463  +
        // Observability metrics
         464  +
        assert_eq!(
         465  +
            FEATURE_ID_TO_METRIC_VALUE.get(&BusinessMetric::ObservabilityTracing),
         466  +
            Some(&"4".into())
         467  +
        );
         468  +
        assert_eq!(
         469  +
            FEATURE_ID_TO_METRIC_VALUE.get(&BusinessMetric::ObservabilityMetrics),
         470  +
            Some(&"5".into())
         471  +
        );
         472  +
        assert_eq!(
         473  +
            FEATURE_ID_TO_METRIC_VALUE.get(&BusinessMetric::ObservabilityOtelTracing),
         474  +
            Some(&"6".into())
         475  +
        );
         476  +
        assert_eq!(
         477  +
            FEATURE_ID_TO_METRIC_VALUE.get(&BusinessMetric::ObservabilityOtelMetrics),
         478  +
            Some(&"7".into())
         479  +
        );
         480  +
         481  +
        // Endpoint Override metric
         482  +
        assert_eq!(
         483  +
            FEATURE_ID_TO_METRIC_VALUE.get(&BusinessMetric::EndpointOverride),
         484  +
            Some(&"N".into())
         485  +
        );
         486  +
    }
  403    487   
}

tmp-codegen-diff/aws-sdk/sdk/aws-runtime/src/user_agent/test_data/feature_id_to_metric_value.json

@@ -27,27 +58,62 @@
   47     47   
  "CREDENTIALS_PROFILE_SSO_LEGACY": "t",
   48     48   
  "CREDENTIALS_SSO_LEGACY": "u",
   49     49   
  "CREDENTIALS_PROFILE_PROCESS": "v",
   50     50   
  "CREDENTIALS_PROCESS": "w",
   51     51   
  "CREDENTIALS_BOTO2_CONFIG_FILE": "x",
   52     52   
  "CREDENTIALS_AWS_SDK_STORE": "y",
   53     53   
  "CREDENTIALS_HTTP": "z",
   54     54   
  "CREDENTIALS_IMDS": "0",
   55     55   
  "SSO_LOGIN_DEVICE": "1",
   56     56   
  "SSO_LOGIN_AUTH": "2",
   57         -
  "BEARER_SERVICE_ENV_VARS": "3"
          57  +
  "BEARER_SERVICE_ENV_VARS": "3",
          58  +
  "OBSERVABILITY_TRACING": "4",
          59  +
  "OBSERVABILITY_METRICS": "5",
          60  +
  "OBSERVABILITY_OTEL_TRACING": "6",
          61  +
  "OBSERVABILITY_OTEL_METRICS": "7"
   58     62   
}

tmp-codegen-diff/aws-sdk/sdk/aws-sigv4/Cargo.toml

@@ -1,1 +77,77 @@
    3      3   
name = "hmac"
    4      4   
harness = false
    5      5   
    6      6   
[[bench]]
    7      7   
name = "sigv4a"
    8      8   
harness = false
    9      9   
required-features = ["sigv4a"]
   10     10   
   11     11   
[package]
   12     12   
name = "aws-sigv4"
   13         -
version = "1.3.6"
          13  +
version = "1.3.8"
   14     14   
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>", "David Barsky <me@davidbarsky.com>"]
   15     15   
description = "SigV4 signer for HTTP requests and Event Stream messages."
   16     16   
edition = "2021"
   17     17   
exclude = ["aws-sig-v4-test-suite/*"]
   18     18   
license = "Apache-2.0"
   19     19   
repository = "https://github.com/smithy-lang/smithy-rs"
   20     20   
[package.metadata.docs.rs]
   21     21   
all-features = true
   22     22   
targets = ["x86_64-unknown-linux-gnu"]
   23     23   
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
   24     24   
rustdoc-args = ["--cfg", "docsrs"]
   25     25   
   26     26   
[package.metadata.smithy-rs-release-tooling]
   27     27   
stable = true
   28     28   
   29     29   
[features]
   30     30   
default = ["sign-http", "http1"]
   31     31   
http0-compat = ["dep:http0"]
   32     32   
http1 = ["dep:http"]
   33     33   
sign-http = ["dep:http0", "dep:percent-encoding", "dep:form_urlencoded"]
   34     34   
sign-eventstream = ["dep:aws-smithy-eventstream"]
   35     35   
sigv4a = ["dep:p256", "dep:crypto-bigint", "dep:subtle", "dep:zeroize", "dep:ring"]
   36     36   
   37     37   
[dependencies]
   38     38   
bytes = "1.10.0"
   39     39   
hex = "0.4.3"
   40     40   
hmac = "0.12"
   41     41   
sha2 = "0.10"
   42     42   
time = "0.3.5"
   43     43   
tracing = "0.1.40"
   44     44   
   45     45   
[dependencies.aws-credential-types]
   46     46   
path = "../aws-credential-types"
   47         -
version = "1.2.9"
          47  +
version = "1.2.10"
   48     48   
   49     49   
[dependencies.aws-smithy-eventstream]
   50     50   
path = "../aws-smithy-eventstream"
   51     51   
optional = true
   52     52   
version = "0.60.13"
   53     53   
   54     54   
[dependencies.aws-smithy-http]
   55     55   
path = "../aws-smithy-http"
   56     56   
version = "0.62.5"
   57     57   
@@ -89,89 +130,130 @@
  109    109   
pretty_assertions = "1.3"
  110    110   
proptest = "1.2"
  111    111   
serde = "1.0.180"
  112    112   
serde_derive = "1.0.180"
  113    113   
serde_json = "1.0.104"
  114    114   
criterion = "0.5"
  115    115   
  116    116   
[dev-dependencies.aws-credential-types]
  117    117   
path = "../aws-credential-types"
  118    118   
features = ["test-util", "hardcoded-credentials"]
  119         -
version = "1.2.9"
         119  +
version = "1.2.10"
  120    120   
  121    121   
[dev-dependencies.aws-smithy-runtime-api]
  122    122   
path = "../aws-smithy-runtime-api"
  123    123   
features = ["client", "test-util"]
  124    124   
version = "1.9.2"
  125    125   
  126    126   
[dev-dependencies.time]
  127    127   
version = "0.3.5"
  128    128   
features = ["parsing"]
  129    129   
[target."cfg(not(any(target_arch = \"powerpc\", target_arch = \"powerpc64\")))".dev-dependencies]