Unverified Commit 5473192d authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Update runtime plugin trait (#2754)



## Motivation and Context
Update the RuntimePlugin trait based on discussion:
1. Methods are infallible
2. Split out `Config` and `Interceptors`
3. `ConfigBag` now has an explicit field `interceptor_state`
4. Refactor `ConfigBagAccessors` so that we can build the core around
the trait and keep the trait together with a `where Self` trick

## Description
- Update the `RuntimePlugin` trait
- Deal with resulting implications
## Testing
- [x] CI


----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._

---------

Co-authored-by: default avatarJohn DiSanti <jdisanti@amazon.com>
parent 8e37d42f
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ use aws_smithy_runtime_api::client::interceptors::{
    BeforeSerializationInterceptorContextMut, BeforeTransmitInterceptorContextMut, BoxError,
    Interceptor,
};
use aws_smithy_runtime_api::client::orchestrator::LoadedRequestBody;
use aws_smithy_runtime_api::client::orchestrator::{ConfigBagAccessors, LoadedRequestBody};
use aws_smithy_types::config_bag::ConfigBag;
use bytes::Bytes;
use http::header::{HeaderName, HeaderValue};
@@ -119,7 +119,8 @@ impl Interceptor for GlacierTreeHashHeaderInterceptor {
    ) -> Result<(), BoxError> {
        // Request the request body to be loaded into memory immediately after serialization
        // so that it can be checksummed before signing and transmit
        cfg.put(LoadedRequestBody::Requested);
        cfg.interceptor_state()
            .set_loaded_request_body(LoadedRequestBody::Requested);
        Ok(())
    }

@@ -139,7 +140,7 @@ impl Interceptor for GlacierTreeHashHeaderInterceptor {
                .clone();
            signing_config.signing_options.payload_override =
                Some(SignableBody::Precomputed(content_sha256));
            cfg.put(signing_config);
            cfg.interceptor_state().put(signing_config);
        } else {
            return Err(
                "the request body wasn't loaded into memory before the retry loop, \
+16 −17
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ use aws_smithy_runtime_api::client::interceptors::{
};
use aws_smithy_runtime_api::client::orchestrator::ConfigBagAccessors;
use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin;
use aws_smithy_types::config_bag::ConfigBag;
use aws_smithy_types::config_bag::{ConfigBag, FrozenLayer, Layer};

/// Interceptor that tells the SigV4 signer to add the signature to query params,
/// and sets the request expiration time from the presigning config.
@@ -40,12 +40,13 @@ impl Interceptor for SigV4PresigningInterceptor {
        _context: &mut BeforeSerializationInterceptorContextMut<'_>,
        cfg: &mut ConfigBag,
    ) -> Result<(), BoxError> {
        cfg.put::<HeaderSerializationSettings>(
        cfg.interceptor_state().put::<HeaderSerializationSettings>(
            HeaderSerializationSettings::new()
                .omit_default_content_length()
                .omit_default_content_type(),
        );
        cfg.set_request_time(SharedTimeSource::new(StaticTimeSource::new(
        cfg.interceptor_state()
            .set_request_time(SharedTimeSource::new(StaticTimeSource::new(
                self.config.start_time(),
            )));
        Ok(())
@@ -61,7 +62,8 @@ impl Interceptor for SigV4PresigningInterceptor {
            config.signing_options.signature_type = HttpSignatureType::HttpRequestQueryParams;
            config.signing_options.payload_override =
                Some(aws_sigv4::http_request::SignableBody::UnsignedPayload);
            cfg.put::<SigV4OperationSigningConfig>(config);
            cfg.interceptor_state()
                .put::<SigV4OperationSigningConfig>(config);
            Ok(())
        } else {
            Err(
@@ -87,18 +89,15 @@ impl SigV4PresigningRuntimePlugin {
}

impl RuntimePlugin for SigV4PresigningRuntimePlugin {
    fn configure(
        &self,
        cfg: &mut ConfigBag,
        interceptors: &mut InterceptorRegistrar,
    ) -> Result<(), BoxError> {
        // Disable some SDK interceptors that shouldn't run for presigning
        cfg.put(disable_interceptor::<InvocationIdInterceptor>("presigning"));
        cfg.put(disable_interceptor::<RequestInfoInterceptor>("presigning"));
        cfg.put(disable_interceptor::<UserAgentInterceptor>("presigning"));
    fn config(&self) -> Option<FrozenLayer> {
        let mut layer = Layer::new("Presigning");
        layer.put(disable_interceptor::<InvocationIdInterceptor>("presigning"));
        layer.put(disable_interceptor::<RequestInfoInterceptor>("presigning"));
        layer.put(disable_interceptor::<UserAgentInterceptor>("presigning"));
        Some(layer.freeze())
    }

        // Register the presigning interceptor
    fn interceptors(&self, interceptors: &mut InterceptorRegistrar) {
        interceptors.register(self.interceptor.clone());
        Ok(())
    }
}
+7 −4
Original line number Diff line number Diff line
@@ -506,6 +506,7 @@ mod tests {
    use super::*;
    use aws_credential_types::Credentials;
    use aws_sigv4::http_request::SigningSettings;
    use aws_smithy_types::config_bag::Layer;
    use aws_types::region::SigningRegion;
    use aws_types::SigningService;
    use std::collections::HashMap;
@@ -556,8 +557,8 @@ mod tests {

    #[test]
    fn endpoint_config_overrides_region_and_service() {
        let mut cfg = ConfigBag::base();
        cfg.put(SigV4OperationSigningConfig {
        let mut layer = Layer::new("test");
        layer.put(SigV4OperationSigningConfig {
            region: Some(SigningRegion::from(Region::new("override-this-region"))),
            service: Some(SigningService::from_static("override-this-service")),
            signing_options: Default::default(),
@@ -577,6 +578,7 @@ mod tests {
        });
        let config = AuthSchemeEndpointConfig::new(Some(&config));

        let cfg = ConfigBag::of_layers(vec![layer]);
        let result =
            SigV4HttpRequestSigner::extract_operation_config(config, &cfg).expect("success");

@@ -593,12 +595,13 @@ mod tests {

    #[test]
    fn endpoint_config_supports_fallback_when_region_or_service_are_unset() {
        let mut cfg = ConfigBag::base();
        cfg.put(SigV4OperationSigningConfig {
        let mut layer = Layer::new("test");
        layer.put(SigV4OperationSigningConfig {
            region: Some(SigningRegion::from(Region::new("us-east-1"))),
            service: Some(SigningService::from_static("qldb")),
            signing_options: Default::default(),
        });
        let cfg = ConfigBag::of_layers(vec![layer]);
        let config = AuthSchemeEndpointConfig::empty();

        let result =
+2 −1
Original line number Diff line number Diff line
@@ -48,7 +48,8 @@ impl Interceptor for InvocationIdInterceptor {
            .map(|gen| gen.generate())
            .transpose()?
            .flatten();
        cfg.put::<InvocationId>(id.unwrap_or_default());
        cfg.interceptor_state()
            .put::<InvocationId>(id.unwrap_or_default());

        Ok(())
    }
+5 −4
Original line number Diff line number Diff line
@@ -166,7 +166,7 @@ mod tests {
    use crate::request_info::RequestPairs;
    use aws_smithy_http::body::SdkBody;
    use aws_smithy_runtime_api::client::interceptors::{Interceptor, InterceptorContext};
    use aws_smithy_types::config_bag::ConfigBag;
    use aws_smithy_types::config_bag::{ConfigBag, Layer};
    use aws_smithy_types::retry::RetryConfig;
    use aws_smithy_types::timeout::TimeoutConfig;
    use aws_smithy_types::type_erasure::TypeErasedBox;
@@ -190,13 +190,14 @@ mod tests {
        context.enter_serialization_phase();
        context.set_request(http::Request::builder().body(SdkBody::empty()).unwrap());

        let mut config = ConfigBag::base();
        config.put(RetryConfig::standard());
        config.put(
        let mut layer = Layer::new("test");
        layer.put(RetryConfig::standard());
        layer.put(
            TimeoutConfig::builder()
                .read_timeout(Duration::from_secs(30))
                .build(),
        );
        let mut config = ConfigBag::of_layers(vec![layer]);

        let _ = context.take_input();
        context.enter_before_transmit_phase();
Loading