Skip to content

Commit b761ae5

Browse files
Add UserAgentFeatureId and UserAgentDetails for UA2.1 Feature Tracking (#3707)
1 parent 2f7a286 commit b761ae5

File tree

4 files changed

+370
-1
lines changed

4 files changed

+370
-1
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
using System.Collections.Generic;
17+
18+
namespace Amazon.Runtime.Internal.UserAgent
19+
{
20+
/// <summary>
21+
/// Represents the User Agent details, including tracked features under User Agent 2.1 (UA2.1).
22+
/// This class ensures that feature metrics are collected efficiently and the final
23+
/// User-Agent string is generated only when needed.
24+
/// </summary>
25+
public class UserAgentDetails
26+
{
27+
private const int MaxSizeBytes = 1024; // 1 KB size limit
28+
private readonly HashSet<string> _trackedFeatureIds = new HashSet<string>();
29+
30+
/// <summary>
31+
/// Gets the list of tracked feature IDs.
32+
/// </summary>
33+
public IEnumerable<string> TrackedFeatureIds => _trackedFeatureIds;
34+
35+
/// <summary>
36+
/// Adds a feature metric to be included in the User-Agent string.
37+
/// Duplicate entries are ignored.
38+
/// </summary>
39+
/// <param name="featureId">The feature metric ID to track.</param>
40+
public void AddFeature(UserAgentFeatureId featureId)
41+
{
42+
if (featureId == null) return;
43+
_trackedFeatureIds.Add(featureId.Value);
44+
}
45+
46+
/// <summary>
47+
/// Generates the User-Agent metrics string.
48+
/// Ensures the final string does not exceed 1024 bytes.
49+
/// </summary>
50+
/// <returns>The formatted User-Agent metrics string.</returns>
51+
#pragma warning disable CA1822 // Mark members as static
52+
public string GenerateMetricsUserAgent()
53+
#pragma warning restore CA1822 // Mark members as static
54+
{
55+
// TODO
56+
return "m/{metricsString}";
57+
}
58+
}
59+
}
Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
namespace Amazon.Runtime.Internal.UserAgent
17+
{
18+
/// <summary>
19+
/// Represents the unique metric identifiers for SDK features tracked under User Agent 2.1 (UA2.1).
20+
/// </summary>
21+
public class UserAgentFeatureId : ConstantClass
22+
{
23+
/// <summary>
24+
/// An operation called using a C2j Resource model.
25+
/// </summary>
26+
public static readonly UserAgentFeatureId RESOURCE_MODEL = new UserAgentFeatureId("A");
27+
28+
/// <summary>
29+
/// An operation called using a waiter.
30+
/// </summary>
31+
public static readonly UserAgentFeatureId WAITER = new UserAgentFeatureId("B");
32+
33+
/// <summary>
34+
/// An operation called using a paginator.
35+
/// </summary>
36+
public static readonly UserAgentFeatureId PAGINATOR = new UserAgentFeatureId("C");
37+
38+
/// <summary>
39+
/// An operation called using the legacy retry mode.
40+
/// </summary>
41+
public static readonly UserAgentFeatureId RETRY_MODE_LEGACY = new UserAgentFeatureId("D");
42+
43+
/// <summary>
44+
/// An operation called using the standard retry mode.
45+
/// </summary>
46+
public static readonly UserAgentFeatureId RETRY_MODE_STANDARD = new UserAgentFeatureId("E");
47+
48+
/// <summary>
49+
/// An operation called using the adaptive retry mode.
50+
/// </summary>
51+
public static readonly UserAgentFeatureId RETRY_MODE_ADAPTIVE = new UserAgentFeatureId("F");
52+
53+
/// <summary>
54+
/// An operation called using the S3 Transfer Manager.
55+
/// </summary>
56+
public static readonly UserAgentFeatureId S3_TRANSFER = new UserAgentFeatureId("G");
57+
58+
/// <summary>
59+
/// An operation called using the S3 Encryption Client V1.
60+
/// </summary>
61+
public static readonly UserAgentFeatureId S3_CRYPTO_V1N = new UserAgentFeatureId("H");
62+
63+
/// <summary>
64+
/// An operation called using the S3 Encryption Client V2.
65+
/// </summary>
66+
public static readonly UserAgentFeatureId S3_CRYPTO_V2 = new UserAgentFeatureId("I");
67+
68+
/// <summary>
69+
/// An operation called using the S3 Express feature.
70+
/// </summary>
71+
public static readonly UserAgentFeatureId S3_EXPRESS_BUCKET = new UserAgentFeatureId("J");
72+
73+
/// <summary>
74+
/// An operation called using the S3 Access Grants feature.
75+
/// </summary>
76+
public static readonly UserAgentFeatureId S3_ACCESS_GRANTS = new UserAgentFeatureId("K");
77+
78+
/// <summary>
79+
/// An operation called using GZIP request compression.
80+
/// </summary>
81+
public static readonly UserAgentFeatureId GZIP_REQUEST_COMPRESSION = new UserAgentFeatureId("L");
82+
83+
/// <summary>
84+
/// An operation called using the Smithy RPC v2 CBOR protocol.
85+
/// </summary>
86+
public static readonly UserAgentFeatureId PROTOCOL_RPC_V2_CBOR = new UserAgentFeatureId("M");
87+
88+
/// <summary>
89+
/// An operation called using a user provided endpoint URL.
90+
/// </summary>
91+
public static readonly UserAgentFeatureId ENDPOINT_OVERRIDE = new UserAgentFeatureId("N");
92+
93+
/// <summary>
94+
/// An operation called with account ID mode set to preferred.
95+
/// </summary>
96+
public static readonly UserAgentFeatureId ACCOUNT_ID_MODE_PREFERRED = new UserAgentFeatureId("P");
97+
98+
/// <summary>
99+
/// An operation called with account ID mode set to disabled.
100+
/// </summary>
101+
public static readonly UserAgentFeatureId ACCOUNT_ID_MODE_DISABLED = new UserAgentFeatureId("Q");
102+
103+
/// <summary>
104+
/// An operation called with account ID mode set to required.
105+
/// </summary>
106+
public static readonly UserAgentFeatureId ACCOUNT_ID_MODE_REQUIRED = new UserAgentFeatureId("R");
107+
108+
/// <summary>
109+
/// An operation called using sigv4a signing.
110+
/// </summary>
111+
public static readonly UserAgentFeatureId SIGV4A_SIGNING = new UserAgentFeatureId("S");
112+
113+
/// <summary>
114+
/// An operation where credential resolution resolved an account ID.
115+
/// </summary>
116+
public static readonly UserAgentFeatureId RESOLVED_ACCOUNT_ID = new UserAgentFeatureId("T");
117+
118+
/// <summary>
119+
/// Operation included a CRC-32 checksum for request payload.
120+
/// </summary>
121+
public static readonly UserAgentFeatureId FLEXIBLE_CHECKSUMS_REQ_CRC32 = new UserAgentFeatureId("U");
122+
123+
/// <summary>
124+
/// Operation included a CRC-32C checksum for request payload.
125+
/// </summary>
126+
public static readonly UserAgentFeatureId FLEXIBLE_CHECKSUMS_REQ_CRC32C = new UserAgentFeatureId("V");
127+
128+
/// <summary>
129+
/// Operation included a CRC-64 checksum for request payload.
130+
/// </summary>
131+
public static readonly UserAgentFeatureId FLEXIBLE_CHECKSUMS_REQ_CRC64 = new UserAgentFeatureId("W");
132+
133+
/// <summary>
134+
/// Operation included a SHA-1 checksum for request payload.
135+
/// </summary>
136+
public static readonly UserAgentFeatureId FLEXIBLE_CHECKSUMS_REQ_SHA1 = new UserAgentFeatureId("X");
137+
138+
/// <summary>
139+
/// Operation included a SHA-256 checksum for request payload.
140+
/// </summary>
141+
public static readonly UserAgentFeatureId FLEXIBLE_CHECKSUMS_REQ_SHA256 = new UserAgentFeatureId("Y");
142+
143+
/// <summary>
144+
/// SDK resolved configuration <see cref="RequestChecksumCalculation.WHEN_SUPPORTED"/>.
145+
/// </summary>
146+
public static readonly UserAgentFeatureId FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED = new UserAgentFeatureId("Z");
147+
148+
/// <summary>
149+
/// SDK resolved configuration <see cref="RequestChecksumCalculation.WHEN_REQUIRED"/>.
150+
/// </summary>
151+
public static readonly UserAgentFeatureId FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED = new UserAgentFeatureId("a");
152+
153+
/// <summary>
154+
/// SDK resolved configuration <see cref="ResponseChecksumValidation.WHEN_SUPPORTED"/>.
155+
/// </summary>
156+
public static readonly UserAgentFeatureId FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED = new UserAgentFeatureId("b");
157+
158+
/// <summary>
159+
/// SDK resolved configuration <see cref="ResponseChecksumValidation.WHEN_REQUIRED"/>.
160+
/// </summary>
161+
public static readonly UserAgentFeatureId FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED = new UserAgentFeatureId("c");
162+
163+
/// <summary>
164+
/// An operation called using a DynamoDB Mapper high level library.
165+
/// </summary>
166+
public static readonly UserAgentFeatureId DDB_MAPPER = new UserAgentFeatureId("d");
167+
168+
/// <summary>
169+
/// An operation called using credentials resolved from code, cli parameters, session object, or client instance.
170+
/// </summary>
171+
public static readonly UserAgentFeatureId CREDENTIALS_CODE = new UserAgentFeatureId("e");
172+
173+
/// <summary>
174+
/// An operation called using credentials resolved from JVM system properties.
175+
/// </summary>
176+
public static readonly UserAgentFeatureId CREDENTIALS_JVM_SYSTEM_PROPERTIES = new UserAgentFeatureId("f");
177+
178+
/// <summary>
179+
/// An operation called using credentials resolved from environment variables.
180+
/// </summary>
181+
public static readonly UserAgentFeatureId CREDENTIALS_ENV_VARS = new UserAgentFeatureId("g");
182+
183+
/// <summary>
184+
/// An operation called using credentials resolved from environment variables for assuming a role with STS using a web identity token.
185+
/// </summary>
186+
public static readonly UserAgentFeatureId CREDENTIALS_ENV_VARS_STS_WEB_ID_TOKEN = new UserAgentFeatureId("h");
187+
188+
/// <summary>
189+
/// An operation called using credentials resolved from STS using assume role.
190+
/// </summary>
191+
public static readonly UserAgentFeatureId CREDENTIALS_STS_ASSUME_ROLE = new UserAgentFeatureId("i");
192+
193+
/// <summary>
194+
/// An operation called using credentials resolved from STS using assume role with SAML.
195+
/// </summary>
196+
public static readonly UserAgentFeatureId CREDENTIALS_STS_ASSUME_ROLE_SAML = new UserAgentFeatureId("j");
197+
198+
/// <summary>
199+
/// An operation called using credentials resolved from STS using assume role with web identity.
200+
/// </summary>
201+
public static readonly UserAgentFeatureId CREDENTIALS_STS_ASSUME_ROLE_WEB_ID = new UserAgentFeatureId("k");
202+
203+
/// <summary>
204+
/// An operation called using credentials resolved from STS using a federation token.
205+
/// </summary>
206+
public static readonly UserAgentFeatureId CREDENTIALS_STS_FEDERATION_TOKEN = new UserAgentFeatureId("l");
207+
208+
/// <summary>
209+
/// An operation called using credentials resolved from STS using a session token.
210+
/// </summary>
211+
public static readonly UserAgentFeatureId CREDENTIALS_STS_SESSION_TOKEN = new UserAgentFeatureId("m");
212+
213+
/// <summary>
214+
/// An operation called using credentials resolved from a config file(s) profile with static credentials.
215+
/// </summary>
216+
public static readonly UserAgentFeatureId CREDENTIALS_PROFILE = new UserAgentFeatureId("n");
217+
218+
/// <summary>
219+
/// An operation called using credentials resolved from a source profile in a config file(s) profile.
220+
/// </summary>
221+
public static readonly UserAgentFeatureId CREDENTIALS_PROFILE_SOURCE_PROFILE = new UserAgentFeatureId("o");
222+
223+
/// <summary>
224+
/// An operation called using credentials resolved from a named provider in a config file(s) profile.
225+
/// </summary>
226+
public static readonly UserAgentFeatureId CREDENTIALS_PROFILE_NAMED_PROVIDER = new UserAgentFeatureId("p");
227+
228+
/// <summary>
229+
/// An operation called using credentials resolved from configuration for assuming a role with STS using web identity token in a config file(s) profile.
230+
/// </summary>
231+
public static readonly UserAgentFeatureId CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN = new UserAgentFeatureId("q");
232+
233+
/// <summary>
234+
/// An operation called using credentials resolved from an SSO session in a config file(s) profile.
235+
/// </summary>
236+
public static readonly UserAgentFeatureId CREDENTIALS_PROFILE_SSO = new UserAgentFeatureId("r");
237+
238+
/// <summary>
239+
/// An operation called using credentials resolved from an SSO session.
240+
/// </summary>
241+
public static readonly UserAgentFeatureId CREDENTIALS_SSO = new UserAgentFeatureId("s");
242+
243+
/// <summary>
244+
/// An operation called using credentials resolved from an SSO session in a config file(s) profile using legacy format.
245+
/// </summary>
246+
public static readonly UserAgentFeatureId CREDENTIALS_PROFILE_SSO_LEGACY = new UserAgentFeatureId("t");
247+
248+
/// <summary>
249+
/// An operation called using credentials resolved from an SSO session using legacy format.
250+
/// </summary>
251+
public static readonly UserAgentFeatureId CREDENTIALS_SSO_LEGACY = new UserAgentFeatureId("u");
252+
253+
/// <summary>
254+
/// An operation called using credentials resolved from a process in a config file(s) profile.
255+
/// </summary>
256+
public static readonly UserAgentFeatureId CREDENTIALS_PROFILE_PROCESS = new UserAgentFeatureId("v");
257+
258+
/// <summary>
259+
/// An operation called using credentials resolved from a process.
260+
/// </summary>
261+
public static readonly UserAgentFeatureId CREDENTIALS_PROCESS = new UserAgentFeatureId("w");
262+
263+
/// <summary>
264+
/// An operation called using credentials resolved from the credentials section of a boto2 config file.
265+
/// </summary>
266+
public static readonly UserAgentFeatureId CREDENTIALS_BOTO2_CONFIG_FILE = new UserAgentFeatureId("x");
267+
268+
/// <summary>
269+
/// An operation called using credentials resolved from a profile in an AWS SDK store.
270+
/// </summary>
271+
public static readonly UserAgentFeatureId CREDENTIALS_AWS_SDK_STORE = new UserAgentFeatureId("y");
272+
273+
/// <summary>
274+
/// An operation called using credentials resolved from an HTTP endpoint.
275+
/// </summary>
276+
public static readonly UserAgentFeatureId CREDENTIALS_HTTP = new UserAgentFeatureId("z");
277+
278+
/// <summary>
279+
/// An operation called using credentials resolved from the instance metadata service (IMDS).
280+
/// </summary>
281+
public static readonly UserAgentFeatureId CREDENTIALS_IMDS = new UserAgentFeatureId("0");
282+
283+
/// <summary>
284+
/// Calling an SSO-OIDC operation as part of the SSO login flow, when using the OAuth2.0 device code grant.
285+
/// </summary>
286+
public static readonly UserAgentFeatureId SSO_LOGIN_DEVICE = new UserAgentFeatureId("1");
287+
288+
/// <summary>
289+
/// Calling an SSO-OIDC operation as part of the SSO login flow, when using the OAuth2.0 authorization code grant.
290+
/// </summary>
291+
public static readonly UserAgentFeatureId SSO_LOGIN_AUTH = new UserAgentFeatureId("2");
292+
293+
public UserAgentFeatureId(string value) : base(value) { }
294+
295+
public static UserAgentFeatureId FindValue(string value)
296+
{
297+
return FindValue<UserAgentFeatureId>(value);
298+
}
299+
300+
public static implicit operator UserAgentFeatureId(string value)
301+
{
302+
return FindValue(value);
303+
}
304+
}
305+
306+
}

sdk/src/Core/Amazon.Runtime/Pipeline/Contexts.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using Amazon.Runtime.Internal;
1818
using Amazon.Runtime.Internal.Auth;
1919
using Amazon.Runtime.Internal.Transform;
20+
using Amazon.Runtime.Internal.UserAgent;
2021
using Amazon.Runtime.Internal.Util;
2122
using System;
2223
using System.Collections.Generic;
@@ -53,6 +54,7 @@ public interface IRequestContext
5354
IDictionary<string, object> ContextAttributes { get; }
5455

5556
IHttpRequestStreamHandle RequestStreamHandle {get;set;}
57+
UserAgentDetails UserAgentDetails { get; }
5658
}
5759

5860
public interface IResponseContext
@@ -104,6 +106,7 @@ public RequestContext(bool enableMetrics, ISigner clientSigner)
104106
this.Metrics = new RequestMetrics();
105107
this.Metrics.IsEnabled = enableMetrics;
106108
this.InvocationId = Guid.NewGuid();
109+
this.UserAgentDetails = new UserAgentDetails();
107110
}
108111

109112
public IRequest Request { get; set; }
@@ -120,6 +123,7 @@ public RequestContext(bool enableMetrics, ISigner clientSigner)
120123
public InvokeOptionsBase Options { get; set; }
121124
public ISigner Signer { get; set; }
122125
public BaseIdentity Identity { get; set; }
126+
public UserAgentDetails UserAgentDetails { get; }
123127

124128
#if AWS_ASYNC_API
125129
public System.Threading.CancellationToken CancellationToken { get; set; }

0 commit comments

Comments
 (0)