forked from Azure/azure-sdk-for-net
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
API for setting dynamic package data for the UserAgent header per Htt…
…pMessage (Azure#27079) * API for SetUserAgentString
- Loading branch information
1 parent
11e1eb1
commit 8ce87d2
Showing
14 changed files
with
264 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
namespace Azure.Core.Pipeline | ||
{ | ||
/// <summary> | ||
/// Extension methods for <see cref="HttpMessage"/>. | ||
/// </summary> | ||
public static class HttpMessageExtensions | ||
{ | ||
/// <summary> | ||
/// Sets the package name and version portion of the UserAgent telemetry value. | ||
/// Note: If <see cref="DiagnosticsOptions.IsTelemetryEnabled"/> is false, this value is never used. | ||
/// </summary> | ||
/// <param name="message">The <see cref="HttpMessage"/>.</param> | ||
/// <param name="userAgentValue">The <see cref="SetUserAgentString"/>.</param> | ||
public static void SetUserAgentString(this HttpMessage message, UserAgentValue userAgentValue) | ||
{ | ||
message.SetInternalProperty(typeof(UserAgentValueKey), userAgentValue.ToString()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 10 additions & 13 deletions
23
sdk/core/Azure.Core/src/Pipeline/Internal/TelemetryPolicy.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,27 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System.Runtime.InteropServices; | ||
|
||
namespace Azure.Core.Pipeline | ||
{ | ||
internal class TelemetryPolicy : HttpPipelineSynchronousPolicy | ||
{ | ||
private readonly string _header; | ||
private readonly string _defaultHeader; | ||
|
||
public TelemetryPolicy(string componentName, string componentVersion, string? applicationId) | ||
public TelemetryPolicy(UserAgentValue userAgentValue) | ||
{ | ||
_defaultHeader = userAgentValue.ToString(); | ||
} | ||
|
||
public override void OnSendingRequest(HttpMessage message) | ||
{ | ||
var platformInformation = $"({RuntimeInformation.FrameworkDescription}; {RuntimeInformation.OSDescription})"; | ||
if (applicationId != null) | ||
if (message.TryGetInternalProperty(typeof(UserAgentValueKey), out var userAgent)) | ||
{ | ||
_header = $"{applicationId} azsdk-net-{componentName}/{componentVersion} {platformInformation}"; | ||
message.Request.Headers.Add(HttpHeader.Names.UserAgent, ((string)userAgent!)); | ||
} | ||
else | ||
{ | ||
_header = $"azsdk-net-{componentName}/{componentVersion} {platformInformation}"; | ||
message.Request.Headers.Add(HttpHeader.Names.UserAgent, _defaultHeader); | ||
} | ||
} | ||
|
||
public override void OnSendingRequest(HttpMessage message) | ||
{ | ||
message.Request.Headers.Add(HttpHeader.Names.UserAgent, _header); | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
sdk/core/Azure.Core/src/Pipeline/Internal/UserAgentValueKey.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
namespace Azure.Core.Pipeline | ||
{ | ||
/// <summary> | ||
/// Class that serves as the key for <see cref="UserAgentValue"/> UserAgent strings on <see cref="HttpMessage"/>. | ||
/// </summary> | ||
internal class UserAgentValueKey { } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.Reflection; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace Azure.Core.Pipeline | ||
{ | ||
/// <summary> | ||
/// Information about the package to be included in UserAgent telemetry | ||
/// </summary> | ||
public class UserAgentValue | ||
{ | ||
private string _userAgent; | ||
|
||
/// <summary> | ||
/// Initialize an instance of <see cref="UserAgentValue"/> by extracting the name and version information from the <see cref="Assembly"/> associated with the <paramref name="type"/>. | ||
/// </summary> | ||
/// <param name="type">The <see cref="Type"/> used to generate the package name and version information for the <see cref="UserAgentValue"/> value.</param> | ||
/// <param name="applicationId">An optional value to be prepended to the <see cref="UserAgentValue"/>. | ||
/// This value overrides the behavior of the <see cref="DiagnosticsOptions.ApplicationId"/> property for the <see cref="HttpMessage"/> it is applied to.</param> | ||
public UserAgentValue(Type type, string? applicationId = null) | ||
{ | ||
var assembly = Assembly.GetAssembly(type); | ||
if (assembly == null) throw new ArgumentException($"The type parameter {type.FullName} does not have a valid Assembly"); | ||
_userAgent = GenerateUserAgentString(assembly, applicationId); | ||
} | ||
|
||
/// <summary> | ||
/// Creates an instance of a <see cref="UserAgentValue"/> based on the Type provided. | ||
/// </summary> | ||
/// <param name="applicationId"></param> | ||
/// <typeparam name="T">The type contained by the Assembly used to generate package name and version information.</typeparam> | ||
/// <returns></returns> | ||
public static UserAgentValue FromType<T>(string? applicationId = null) | ||
{ | ||
return new UserAgentValue(typeof(T), applicationId); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a formatted UserAgent string | ||
/// </summary> | ||
public override string ToString() => _userAgent; | ||
|
||
internal static string GenerateUserAgentString(Assembly clientAssembly, string? applicationId = null) | ||
{ | ||
const string PackagePrefix = "Azure."; | ||
|
||
AssemblyInformationalVersionAttribute? versionAttribute = clientAssembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>(); | ||
if (versionAttribute == null) | ||
{ | ||
throw new InvalidOperationException( | ||
$"{nameof(AssemblyInformationalVersionAttribute)} is required on client SDK assembly '{clientAssembly.FullName}'."); | ||
} | ||
|
||
string version = versionAttribute.InformationalVersion; | ||
|
||
string assemblyName = clientAssembly.GetName().Name!; | ||
if (assemblyName.StartsWith(PackagePrefix, StringComparison.Ordinal)) | ||
{ | ||
assemblyName = assemblyName.Substring(PackagePrefix.Length); | ||
} | ||
|
||
int hashSeparator = version.IndexOfOrdinal('+'); | ||
if (hashSeparator != -1) | ||
{ | ||
version = version.Substring(0, hashSeparator); | ||
} | ||
var platformInformation = $"({RuntimeInformation.FrameworkDescription}; {RuntimeInformation.OSDescription})"; | ||
|
||
return applicationId != null | ||
? $"{applicationId} azsdk-net-{assemblyName}/{version} {platformInformation}" | ||
: $"azsdk-net-{assemblyName}/{version} {platformInformation}"; | ||
} | ||
} | ||
} |
Oops, something went wrong.