Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ExtraQP to inject telemetry SDK ID #2973

Merged
merged 2 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace Microsoft.Identity.Web
{
internal static class IdHelper
{
private const string IDWebSku = "IDWeb.";

private static readonly Lazy<string> s_idWebVersion = new Lazy<string>(
() =>
{
Expand All @@ -34,9 +36,14 @@ internal static class IdHelper
return version[1];
});

public static string CreateTelemetryInfo()
internal static string GetIdWebVersion()
{
return s_idWebVersion.Value;
}

internal static string CreateTelemetryInfo()
{
return string.Format(CultureInfo.InvariantCulture, Constants.IDWebSku + s_idWebVersion.Value);
return string.Format(CultureInfo.InvariantCulture, IDWebSku + s_idWebVersion.Value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Microsoft.Identity.Web.Diagnostics.IdHelper
Microsoft.Identity.Web.IdHelper
static Microsoft.Identity.Web.Diagnostics.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.Diagnostics.IdHelper.GetIdWebVersion() -> string!
static Microsoft.Identity.Web.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.IdHelper.GetIdWebVersion() -> string!
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Microsoft.Identity.Web.Diagnostics.IdHelper
Microsoft.Identity.Web.IdHelper
static Microsoft.Identity.Web.Diagnostics.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.Diagnostics.IdHelper.GetIdWebVersion() -> string!
static Microsoft.Identity.Web.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.IdHelper.GetIdWebVersion() -> string!
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Microsoft.Identity.Web.Diagnostics.IdHelper
Microsoft.Identity.Web.IdHelper
static Microsoft.Identity.Web.Diagnostics.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.Diagnostics.IdHelper.GetIdWebVersion() -> string!
static Microsoft.Identity.Web.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.IdHelper.GetIdWebVersion() -> string!
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Microsoft.Identity.Web.Diagnostics.IdHelper
Microsoft.Identity.Web.IdHelper
static Microsoft.Identity.Web.Diagnostics.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.Diagnostics.IdHelper.GetIdWebVersion() -> string!
static Microsoft.Identity.Web.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.IdHelper.GetIdWebVersion() -> string!
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Microsoft.Identity.Web.Diagnostics.IdHelper
Microsoft.Identity.Web.IdHelper
static Microsoft.Identity.Web.Diagnostics.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.Diagnostics.IdHelper.GetIdWebVersion() -> string!
static Microsoft.Identity.Web.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.IdHelper.GetIdWebVersion() -> string!
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Microsoft.Identity.Web.Diagnostics.IdHelper
Microsoft.Identity.Web.IdHelper
static Microsoft.Identity.Web.Diagnostics.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.Diagnostics.IdHelper.GetIdWebVersion() -> string!
static Microsoft.Identity.Web.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.IdHelper.GetIdWebVersion() -> string!
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Microsoft.Identity.Web.Diagnostics.IdHelper
Microsoft.Identity.Web.IdHelper
static Microsoft.Identity.Web.Diagnostics.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.Diagnostics.IdHelper.GetIdWebVersion() -> string!
static Microsoft.Identity.Web.IdHelper.CreateTelemetryInfo() -> string!
static Microsoft.Identity.Web.IdHelper.GetIdWebVersion() -> string!
48 changes: 36 additions & 12 deletions src/Microsoft.Identity.Web.DownstreamApi/DownstreamApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
Expand Down Expand Up @@ -167,8 +168,8 @@ public Task<HttpResponseMessage> CallApiForAppAsync(
HttpResponseMessage response = await CallApiInternalAsync(serviceName, effectiveOptions, false,
null, user, cancellationToken).ConfigureAwait(false);
return await DeserializeOutputAsync<TOutput>(response, effectiveOptions).ConfigureAwait(false);
}

}
#if NET8_0_OR_GREATER
/// <inheritdoc/>
public async Task<TOutput?> CallApiForUserAsync<TInput, TOutput>(
Expand Down Expand Up @@ -267,7 +268,7 @@ public Task<HttpResponseMessage> CallApiForAppAsync(
/// </summary>
/// <param name="optionsInstanceName">Named configuration.</param>
/// <param name="calledApiOptionsOverride">Delegate to override the configuration.</param>
internal /* for tests */ DownstreamApiOptions MergeOptions(
internal /* for tests */ DownstreamApiOptions MergeOptions(
string? optionsInstanceName,
Action<DownstreamApiOptions>? calledApiOptionsOverride)
{
Expand All @@ -293,7 +294,7 @@ public Task<HttpResponseMessage> CallApiForAppAsync(
/// <param name="optionsInstanceName">Named configuration.</param>
/// <param name="calledApiOptionsOverride">Delegate to override the configuration.</param>
/// <param name="httpMethod">Http method overriding the configuration options.</param>
internal /* for tests */ DownstreamApiOptions MergeOptions(
internal /* for tests */ DownstreamApiOptions MergeOptions(
string? optionsInstanceName,
Action<DownstreamApiOptionsReadOnlyHttpMethod>? calledApiOptionsOverride, HttpMethod httpMethod)
{
Expand All @@ -311,8 +312,8 @@ public Task<HttpResponseMessage> CallApiForAppAsync(
DownstreamApiOptionsReadOnlyHttpMethod clonedOptions = new DownstreamApiOptionsReadOnlyHttpMethod(options, httpMethod.ToString());
calledApiOptionsOverride?.Invoke(clonedOptions);
return clonedOptions;
}

}
internal static HttpContent? SerializeInput<TInput>(TInput input, DownstreamApiOptions effectiveOptions)
{
return SerializeInputImpl(input, effectiveOptions, null);
Expand Down Expand Up @@ -350,7 +351,7 @@ public Task<HttpResponseMessage> CallApiForAppAsync(
}

internal static async Task<TOutput?> DeserializeOutputAsync<TOutput>(HttpResponseMessage response, DownstreamApiOptions effectiveOptions)
where TOutput : class
where TOutput : class
{
try
{
Expand Down Expand Up @@ -398,8 +399,8 @@ public Task<HttpResponseMessage> CallApiForAppAsync(
}
return stringContent as TOutput;
}
}
}

private static async Task<TOutput?> DeserializeOutputImplAsync<TOutput>(HttpResponseMessage response, DownstreamApiOptions effectiveOptions, JsonTypeInfo<TOutput> outputJsonTypeInfo)
where TOutput : class
{
Expand Down Expand Up @@ -451,7 +452,7 @@ public Task<HttpResponseMessage> CallApiForAppAsync(
}
}

internal async Task<HttpResponseMessage> CallApiInternalAsync(
internal /* for tests */ async Task<HttpResponseMessage> CallApiInternalAsync(
string? serviceName,
DownstreamApiOptions effectiveOptions,
bool appToken,
Expand Down Expand Up @@ -494,14 +495,16 @@ internal async Task<HttpResponseMessage> CallApiInternalAsync(
return downstreamApiResult;
}

internal async Task UpdateRequestAsync(
internal /* internal for test */ async Task UpdateRequestAsync(
HttpRequestMessage httpRequestMessage,
HttpContent? content,
DownstreamApiOptions effectiveOptions,
bool appToken,
ClaimsPrincipal? user,
CancellationToken cancellationToken)
{
AddCallerSDKTelemetry(effectiveOptions);

if (content != null)
{
httpRequestMessage.Content = content;
Expand All @@ -517,7 +520,7 @@ internal async Task UpdateRequestAsync(
effectiveOptions.Scopes,
effectiveOptions,
user,
cancellationToken).ConfigureAwait(false);
cancellationToken).ConfigureAwait(false);

httpRequestMessage.Headers.Add(Authorization, authorizationHeader);
}
Expand All @@ -532,5 +535,26 @@ internal async Task UpdateRequestAsync(
// Opportunity to change the request message
effectiveOptions.CustomizeHttpRequestMessage?.Invoke(httpRequestMessage);
}

bgavrilMS marked this conversation as resolved.
Show resolved Hide resolved
internal /* for test */ static Dictionary<string, string> CallerSDKDetails { get; } = new()
{
{ "caller-sdk-id", "IdWeb_1" },
{ "caller-sdk-ver", IdHelper.GetIdWebVersion() }
};

private static void AddCallerSDKTelemetry(DownstreamApiOptions effectiveOptions)
{
if (effectiveOptions.AcquireTokenOptions.ExtraQueryParameters == null)
bgavrilMS marked this conversation as resolved.
Show resolved Hide resolved
{
effectiveOptions.AcquireTokenOptions.ExtraQueryParameters = CallerSDKDetails;
}
else
{
effectiveOptions.AcquireTokenOptions.ExtraQueryParameters["caller-sdk-id"] =
CallerSDKDetails["caller-sdk-id"];
effectiveOptions.AcquireTokenOptions.ExtraQueryParameters["caller-sdk-ver"] =
CallerSDKDetails["caller-sdk-ver"];
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
bn
static Microsoft.Identity.Web.DownstreamApi.CallerSDKDetails.get -> System.Collections.Generic.Dictionary<string!, string!>!
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
static Microsoft.Identity.Web.DownstreamApi.CallerSDKDetails.get -> System.Collections.Generic.Dictionary<string!, string!>!
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
static Microsoft.Identity.Web.DownstreamApi.CallerSDKDetails.get -> System.Collections.Generic.Dictionary<string!, string!>!
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
static Microsoft.Identity.Web.DownstreamApi.CallerSDKDetails.get -> System.Collections.Generic.Dictionary<string!, string!>!
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
static Microsoft.Identity.Web.DownstreamApi.CallerSDKDetails.get -> System.Collections.Generic.Dictionary<string!, string!>!
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
static Microsoft.Identity.Web.DownstreamApi.CallerSDKDetails.get -> System.Collections.Generic.Dictionary<string!, string!>!
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
static Microsoft.Identity.Web.DownstreamApi.CallerSDKDetails.get -> System.Collections.Generic.Dictionary<string!, string!>!
1 change: 0 additions & 1 deletion src/Microsoft.Identity.Web.TokenAcquisition/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ public static class Constants

// Telemetry headers
internal const string TelemetryHeaderKey = "x-client-brkrver";
internal const string IDWebSku = "IDWeb.";

// Authorize for scopes attributes
internal const string XReturnUrl = "x-ReturnUrl";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,51 @@ public async Task UpdateRequestAsync_WithContent_AddsContentToRequestAsync()
// Arrange
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "https://example.com");
var content = new StringContent("test content");
var options = new DownstreamApiOptions();

// Act
await _input.UpdateRequestAsync(httpRequestMessage, content, new DownstreamApiOptions(), false, null, CancellationToken.None);
await _input.UpdateRequestAsync(httpRequestMessage, content, options, false, null, CancellationToken.None);

// Assert
Assert.Equal(content, httpRequestMessage.Content);
Assert.Equal("application/json", httpRequestMessage.Headers.Accept.Single().MediaType);
Assert.Equal("text/plain", httpRequestMessage.Content?.Headers.ContentType?.MediaType);
Assert.Equal(options.AcquireTokenOptions.ExtraQueryParameters, DownstreamApi.CallerSDKDetails);
}


[Fact]
public async Task UpdateRequestAsync_AddsToExtraQP()
{
// Arrange
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "https://example.com");
var content = new StringContent("test content");
var options = new DownstreamApiOptions() {
AcquireTokenOptions = new AcquireTokenOptions() {
ExtraQueryParameters = new Dictionary<string, string>()
{
{ "n1", "v1" },
{ "n2", "v2" },
{ "caller-sdk-id", "bogus" } // value will be overwritten by the SDK
}
} };

// Act
await _input.UpdateRequestAsync(httpRequestMessage, content, options, false, null, CancellationToken.None);

// Assert
Assert.Equal(content, httpRequestMessage.Content);
Assert.Equal("application/json", httpRequestMessage.Headers.Accept.Single().MediaType);
Assert.Equal("text/plain", httpRequestMessage.Content?.Headers.ContentType?.MediaType);
Assert.Equal("v1", options.AcquireTokenOptions.ExtraQueryParameters["n1"]);
Assert.Equal("v2", options.AcquireTokenOptions.ExtraQueryParameters["n2"]);
Assert.Equal(
DownstreamApi.CallerSDKDetails["caller-sdk-id"],
options.AcquireTokenOptions.ExtraQueryParameters["caller-sdk-id"] );
Assert.Equal(
DownstreamApi.CallerSDKDetails["caller-sdk-ver"],
options.AcquireTokenOptions.ExtraQueryParameters["caller-sdk-ver"]);

}

[Theory]
Expand All @@ -83,6 +120,7 @@ public async Task UpdateRequestAsync_WithScopes_AddsAuthorizationHeaderToRequest
Assert.Equal("ey", httpRequestMessage.Headers.Authorization?.Parameter);
Assert.Equal("Bearer", httpRequestMessage.Headers.Authorization?.Scheme);
Assert.Equal("application/json", httpRequestMessage.Headers.Accept.Single().MediaType);
Assert.Equal(options.AcquireTokenOptions.ExtraQueryParameters, DownstreamApi.CallerSDKDetails);
}

[Fact]
Expand Down
Loading