Skip to content

Commit 123255c

Browse files
Merge pull request #3738 from aws/Business-Metrics-Tracking-UA-2.1
Business metrics tracking UA 2.1
2 parents f4b0d8a + c4f47c7 commit 123255c

File tree

52 files changed

+1039
-567
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1039
-567
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"core": {
3+
"changeLogMessages": [
4+
"Update the AWS SDK for .NET to include encoded metrics in the `User-Agent` header to track which features were used for a given request (for example, which retry behavior and how credentials were resolved)"
5+
],
6+
"type": "patch",
7+
"updateMinimum": true
8+
}
9+
}

generator/ServiceModels/s3/s3.customizations.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
{ "operation": "addAfter", "newType": "Amazon.S3.Internal.AmazonS3RedirectHandler", "targetType": "Amazon.Runtime.Internal.Unmarshaller" },
99
{ "operation": "addBefore", "newType": "Amazon.S3.Internal.S3Express.S3ExpressPreSigner", "targetType": "Amazon.Runtime.Internal.Signer" },
1010
{ "operation": "addAfter", "newType": "Amazon.S3.Internal.AmazonS3PostMarshallHandler", "targetType": "Amazon.Runtime.Internal.EndpointResolver" },
11-
{ "operation": "addAfter", "newType": "Amazon.S3.Internal.AmazonS3UserAgentHandler", "targetType": "Amazon.Runtime.Internal.ChecksumHandler" },
1211
{
1312
"condition":"this.Config.RetryMode == RequestRetryMode.Standard",
1413
"operation": "replace",

sdk/src/Core/Amazon.Runtime/AmazonWebServiceRequest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*/
1515
using System;
1616
using System.Collections.Generic;
17-
using System.Text;
17+
using Amazon.Runtime.Internal.UserAgent;
1818

1919
namespace Amazon.Runtime
2020
{
@@ -26,7 +26,7 @@ public abstract partial class AmazonWebServiceRequest : Amazon.Runtime.Internal.
2626
private readonly object _lock = new object();
2727

2828
internal RequestEventHandler mBeforeRequestEvent;
29-
internal string UserAgentAddition { get; set; } = null;
29+
UserAgentDetails Amazon.Runtime.Internal.IAmazonWebServiceRequest.UserAgentDetails { get; } = new UserAgentDetails();
3030

3131
internal event RequestEventHandler BeforeRequestEvent
3232
{

sdk/src/Core/Amazon.Runtime/CredentialManagement/AWSCredentialsFactory.cs

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@
1212
* express or implied. See the License for the specific language governing
1313
* permissions and limitations under the License.
1414
*/
15-
using Amazon.Runtime.Internal;
1615
using Amazon.Runtime.CredentialManagement.Internal;
16+
using Amazon.Runtime.Credentials.Internal;
17+
using Amazon.Runtime.Internal.Settings;
18+
using Amazon.Runtime.Internal.UserAgent;
1719
using Amazon.Util;
20+
using Amazon.Util.Internal;
1821
using System;
1922
using System.Collections.Generic;
2023
using System.Globalization;
2124
using System.IO;
2225
using System.Linq;
23-
using Amazon.Runtime.Credentials.Internal;
24-
using Amazon.Runtime.Internal.Settings;
25-
using Amazon.Util.Internal;
2626

2727
namespace Amazon.Runtime.CredentialManagement
2828
{
@@ -199,12 +199,16 @@ private static AWSCredentials GetAWSCredentialsInternal(
199199
{
200200
if (profileType.HasValue)
201201
{
202+
AWSCredentials awsCredentials = null;
202203
switch (profileType)
203204
{
204205
case CredentialProfileType.Basic:
205-
return new BasicAWSCredentials(options.AccessKey, options.SecretKey, options.AwsAccountId);
206+
awsCredentials = new BasicAWSCredentials(options.AccessKey, options.SecretKey, options.AwsAccountId);
207+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE);
208+
break;
206209
case CredentialProfileType.Session:
207-
return new SessionAWSCredentials(options.AccessKey, options.SecretKey, options.Token, options.AwsAccountId);
210+
awsCredentials = new SessionAWSCredentials(options.AccessKey, options.SecretKey, options.Token, options.AwsAccountId);
211+
break;
208212
case CredentialProfileType.AssumeRole:
209213
case CredentialProfileType.AssumeRoleExternal:
210214
case CredentialProfileType.AssumeRoleMFA:
@@ -249,7 +253,11 @@ private static AWSCredentials GetAWSCredentialsInternal(
249253
ExternalId = options.ExternalID,
250254
MfaSerialNumber = options.MfaSerial
251255
};
252-
return new AssumeRoleAWSCredentials(sourceCredentials, options.RoleArn, roleSessionName, assumeRoleOptions);
256+
257+
awsCredentials = new AssumeRoleAWSCredentials(sourceCredentials, options.RoleArn, roleSessionName, assumeRoleOptions);
258+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_SOURCE_PROFILE);
259+
break;
260+
253261
case CredentialProfileType.AssumeRoleCredentialSource:
254262
case CredentialProfileType.AssumeRoleCredentialSourceSessionName:
255263
// get credentials specified by credentialSource
@@ -269,29 +277,31 @@ private static AWSCredentials GetAWSCredentialsInternal(
269277

270278
roleSessionName = options.RoleSessionName ?? RoleSessionNamePrefix + AWSSDKUtils.CorrectedUtcNow.Ticks;
271279
assumeRoleOptions = new AssumeRoleAWSCredentialsOptions();
272-
return new AssumeRoleAWSCredentials(sourceCredentials, options.RoleArn, roleSessionName, assumeRoleOptions);
280+
281+
awsCredentials = new AssumeRoleAWSCredentials(sourceCredentials, options.RoleArn, roleSessionName, assumeRoleOptions);
282+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_NAMED_PROVIDER);
283+
break;
284+
273285
case CredentialProfileType.AssumeRoleWithWebIdentity:
274286
case CredentialProfileType.AssumeRoleWithWebIdentitySessionName:
275-
return new AssumeRoleWithWebIdentityCredentials(options.WebIdentityTokenFile, options.RoleArn, options.RoleSessionName);
276-
287+
awsCredentials = new AssumeRoleWithWebIdentityCredentials(options.WebIdentityTokenFile, options.RoleArn, options.RoleSessionName);
288+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN);
289+
break;
290+
277291
case CredentialProfileType.SSO:
278-
{
279-
var ssoCredentialsOptions = new SSOAWSCredentialsOptions
280-
{
292+
var ssoCredentialsOptions = new SSOAWSCredentialsOptions
293+
{
281294
SessionName = options.SsoSession,
282295
Scopes = options.SsoRegistrationScopes?.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToList()
283296
};
284297

285-
return new SSOAWSCredentials(
286-
options.SsoAccountId, options.SsoRegion,
287-
options.SsoRoleName, options.SsoStartUrl,
288-
ssoCredentialsOptions
289-
);
290-
}
291-
298+
var isLegacyFormat = string.IsNullOrEmpty(options.SsoSession);
299+
awsCredentials = new SSOAWSCredentials(options.SsoAccountId, options.SsoRegion, options.SsoRoleName, options.SsoStartUrl, ssoCredentialsOptions);
300+
awsCredentials.FeatureIdSources.Add(isLegacyFormat ? UserAgentFeatureId.CREDENTIALS_PROFILE_SSO_LEGACY : UserAgentFeatureId.CREDENTIALS_PROFILE_SSO);
301+
break;
302+
292303
case CredentialProfileType.SAMLRole:
293304
case CredentialProfileType.SAMLRoleUserIdentity:
294-
295305
if (UserCrypto.IsUserCryptAvailable)
296306
{
297307
var federatedOptions = new FederatedAWSCredentialsOptions()
@@ -300,15 +310,18 @@ private static AWSCredentials GetAWSCredentialsInternal(
300310
UserIdentity = options.UserIdentity,
301311
ProfileName = profileName
302312
};
303-
return new FederatedAWSCredentials(new SAMLEndpointManager().GetEndpoint(options.EndpointName),
313+
awsCredentials = new FederatedAWSCredentials(new SAMLEndpointManager().GetEndpoint(options.EndpointName),
304314
options.RoleArn, federatedOptions);
315+
break;
305316
}
306317
else
307318
{
308319
return ThrowOrReturnNull("Federated credentials are not available on this platform.", null, throwIfInvalid);
309320
}
310321
case CredentialProfileType.CredentialProcess:
311-
return new ProcessAWSCredentials(options.CredentialProcess, options.AwsAccountId);
322+
awsCredentials = new ProcessAWSCredentials(options.CredentialProcess, options.AwsAccountId);
323+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_PROFILE_PROCESS);
324+
break;
312325

313326
default:
314327
var defaultMessage = profileName == null
@@ -319,6 +332,11 @@ private static AWSCredentials GetAWSCredentialsInternal(
319332

320333
return ThrowOrReturnNull(defaultMessage, null, throwIfInvalid);
321334
}
335+
336+
if (profileSource is NetSDKCredentialsFile)
337+
awsCredentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_AWS_SDK_STORE);
338+
339+
return awsCredentials;
322340
}
323341
else
324342
{

sdk/src/Core/Amazon.Runtime/Credentials/AWSCredentials.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
* permissions and limitations under the License.
1414
*/
1515

16-
1716
using Amazon.Runtime.Identity;
17+
using Amazon.Runtime.Internal.UserAgent;
18+
using System.Collections.Generic;
1819

1920
namespace Amazon.Runtime
2021
{
@@ -23,6 +24,16 @@ namespace Amazon.Runtime
2324
/// </summary>
2425
public abstract class AWSCredentials : BaseIdentity
2526
{
27+
/// <summary>
28+
/// Internal property that can be used to specify how this instance of AWS credentials were resolved.
29+
/// </summary>
30+
/// <remarks>
31+
/// Credential providers MUST add to this property to have their specific feature ID tracked.
32+
/// <para />
33+
/// If empty, no value will be included in the user agent header.
34+
/// </remarks>
35+
internal HashSet<UserAgentFeatureId> FeatureIdSources { get; set; } = new();
36+
2637
/// <summary>
2738
/// Returns a copy of ImmutableCredentials
2839
/// </summary>

sdk/src/Core/Amazon.Runtime/Credentials/AssumeRoleAWSCredentials.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,17 @@
1313
* permissions and limitations under the License.
1414
*/
1515
using Amazon.Runtime.Internal;
16+
using Amazon.Runtime.Internal.UserAgent;
1617
using Amazon.Runtime.Internal.Util;
1718
using Amazon.Runtime.SharedInterfaces;
1819
using Amazon.RuntimeDependencies;
1920
using Amazon.Util.Internal;
2021
using System;
22+
using System.Diagnostics.CodeAnalysis;
2123
using System.Globalization;
2224
using System.Net;
23-
using System.Diagnostics.CodeAnalysis;
24-
using ThirdParty.RuntimeBackports;
2525
using System.Threading.Tasks;
26+
using ThirdParty.RuntimeBackports;
2627

2728
namespace Amazon.Runtime
2829
{
@@ -33,7 +34,6 @@ namespace Amazon.Runtime
3334
public class AssumeRoleAWSCredentials : RefreshingAWSCredentials
3435
{
3536
private RegionEndpoint DefaultSTSClientRegion = RegionEndpoint.USEast1;
36-
3737
private Logger _logger = Logger.GetLogger(typeof(AssumeRoleAWSCredentials));
3838

3939
/// <summary>
@@ -85,6 +85,7 @@ public AssumeRoleAWSCredentials(AWSCredentials sourceCredentials, string roleArn
8585
RoleArn = roleArn;
8686
RoleSessionName = roleSessionName;
8787
Options = options;
88+
FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_STS_ASSUME_ROLE);
8889

8990
// Make sure to fetch new credentials well before the current credentials expire to avoid
9091
// any request being made with expired credentials.

sdk/src/Core/Amazon.Runtime/Credentials/AssumeRoleWithWebIdentityCredentials.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
using System.Net;
2727
using System.Text.RegularExpressions;
2828
using System.Threading.Tasks;
29+
using Amazon.Runtime.Internal.UserAgent;
2930

3031
namespace Amazon.Runtime
3132
{
@@ -65,6 +66,7 @@ public partial class AssumeRoleWithWebIdentityCredentials : RefreshingAWSCredent
6566
private AssumeRoleWithWebIdentityCredentialsOptions _options;
6667

6768
#region Properties
69+
6870
/// <summary>
6971
/// The absolute path to the file on disk containing an OIDC token
7072
/// </summary>
@@ -79,7 +81,8 @@ public partial class AssumeRoleWithWebIdentityCredentials : RefreshingAWSCredent
7981
/// An identifier for the assumed role session.
8082
/// </summary>
8183
public string RoleSessionName { get; }
82-
#endregion Properties
84+
85+
#endregion Properties
8386

8487
/// <summary>
8588
/// Constructs an AssumeRoleWithWebIdentityCredentials object.
@@ -122,6 +125,7 @@ public AssumeRoleWithWebIdentityCredentials(string webIdentityTokenFile, string
122125
RoleArn = roleArn;
123126
RoleSessionName = string.IsNullOrEmpty(roleSessionName) ? _roleSessionNameDefault : roleSessionName;
124127
_options = options;
128+
FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_STS_ASSUME_ROLE_WEB_ID);
125129

126130
// Make sure to fetch new credentials well before the current credentials expire to avoid
127131
// any request being made with expired credentials.
@@ -138,7 +142,11 @@ public static AssumeRoleWithWebIdentityCredentials FromEnvironmentVariables()
138142
var webIdentityTokenFile = Environment.GetEnvironmentVariable(WebIdentityTokenFileEnvVariable);
139143
var roleArn = Environment.GetEnvironmentVariable(RoleArnEnvVariable);
140144
var roleSessionName = Environment.GetEnvironmentVariable(RoleSessionNameEnvVariable);
141-
return new AssumeRoleWithWebIdentityCredentials(webIdentityTokenFile, roleArn, roleSessionName);
145+
146+
var credentials = new AssumeRoleWithWebIdentityCredentials(webIdentityTokenFile, roleArn, roleSessionName);
147+
credentials.FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_ENV_VARS_STS_WEB_ID_TOKEN);
148+
149+
return credentials;
142150
}
143151

144152
protected override CredentialsRefreshState GenerateNewCredentials()

sdk/src/Core/Amazon.Runtime/Credentials/BasicAWSCredentials.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* permissions and limitations under the License.
1414
*/
1515

16+
using Amazon.Runtime.Internal.UserAgent;
1617
using Amazon.Runtime.Internal.Util;
1718
using Amazon.Util;
1819

@@ -29,10 +30,8 @@ public class BasicAWSCredentials : AWSCredentials
2930

3031
#endregion
3132

32-
3333
#region Constructors
3434

35-
3635
/// <summary>
3736
/// Constructs a BasicAWSCredentials object for the specified accessKey and secretKey.
3837
/// </summary>
@@ -57,12 +56,12 @@ public BasicAWSCredentials(string accessKey, string secretKey, string accountId)
5756
if (!string.IsNullOrEmpty(accessKey))
5857
{
5958
_credentials = new ImmutableCredentials(accessKey, secretKey, null, accountId);
59+
FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_CODE);
6060
}
6161
}
6262

6363
#endregion
6464

65-
6665
#region Abstract class overrides
6766

6867
/// <summary>
@@ -92,7 +91,6 @@ public override bool Equals(object obj)
9291
new object[] { _credentials },
9392
new object[] { bac._credentials });
9493
}
95-
9694
public override int GetHashCode()
9795
{
9896
return Hashing.Hash(_credentials);

sdk/src/Core/Amazon.Runtime/Credentials/DefaultInstanceProfileAWSCredentials.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* express or implied. See the License for the specific language governing
1313
* permissions and limitations under the License.
1414
*/
15+
using Amazon.Runtime.Internal.UserAgent;
1516
using Amazon.Runtime.Internal.Util;
1617
using Amazon.Util;
1718
using System;
@@ -77,14 +78,18 @@ public static DefaultInstanceProfileAWSCredentials Instance
7778
private DefaultInstanceProfileAWSCredentials()
7879
{
7980
// if IMDS is turned off, no need to spin up the timer task
80-
if (!EC2InstanceMetadata.IsIMDSEnabled) return;
81+
if (!EC2InstanceMetadata.IsIMDSEnabled)
82+
{
83+
return;
84+
}
8185

8286
_logger = Logger.GetLogger(typeof(DefaultInstanceProfileAWSCredentials));
83-
8487
_credentialsRetrieverTimer = new Timer(RenewCredentials, null, TimeSpan.Zero, _neverTimespan); // This invokes synchronous calls in seperate thread.
88+
FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_IMDS);
8589
}
8690

8791
#region Overrides
92+
8893
/// <summary>
8994
/// Returns a copy of the most recent instance profile credentials.
9095
/// </summary>
@@ -262,7 +267,8 @@ public override async Task<ImmutableCredentials> GetCredentialsAsync()
262267

263268
return credentials;
264269
}
265-
#endregion
270+
271+
#endregion
266272

267273
#region Private members
268274
private void RenewCredentials(object unused)
@@ -366,7 +372,8 @@ private static void CheckIsIMDSEnabled()
366372
}
367373
#endregion
368374

369-
#region IDisposable Support
375+
#region IDisposable Support
376+
370377
private bool _isDisposed = false;
371378

372379
protected virtual void Dispose(bool disposing)
@@ -395,6 +402,7 @@ public void Dispose()
395402
Dispose(true);
396403
GC.SuppressFinalize(this);
397404
}
398-
#endregion
405+
406+
#endregion
399407
}
400408
}

sdk/src/Core/Amazon.Runtime/Credentials/EnvironmentVariablesAWSCredentials.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* express or implied. See the License for the specific language governing
1313
* permissions and limitations under the License.
1414
*/
15+
using Amazon.Runtime.Internal.UserAgent;
1516
using Amazon.Runtime.Internal.Util;
1617
using System;
1718
using System.Globalization;
@@ -56,6 +57,8 @@ public EnvironmentVariablesAWSCredentials()
5657

5758
// We need to do an initial fetch to validate that we can use environment variables to get the credentials.
5859
FetchCredentials();
60+
61+
FeatureIdSources.Add(UserAgentFeatureId.CREDENTIALS_ENV_VARS);
5962
}
6063

6164
#endregion

0 commit comments

Comments
 (0)