Skip to content

Commit dabbfaa

Browse files
authored
Add the ability to disable interceptors via the config bag (#2757)
This replaces the existing custom interceptor disable logic with shared logic to allow generally disabling any public interceptors from Runtime plugins. The previous behavior was very brittle because it relied heavily on runtime plugin execution order. ## Motivation and Context - simplify presigning behavior - generalize logic to disable interceptors ## Description Create `disable_interceptor` struct, which, when inserted into the configuration bag can disable an interceptor via the `Interceptors` execution interface. ## Testing - ` (cd aws/sdk/build/aws-sdk/sdk/s3 && cargo test --test presigning)` ## Checklist <!--- If a checkbox below is not applicable, then please DELETE it rather than leaving it unchecked --> - [ ] I have updated `CHANGELOG.next.toml` if I made changes to the smithy-rs codegen or runtime crates - [ ] I have updated `CHANGELOG.next.toml` if I made changes to the AWS SDK, generated SDK code, or SDK runtime crates ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._
1 parent ccbc9a1 commit dabbfaa

File tree

9 files changed

+209
-151
lines changed

9 files changed

+209
-151
lines changed

aws/rust-runtime/aws-inlineable/src/presigning_interceptors.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
use crate::presigning::PresigningConfig;
99
use crate::serialization_settings::HeaderSerializationSettings;
1010
use aws_runtime::auth::sigv4::{HttpSignatureType, SigV4OperationSigningConfig};
11-
use aws_runtime::invocation_id::DisableInvocationIdInterceptor;
12-
use aws_runtime::request_info::DisableRequestInfoInterceptor;
13-
use aws_runtime::user_agent::DisableUserAgentInterceptor;
11+
use aws_runtime::invocation_id::InvocationIdInterceptor;
12+
use aws_runtime::request_info::RequestInfoInterceptor;
13+
use aws_runtime::user_agent::UserAgentInterceptor;
1414
use aws_smithy_async::time::{SharedTimeSource, StaticTimeSource};
1515
use aws_smithy_runtime_api::client::interceptors::{
16-
BeforeSerializationInterceptorContextMut, BeforeTransmitInterceptorContextMut, BoxError,
17-
Interceptor, InterceptorRegistrar, SharedInterceptor,
16+
disable_interceptor, BeforeSerializationInterceptorContextMut,
17+
BeforeTransmitInterceptorContextMut, BoxError, Interceptor, InterceptorRegistrar,
18+
SharedInterceptor,
1819
};
1920
use aws_smithy_runtime_api::client::orchestrator::ConfigBagAccessors;
2021
use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin;
@@ -92,9 +93,9 @@ impl RuntimePlugin for SigV4PresigningRuntimePlugin {
9293
interceptors: &mut InterceptorRegistrar,
9394
) -> Result<(), BoxError> {
9495
// Disable some SDK interceptors that shouldn't run for presigning
95-
cfg.put(DisableInvocationIdInterceptor::new("presigning"));
96-
cfg.put(DisableRequestInfoInterceptor::new("presigning"));
97-
cfg.put(DisableUserAgentInterceptor::new("presigning"));
96+
cfg.put(disable_interceptor::<InvocationIdInterceptor>("presigning"));
97+
cfg.put(disable_interceptor::<RequestInfoInterceptor>("presigning"));
98+
cfg.put(disable_interceptor::<UserAgentInterceptor>("presigning"));
9899

99100
// Register the presigning interceptor
100101
interceptors.register(self.interceptor.clone());

aws/rust-runtime/aws-runtime/src/invocation_id.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,6 @@ pub use test_util::{NoInvocationIdGenerator, PredefinedInvocationIdGenerator};
1818
#[allow(clippy::declare_interior_mutable_const)] // we will never mutate this
1919
const AMZ_SDK_INVOCATION_ID: HeaderName = HeaderName::from_static("amz-sdk-invocation-id");
2020

21-
/// Config marker that disables the invocation ID interceptor.
22-
#[doc(hidden)]
23-
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
24-
pub struct DisableInvocationIdInterceptor {
25-
why: &'static str,
26-
}
27-
28-
impl DisableInvocationIdInterceptor {
29-
/// Creates a new `DisableInvocationIdInterceptor`.
30-
///
31-
/// Takes a human readable string for the `Debug` impl to state why it is being disabled.
32-
/// This is to assist with debugging issues with requests.
33-
pub fn new(why: &'static str) -> Self {
34-
Self { why }
35-
}
36-
}
37-
3821
/// A generator for returning new invocation IDs on demand.
3922
pub trait InvocationIdGenerator: Debug + Send + Sync {
4023
/// Call this function to receive a new [`InvocationId`] or an error explaining why one couldn't

aws/rust-runtime/aws-runtime/src/request_info.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,6 @@ use std::time::{Duration, SystemTime};
2020
#[allow(clippy::declare_interior_mutable_const)] // we will never mutate this
2121
const AMZ_SDK_REQUEST: HeaderName = HeaderName::from_static("amz-sdk-request");
2222

23-
/// Config marker that disables the invocation ID interceptor.
24-
#[doc(hidden)]
25-
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
26-
pub struct DisableRequestInfoInterceptor {
27-
why: &'static str,
28-
}
29-
30-
impl DisableRequestInfoInterceptor {
31-
/// Creates a new `DisableRequestInfoInterceptor`.
32-
///
33-
/// Takes a human readable string for the `Debug` impl to state why it is being disabled.
34-
/// This is to assist with debugging issues with requests.
35-
pub fn new(why: &'static str) -> Self {
36-
Self { why }
37-
}
38-
}
39-
4023
/// Generates and attaches a request header that communicates request-related metadata.
4124
/// Examples include:
4225
///

aws/rust-runtime/aws-runtime/src/user_agent.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,23 +49,6 @@ impl From<InvalidHeaderValue> for UserAgentInterceptorError {
4949
}
5050
}
5151

52-
/// Config marker that disables the user agent interceptor.
53-
#[doc(hidden)]
54-
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
55-
pub struct DisableUserAgentInterceptor {
56-
why: &'static str,
57-
}
58-
59-
impl DisableUserAgentInterceptor {
60-
/// Creates a new `DisableUserAgentInterceptor`.
61-
///
62-
/// Takes a human readable string for the `Debug` impl to state why it is being disabled.
63-
/// This is to assist with debugging issues with requests.
64-
pub fn new(why: &'static str) -> Self {
65-
Self { why }
66-
}
67-
}
68-
6952
/// Generates and attaches the AWS SDK's user agent to a HTTP request
7053
#[non_exhaustive]
7154
#[derive(Debug, Default)]

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/InvocationIdDecorator.kt

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegen
1010
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
1111
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginSection
1212
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
13-
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
1413
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
1514
import software.amazon.smithy.rust.codegen.core.rustlang.writable
1615
import software.amazon.smithy.rust.codegen.core.util.letIf
@@ -38,14 +37,8 @@ private class InvocationIdRuntimePluginCustomization(
3837

3938
override fun section(section: ServiceRuntimePluginSection): Writable = writable {
4039
if (section is ServiceRuntimePluginSection.AdditionalConfig) {
41-
val invocationId = AwsRuntimeType.awsRuntime(codegenContext.runtimeConfig).resolve("invocation_id")
42-
rustBlockTemplate(
43-
"if cfg.get::<#{DisableInvocationIdInterceptor}>().is_none()",
44-
"DisableInvocationIdInterceptor" to invocationId.resolve("DisableInvocationIdInterceptor"),
45-
) {
46-
section.registerInterceptor(codegenContext.runtimeConfig, this) {
47-
rustTemplate("#{InvocationIdInterceptor}::new()", *codegenScope)
48-
}
40+
section.registerInterceptor(codegenContext.runtimeConfig, this) {
41+
rustTemplate("#{InvocationIdInterceptor}::new()", *codegenScope)
4942
}
5043
}
5144
}

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/RetryInformationHeaderDecorator.kt

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRunti
1111
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginSection
1212
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
1313
import software.amazon.smithy.rust.codegen.core.rustlang.rust
14-
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
1514
import software.amazon.smithy.rust.codegen.core.rustlang.writable
1615
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
1716
import software.amazon.smithy.rust.codegen.core.util.letIf
@@ -37,22 +36,17 @@ private class AddRetryInformationHeaderInterceptors(codegenContext: ClientCodege
3736

3837
override fun section(section: ServiceRuntimePluginSection): Writable = writable {
3938
if (section is ServiceRuntimePluginSection.AdditionalConfig) {
40-
rustBlockTemplate(
41-
"if cfg.get::<#{DisableRequestInfoInterceptor}>().is_none()",
42-
"DisableRequestInfoInterceptor" to awsRuntime.resolve("request_info::DisableRequestInfoInterceptor"),
43-
) {
44-
// Track the latency between client and server.
45-
section.registerInterceptor(runtimeConfig, this) {
46-
rust(
47-
"#T::new()",
48-
smithyRuntime.resolve("client::orchestrator::interceptors::ServiceClockSkewInterceptor"),
49-
)
50-
}
39+
// Track the latency between client and server.
40+
section.registerInterceptor(runtimeConfig, this) {
41+
rust(
42+
"#T::new()",
43+
smithyRuntime.resolve("client::orchestrator::interceptors::ServiceClockSkewInterceptor"),
44+
)
45+
}
5146

52-
// Add request metadata to outgoing requests. Sets a header.
53-
section.registerInterceptor(runtimeConfig, this) {
54-
rust("#T::new()", awsRuntime.resolve("request_info::RequestInfoInterceptor"))
55-
}
47+
// Add request metadata to outgoing requests. Sets a header.
48+
section.registerInterceptor(runtimeConfig, this) {
49+
rust("#T::new()", awsRuntime.resolve("request_info::RequestInfoInterceptor"))
5650
}
5751
}
5852
}

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/UserAgentDecorator.kt

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import software.amazon.smithy.rust.codegen.client.smithy.generators.config.Confi
1818
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
1919
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
2020
import software.amazon.smithy.rust.codegen.core.rustlang.rust
21-
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
2221
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
2322
import software.amazon.smithy.rust.codegen.core.rustlang.writable
2423
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
@@ -105,16 +104,11 @@ class UserAgentDecorator : ClientCodegenDecorator {
105104

106105
override fun section(section: ServiceRuntimePluginSection): Writable = writable {
107106
if (section is ServiceRuntimePluginSection.AdditionalConfig) {
108-
rustBlockTemplate(
109-
"if cfg.get::<#{DisableUserAgentInterceptor}>().is_none()",
110-
"DisableUserAgentInterceptor" to awsRuntime.resolve("user_agent::DisableUserAgentInterceptor"),
111-
) {
112-
section.putConfigValue(this) {
113-
rust("#T.clone()", ClientRustModule.Meta.toType().resolve("API_METADATA"))
114-
}
115-
section.registerInterceptor(runtimeConfig, this) {
116-
rust("#T::new()", awsRuntime.resolve("user_agent::UserAgentInterceptor"))
117-
}
107+
section.putConfigValue(this) {
108+
rust("#T.clone()", ClientRustModule.Meta.toType().resolve("API_METADATA"))
109+
}
110+
section.registerInterceptor(runtimeConfig, this) {
111+
rust("#T::new()", awsRuntime.resolve("user_agent::UserAgentInterceptor"))
118112
}
119113
}
120114
}

design/src/client/orchestrator.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ The orchestrator's work is divided into four phases:
5252
*NOTE: If an interceptor fails, then the other interceptors for that lifecycle event are still run. All resulting errors are collected and emitted together.*
5353

5454
0. **Building the `ConfigBag` and mounting interceptors**.
55-
- *This phase is infallible.*
55+
- *This phase is fallible.*
5656
- An interceptor context is created. This will hold request and response objects, making them available to interceptors.
5757
- All runtime plugins set at the client-level are run. These plugins can set config and mount interceptors. Any _"read before execution"_ interceptors that have been set get run.
5858
- All runtime plugins set at the operation-level are run. These plugins can also set config and mount interceptors. Any new _"read before execution"_ interceptors that have been set get run.

0 commit comments

Comments
 (0)