Skip to content

Commit b9458df

Browse files
author
Zelda Hessler
authored
add tracking for checksum algorithm and retry mode business metrics (#3944)
Adds business metric tracking for checksum algorithms and retry modes. This PR includes tests. ---- _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 9b2236a commit b9458df

File tree

14 files changed

+368
-112
lines changed

14 files changed

+368
-112
lines changed

aws/rust-runtime/Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aws/rust-runtime/aws-config/Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aws/rust-runtime/aws-runtime/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "aws-runtime"
3-
version = "1.5.1"
3+
version = "1.5.2"
44
authors = ["AWS Rust SDK Team <aws-sdk-rust@amazon.com>"]
55
description = "Runtime support code for the AWS SDK. This crate isn't intended to be used directly."
66
edition = "2021"

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

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,16 @@ iterable_enum!(
127127
AccountIdModeDisabled,
128128
AccountIdModeRequired,
129129
Sigv4aSigning,
130-
ResolvedAccountId
130+
ResolvedAccountId,
131+
FlexibleChecksumsReqCrc32,
132+
FlexibleChecksumsReqCrc32c,
133+
FlexibleChecksumsReqCrc64,
134+
FlexibleChecksumsReqSha1,
135+
FlexibleChecksumsReqSha256,
136+
FlexibleChecksumsReqWhenSupported,
137+
FlexibleChecksumsReqWhenRequired,
138+
FlexibleChecksumsResWhenSupported,
139+
FlexibleChecksumsResWhenRequired
131140
);
132141

133142
pub(crate) trait ProvideBusinessMetric {
@@ -142,6 +151,25 @@ impl ProvideBusinessMetric for SmithySdkFeature {
142151
Paginator => Some(BusinessMetric::Paginator),
143152
GzipRequestCompression => Some(BusinessMetric::GzipRequestCompression),
144153
ProtocolRpcV2Cbor => Some(BusinessMetric::ProtocolRpcV2Cbor),
154+
RetryModeStandard => Some(BusinessMetric::RetryModeStandard),
155+
RetryModeAdaptive => Some(BusinessMetric::RetryModeAdaptive),
156+
FlexibleChecksumsReqCrc32 => Some(BusinessMetric::FlexibleChecksumsReqCrc32),
157+
FlexibleChecksumsReqCrc32c => Some(BusinessMetric::FlexibleChecksumsReqCrc32c),
158+
FlexibleChecksumsReqCrc64 => Some(BusinessMetric::FlexibleChecksumsReqCrc64),
159+
FlexibleChecksumsReqSha1 => Some(BusinessMetric::FlexibleChecksumsReqSha1),
160+
FlexibleChecksumsReqSha256 => Some(BusinessMetric::FlexibleChecksumsReqSha256),
161+
FlexibleChecksumsReqWhenSupported => {
162+
Some(BusinessMetric::FlexibleChecksumsReqWhenSupported)
163+
}
164+
FlexibleChecksumsReqWhenRequired => {
165+
Some(BusinessMetric::FlexibleChecksumsReqWhenRequired)
166+
}
167+
FlexibleChecksumsResWhenSupported => {
168+
Some(BusinessMetric::FlexibleChecksumsResWhenSupported)
169+
}
170+
FlexibleChecksumsResWhenRequired => {
171+
Some(BusinessMetric::FlexibleChecksumsResWhenRequired)
172+
}
145173
otherwise => {
146174
// This may occur if a customer upgrades only the `aws-smithy-runtime-api` crate
147175
// while continuing to use an outdated version of an SDK crate or the `aws-runtime`
@@ -260,16 +288,26 @@ mod tests {
260288
"ACCOUNT_ID_MODE_DISABLED": "Q",
261289
"ACCOUNT_ID_MODE_REQUIRED": "R",
262290
"SIGV4A_SIGNING": "S",
263-
"RESOLVED_ACCOUNT_ID": "T"
291+
"RESOLVED_ACCOUNT_ID": "T",
292+
"FLEXIBLE_CHECKSUMS_REQ_CRC32" : "U",
293+
"FLEXIBLE_CHECKSUMS_REQ_CRC32C" : "V",
294+
"FLEXIBLE_CHECKSUMS_REQ_CRC64" : "W",
295+
"FLEXIBLE_CHECKSUMS_REQ_SHA1" : "X",
296+
"FLEXIBLE_CHECKSUMS_REQ_SHA256" : "Y",
297+
"FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED" : "Z",
298+
"FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED" : "a",
299+
"FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED" : "b",
300+
"FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED" : "c"
264301
}
265302
"#;
266303

267304
let expected: HashMap<&str, &str> = serde_json::from_str(EXPECTED).unwrap();
268305
assert_eq!(expected.len(), FEATURE_ID_TO_METRIC_VALUE.len());
269306

270307
for (feature_id, metric_value) in &*FEATURE_ID_TO_METRIC_VALUE {
308+
let expected = expected.get(format!("{feature_id}").as_str());
271309
assert_eq!(
272-
expected.get(format!("{feature_id}").as_str()).unwrap(),
310+
expected.expect(&format!("Expected {feature_id} to have value `{metric_value}` but it was `{expected:?}` instead.")),
273311
metric_value,
274312
);
275313
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ internal fun RuntimeConfig.awsInlineableHttpRequestChecksum() =
3939
CargoDependency.smithyHttp(this),
4040
CargoDependency.smithyRuntimeApiClient(this),
4141
CargoDependency.smithyTypes(this),
42+
CargoDependency.TempFile,
4243
),
4344
)
4445

aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/UserAgentDecoratorTest.kt

Lines changed: 122 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package software.amazon.smithy.rustsdk
77

88
import org.junit.jupiter.api.Test
99
import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency
10+
import software.amazon.smithy.rust.codegen.core.rustlang.rust
1011
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
1112
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
1213
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType.Companion.preludeScope
@@ -176,9 +177,7 @@ class UserAgentDecoratorTest {
176177
val moduleName = ctx.moduleUseName()
177178
rustTemplate(
178179
"""
179-
use $moduleName::config::{
180-
Region,
181-
};
180+
use $moduleName::config::Region;
182181
use $moduleName::{Client, Config};
183182
184183
let (http_client, rcvr) = #{capture_request}(#{None});
@@ -197,7 +196,126 @@ class UserAgentDecoratorTest {
197196
#{assert_ua_contains_metric_values}(user_agent, &["M"]);
198197
""",
199198
*preludeScope,
200-
"assert_ua_contains_metric_values" to AwsRuntimeType.awsRuntimeTestUtil(rc).resolve("user_agent::test_util::assert_ua_contains_metric_values"),
199+
"assert_ua_contains_metric_values" to
200+
AwsRuntimeType.awsRuntimeTestUtil(rc)
201+
.resolve("user_agent::test_util::assert_ua_contains_metric_values"),
202+
"capture_request" to RuntimeType.captureRequest(rc),
203+
"disable_interceptor" to
204+
RuntimeType.smithyRuntimeApiClient(rc)
205+
.resolve("client::interceptors::disable_interceptor"),
206+
"UserAgentInterceptor" to
207+
AwsRuntimeType.awsRuntime(rc)
208+
.resolve("user_agent::UserAgentInterceptor"),
209+
)
210+
}
211+
}
212+
}
213+
}
214+
215+
@Test
216+
fun `it emits business metrics for retry modes`() {
217+
val model =
218+
"""
219+
namespace test
220+
221+
use aws.auth#sigv4
222+
use aws.api#service
223+
use aws.protocols#restJson1
224+
use smithy.rules#endpointRuleSet
225+
226+
@auth([sigv4])
227+
@sigv4(name: "dontcare")
228+
@endpointRuleSet({
229+
"version": "1.0",
230+
"rules": [{ "type": "endpoint", "conditions": [], "endpoint": { "url": "https://example.com" } }],
231+
"parameters": {}
232+
})
233+
@service(sdkId: "dontcare")
234+
@restJson1
235+
service TestService { version: "2023-01-01", operations: [SomeOperation] }
236+
237+
@http(uri: "/SomeOperation", method: "GET")
238+
@optionalAuth
239+
operation SomeOperation {
240+
input: SomeInput,
241+
output: SomeOutput
242+
}
243+
244+
@input
245+
structure SomeInput {}
246+
247+
@output
248+
structure SomeOutput {}
249+
""".asSmithyModel()
250+
251+
awsSdkIntegrationTest(model) { ctx, rustCrate ->
252+
rustCrate.integrationTest("retry_mode_feature_tracker") {
253+
val rc = ctx.runtimeConfig
254+
val moduleName = ctx.moduleUseName()
255+
256+
rust(
257+
"""
258+
use $moduleName::config::{Region, retry::RetryConfig};
259+
use $moduleName::{Client, Config};
260+
""",
261+
)
262+
263+
tokioTest("should_emit_metric_in_user_agent_standard_mode") {
264+
rustTemplate(
265+
"""
266+
let (http_client, rcvr) = #{capture_request}(#{None});
267+
let config = Config::builder()
268+
.region(Region::new("us-east-1"))
269+
.http_client(http_client.clone())
270+
.retry_config(RetryConfig::standard())
271+
.with_test_defaults()
272+
.build();
273+
let client = Client::from_conf(config);
274+
let _ = client.some_operation().send().await;
275+
let expected_req = rcvr.expect_request();
276+
let user_agent = expected_req
277+
.headers()
278+
.get("x-amz-user-agent")
279+
.unwrap();
280+
#{assert_ua_contains_metric_values}(user_agent, &["E"]);
281+
""",
282+
*preludeScope,
283+
"assert_ua_contains_metric_values" to
284+
AwsRuntimeType.awsRuntimeTestUtil(rc)
285+
.resolve("user_agent::test_util::assert_ua_contains_metric_values"),
286+
"capture_request" to RuntimeType.captureRequest(rc),
287+
"disable_interceptor" to
288+
RuntimeType.smithyRuntimeApiClient(rc)
289+
.resolve("client::interceptors::disable_interceptor"),
290+
"UserAgentInterceptor" to
291+
AwsRuntimeType.awsRuntime(rc)
292+
.resolve("user_agent::UserAgentInterceptor"),
293+
)
294+
}
295+
296+
tokioTest("should_emit_metric_in_user_agent_adaptive_mode") {
297+
rustTemplate(
298+
"""
299+
let (http_client, rcvr) = #{capture_request}(#{None});
300+
let config = Config::builder()
301+
.region(Region::new("us-east-1"))
302+
.http_client(http_client.clone())
303+
.retry_config(RetryConfig::adaptive())
304+
.with_test_defaults()
305+
.build();
306+
let client = Client::from_conf(config);
307+
let _ = client.some_operation().send().await;
308+
let expected_req = rcvr.expect_request();
309+
let user_agent = expected_req
310+
.headers()
311+
.get("x-amz-user-agent")
312+
.unwrap();
313+
#{assert_ua_contains_metric_values}(user_agent, &["F"]);
314+
""",
315+
*preludeScope,
316+
"assert_ua_contains_metric_values" to
317+
AwsRuntimeType.awsRuntimeTestUtil(rc)
318+
.resolve("user_agent::test_util::assert_ua_contains_metric_values"),
201319
"capture_request" to RuntimeType.captureRequest(rc),
202320
"disable_interceptor" to
203321
RuntimeType.smithyRuntimeApiClient(rc)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package software.amazon.smithy.rust.codegen.client.smithy.customizations
7+
8+
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
9+
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
10+
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginSection
11+
import software.amazon.smithy.rust.codegen.core.rustlang.InlineDependency
12+
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
13+
import software.amazon.smithy.rust.codegen.core.rustlang.rust
14+
import software.amazon.smithy.rust.codegen.core.rustlang.writable
15+
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
16+
17+
class RetryModeFeatureTrackerRuntimePluginCustomization(codegenContext: ClientCodegenContext) :
18+
ServiceRuntimePluginCustomization() {
19+
private val runtimeConfig = codegenContext.runtimeConfig
20+
21+
override fun section(section: ServiceRuntimePluginSection): Writable =
22+
writable {
23+
when (section) {
24+
is ServiceRuntimePluginSection.RegisterRuntimeComponents -> {
25+
section.registerInterceptor(this) {
26+
rust(
27+
"#T::new()",
28+
RuntimeType.forInlineDependency(
29+
InlineDependency.sdkFeatureTracker(runtimeConfig),
30+
).resolve("retry_mode::RetryModeFeatureTrackerInterceptor"),
31+
)
32+
}
33+
}
34+
35+
else -> emptySection
36+
}
37+
}
38+
}

codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customize/RequiredCustomizations.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import software.amazon.smithy.rust.codegen.client.smithy.customizations.Resilien
1919
import software.amazon.smithy.rust.codegen.client.smithy.customizations.RetryClassifierConfigCustomization
2020
import software.amazon.smithy.rust.codegen.client.smithy.customizations.RetryClassifierOperationCustomization
2121
import software.amazon.smithy.rust.codegen.client.smithy.customizations.RetryClassifierServiceRuntimePluginCustomization
22+
import software.amazon.smithy.rust.codegen.client.smithy.customizations.RetryModeFeatureTrackerRuntimePluginCustomization
2223
import software.amazon.smithy.rust.codegen.client.smithy.customizations.TimeSourceCustomization
2324
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationCustomization
2425
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
@@ -134,5 +135,6 @@ class RequiredCustomizations : ClientCodegenDecorator {
134135
): List<ServiceRuntimePluginCustomization> =
135136
baseCustomizations +
136137
ConnectionPoisoningRuntimePluginCustomization(codegenContext) +
137-
RetryClassifierServiceRuntimePluginCustomization(codegenContext)
138+
RetryClassifierServiceRuntimePluginCustomization(codegenContext) +
139+
RetryModeFeatureTrackerRuntimePluginCustomization(codegenContext)
138140
}

0 commit comments

Comments
 (0)