From 64c6e6012e318ea6ae290fb74310c43a35470b3d Mon Sep 17 00:00:00 2001 From: Ross Grambo <rossgrambo@microsoft.com> Date: Thu, 20 Jun 2024 11:14:07 -0700 Subject: [PATCH 1/4] Switches to Activity for storing TargetingId and removes Microsoft.FeatureManagement.Telemetry.AspNetCore project --- ...EvaluationDataToApplicationInsights.csproj | 1 - .../Program.cs | 2 +- examples/VariantServiceDemo/Program.cs | 2 +- .../TargetingHttpContextMiddleware.cs | 13 +++-- .../TargetingTelemetryInitializer.cs | 52 +++++++++++++++++++ 5 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs diff --git a/examples/EvaluationDataToApplicationInsights/EvaluationDataToApplicationInsights.csproj b/examples/EvaluationDataToApplicationInsights/EvaluationDataToApplicationInsights.csproj index d3a84c9d..f4f7bbc6 100644 --- a/examples/EvaluationDataToApplicationInsights/EvaluationDataToApplicationInsights.csproj +++ b/examples/EvaluationDataToApplicationInsights/EvaluationDataToApplicationInsights.csproj @@ -12,7 +12,6 @@ <ItemGroup> <ProjectReference Include="..\..\src\Microsoft.FeatureManagement.AspNetCore\Microsoft.FeatureManagement.AspNetCore.csproj" /> - <ProjectReference Include="..\..\src\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj" /> <ProjectReference Include="..\..\src\Microsoft.FeatureManagement.Telemetry.ApplicationInsights\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.csproj" /> </ItemGroup> diff --git a/examples/EvaluationDataToApplicationInsights/Program.cs b/examples/EvaluationDataToApplicationInsights/Program.cs index 2274fcb0..bf83d5d6 100644 --- a/examples/EvaluationDataToApplicationInsights/Program.cs +++ b/examples/EvaluationDataToApplicationInsights/Program.cs @@ -4,7 +4,7 @@ using EvaluationDataToApplicationInsights; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.FeatureManagement; -using Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore; +using Microsoft.FeatureManagement.Telemetry.ApplicationInsights; var builder = WebApplication.CreateBuilder(args); diff --git a/examples/VariantServiceDemo/Program.cs b/examples/VariantServiceDemo/Program.cs index b3a4bcfa..89e17c2c 100644 --- a/examples/VariantServiceDemo/Program.cs +++ b/examples/VariantServiceDemo/Program.cs @@ -4,7 +4,7 @@ using VariantServiceDemo; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.FeatureManagement; -using Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore; +using Microsoft.FeatureManagement.Telemetry.ApplicationInsights; var builder = WebApplication.CreateBuilder(args); diff --git a/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs b/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs index 8dd2378f..fdf4974e 100644 --- a/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs +++ b/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs @@ -3,9 +3,11 @@ // using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.Logging; using Microsoft.FeatureManagement.FeatureFilters; using System; +using System.Net.Http; using System.Threading.Tasks; namespace Microsoft.FeatureManagement @@ -34,11 +36,11 @@ public TargetingHttpContextMiddleware(RequestDelegate next, ILoggerFactory logge /// <param name="context">The <see cref="HttpContext"/> to add the targeting information to.</param> /// <param name="targetingContextAccessor">The <see cref="ITargetingContextAccessor"/> to retrieve the targeting information from.</param> /// <exception cref="ArgumentNullException">Thrown if the provided context or targetingContextAccessor is null.</exception> - public async Task InvokeAsync(HttpContext context, ITargetingContextAccessor targetingContextAccessor) + public async Task InvokeAsync(HttpContext httpContext, ITargetingContextAccessor targetingContextAccessor) { - if (context == null) + if (httpContext == null) { - throw new ArgumentNullException(nameof(context)); + throw new ArgumentNullException(nameof(httpContext)); } if (targetingContextAccessor == null) @@ -50,14 +52,15 @@ public async Task InvokeAsync(HttpContext context, ITargetingContextAccessor tar if (targetingContext != null) { - context.Items[TargetingIdKey] = targetingContext.UserId; + var activityFeature = httpContext.Features.Get<IHttpActivityFeature>(); + activityFeature.Activity.AddBaggage(TargetingIdKey, targetingContext.UserId); } else { _logger.LogDebug("The targeting context accessor returned a null TargetingContext"); } - await _next(context); + await _next(httpContext); } } } diff --git a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs b/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs new file mode 100644 index 00000000..7ff7aa87 --- /dev/null +++ b/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// + +using Microsoft.ApplicationInsights.Channel; +using Microsoft.ApplicationInsights.DataContracts; +using Microsoft.ApplicationInsights.Extensibility; +using System.Diagnostics; + +namespace Microsoft.FeatureManagement.Telemetry.ApplicationInsights +{ + /// <summary> + /// Used to add targeting information to outgoing Application Insights telemetry. + /// </summary> + public class TargetingTelemetryInitializer : ITelemetryInitializer + { + private const string TargetingIdKey = $"Microsoft.FeatureManagement.TargetingId"; + + /// <summary> + /// Creates an instance of the TargetingTelemetryInitializer + /// </summary> + public TargetingTelemetryInitializer() { } + + /// <summary> + /// When telemetry is initialized, adds targeting information to all relevant telemetry. + /// </summary> + /// <param name="telemetry">The <see cref="ITelemetry"/> to be initialized.</param> + /// <exception cref="ArgumentNullException">Thrown if the any param is null.</exception> + public void Initialize(ITelemetry telemetry) + { + if (telemetry == null) + { + throw new ArgumentNullException(nameof(telemetry)); + } + + // Extract the targeting id from the current activity's baggage + string targetingId = Activity.Current?.Baggage.FirstOrDefault(t => t.Key == TargetingIdKey).Value; + + // Don't modify telemetry if there's no available targeting id + if (string.IsNullOrEmpty(targetingId)) + { + return; + } + + // Telemetry.Properties is deprecated in favor of ISupportProperties + if (telemetry is ISupportProperties telemetryWithSupportProperties) + { + telemetryWithSupportProperties.Properties["TargetingId"] = targetingId; + } + } + } +} From 956c99a34c6b1eeda23e51991f527d09f02d5d3e Mon Sep 17 00:00:00 2001 From: Ross Grambo <rossgrambo@microsoft.com> Date: Thu, 27 Jun 2024 10:53:49 -0700 Subject: [PATCH 2/4] Removes Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore --- Microsoft.FeatureManagement.sln | 6 -- pack.ps1 | 3 +- ...etry.ApplicationInsights.AspNetCore.csproj | 52 --------------- .../TargetingTelemetryInitializer.cs | 63 ------------------- 4 files changed, 1 insertion(+), 123 deletions(-) delete mode 100644 src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj delete mode 100644 src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/TargetingTelemetryInitializer.cs diff --git a/Microsoft.FeatureManagement.sln b/Microsoft.FeatureManagement.sln index 2da0237c..3b8c8661 100644 --- a/Microsoft.FeatureManagement.sln +++ b/Microsoft.FeatureManagement.sln @@ -27,8 +27,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FeatureManagement EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EvaluationDataToApplicationInsights", "examples\EvaluationDataToApplicationInsights\EvaluationDataToApplicationInsights.csproj", "{1502529E-47E9-4306-98C4-BF6CF7C7C275}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore", "src\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj", "{C647611B-A8E5-4AD7-9DBA-60DDE276644B}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorServerApp", "examples\BlazorServerApp\BlazorServerApp.csproj", "{12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VariantServiceDemo", "examples\VariantServiceDemo\VariantServiceDemo.csproj", "{E8E17CB9-434E-4386-BF96-FA53BBFDCD6F}" @@ -79,10 +77,6 @@ Global {1502529E-47E9-4306-98C4-BF6CF7C7C275}.Debug|Any CPU.Build.0 = Debug|Any CPU {1502529E-47E9-4306-98C4-BF6CF7C7C275}.Release|Any CPU.ActiveCfg = Release|Any CPU {1502529E-47E9-4306-98C4-BF6CF7C7C275}.Release|Any CPU.Build.0 = Release|Any CPU - {C647611B-A8E5-4AD7-9DBA-60DDE276644B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C647611B-A8E5-4AD7-9DBA-60DDE276644B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C647611B-A8E5-4AD7-9DBA-60DDE276644B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C647611B-A8E5-4AD7-9DBA-60DDE276644B}.Release|Any CPU.Build.0 = Release|Any CPU {12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}.Debug|Any CPU.Build.0 = Debug|Any CPU {12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/pack.ps1 b/pack.ps1 index 12274bbd..efe1835e 100644 --- a/pack.ps1 +++ b/pack.ps1 @@ -22,8 +22,7 @@ $targetProjects = @( "Microsoft.FeatureManagement", "Microsoft.FeatureManagement.AspNetCore", - "Microsoft.FeatureManagement.Telemetry.ApplicationInsights", - "Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore" + "Microsoft.FeatureManagement.Telemetry.ApplicationInsights" ) # Create the log directory. diff --git a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj b/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj deleted file mode 100644 index 0c4eb847..00000000 --- a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj +++ /dev/null @@ -1,52 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - <Import Project="..\..\build\NugetProperties.props" /> - - <!-- Official Version --> - <PropertyGroup> - <MajorVersion>4</MajorVersion> - <MinorVersion>0</MinorVersion> - <PatchVersion>0</PatchVersion> - <PreviewVersion>-preview3</PreviewVersion> - </PropertyGroup> - - <Import Project="..\..\build\Versioning.props" /> - - <PropertyGroup> - <TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks> - <ImplicitUsings>enable</ImplicitUsings> - <SignAssembly>true</SignAssembly> - <DelaySign>false</DelaySign> - <AssemblyOriginatorKeyFile>..\..\build\Microsoft.FeatureManagement.snk</AssemblyOriginatorKeyFile> - </PropertyGroup> - - <PropertyGroup> - <Description>Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore provides a solution for tagging Application Insights telemetry with Microsoft.FeatureManagement targeting information.</Description> - <Authors>Microsoft</Authors> - <Company>Microsoft</Company> - <PackageLicenseUrl>https://licenses.nuget.org/MIT</PackageLicenseUrl> - <PackageProjectUrl>https://github.com/Azure/AppConfiguration</PackageProjectUrl> - <PackageReleaseNotes>Release notes can be found at https://aka.ms/MicrosoftFeatureManagementReleaseNotes</PackageReleaseNotes> - <PackageTags>Microsoft FeatureManagement FeatureFlags ApplicationInsights</PackageTags> - <PackageIconUrl>https://aka.ms/AzureAppConfigurationPackageIcon</PackageIconUrl> - <Copyright>© Microsoft Corporation. All rights reserved.</Copyright> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Microsoft.ApplicationInsights" Version="2.22.0" /> - <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" /> - </ItemGroup> - - <ItemGroup> - <ProjectReference Include="..\Microsoft.FeatureManagement\Microsoft.FeatureManagement.csproj" /> - <ProjectReference Include="..\Microsoft.FeatureManagement.Telemetry.ApplicationInsights\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.csproj" /> - </ItemGroup> - - <PropertyGroup> - <DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\XMLComments\$(MSBuildProjectName).xml</DocumentationFile> - </PropertyGroup> - - <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish"> - <Copy SourceFiles="$(DocumentationFile)" DestinationFolder="$(OutDir)\XMLComments" SkipUnchangedFiles="false" /> - </Target> - -</Project> diff --git a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/TargetingTelemetryInitializer.cs b/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/TargetingTelemetryInitializer.cs deleted file mode 100644 index e01bd9e4..00000000 --- a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/TargetingTelemetryInitializer.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// - -using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; -using Microsoft.ApplicationInsights.Channel; -using Microsoft.ApplicationInsights.DataContracts; -using Microsoft.AspNetCore.Http; - -namespace Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore -{ - /// <summary> - /// Used to add targeting information to outgoing Application Insights telemetry. - /// </summary> - public class TargetingTelemetryInitializer : TelemetryInitializerBase - { - private const string TargetingIdKey = $"Microsoft.FeatureManagement.TargetingId"; - - /// <summary> - /// Creates an instance of the TargetingTelemetryInitializer - /// </summary> - public TargetingTelemetryInitializer(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor) - { - } - - /// <summary> - /// When telemetry is initialized, adds targeting information to all relevant telemetry. - /// </summary> - /// <param name="httpContext">The <see cref="HttpContext"/> to get the targeting information from.</param> - /// <param name="requestTelemetry">The <see cref="RequestTelemetry"/> relevant to the telemetry.</param> - /// <param name="telemetry">The <see cref="ITelemetry"/> to be initialized.</param> - /// <exception cref="ArgumentNullException">Thrown if the any param is null.</exception> - protected override void OnInitializeTelemetry(HttpContext httpContext, RequestTelemetry requestTelemetry, ITelemetry telemetry) - { - if (telemetry == null) - { - throw new ArgumentNullException(nameof(telemetry)); - } - - if (httpContext == null) - { - throw new ArgumentNullException(nameof(httpContext)); - } - - // Extract the targeting id from the http context - string targetingId = null; - - if (httpContext.Items.TryGetValue(TargetingIdKey, out object value)) - { - targetingId = value?.ToString(); - } - - if (!string.IsNullOrEmpty(targetingId)) - { - // Telemetry.Properties is deprecated in favor of ISupportProperties - if (telemetry is ISupportProperties telemetryWithSupportProperties) - { - telemetryWithSupportProperties.Properties["TargetingId"] = targetingId; - } - } - } - } -} From ca04dd37c887788c8f143fc23cbf22ddad561a36 Mon Sep 17 00:00:00 2001 From: Ross Grambo <rossgrambo@microsoft.com> Date: Thu, 27 Jun 2024 11:33:14 -0700 Subject: [PATCH 3/4] Adds null check in middleware --- examples/VariantServiceDemo/VariantServiceDemo.csproj | 1 - .../TargetingHttpContextMiddleware.cs | 7 ++++--- .../TargetingTelemetryInitializer.cs | 5 ----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/examples/VariantServiceDemo/VariantServiceDemo.csproj b/examples/VariantServiceDemo/VariantServiceDemo.csproj index d3a84c9d..f4f7bbc6 100644 --- a/examples/VariantServiceDemo/VariantServiceDemo.csproj +++ b/examples/VariantServiceDemo/VariantServiceDemo.csproj @@ -12,7 +12,6 @@ <ItemGroup> <ProjectReference Include="..\..\src\Microsoft.FeatureManagement.AspNetCore\Microsoft.FeatureManagement.AspNetCore.csproj" /> - <ProjectReference Include="..\..\src\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj" /> <ProjectReference Include="..\..\src\Microsoft.FeatureManagement.Telemetry.ApplicationInsights\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.csproj" /> </ItemGroup> diff --git a/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs b/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs index fdf4974e..97db0c6e 100644 --- a/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs +++ b/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs @@ -25,7 +25,8 @@ public class TargetingHttpContextMiddleware /// <summary> /// Creates an instance of the TargetingHttpContextMiddleware /// </summary> - public TargetingHttpContextMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { + public TargetingHttpContextMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) + { _next = next ?? throw new ArgumentNullException(nameof(next)); _logger = loggerFactory?.CreateLogger<TargetingHttpContextMiddleware>() ?? throw new ArgumentNullException(nameof(loggerFactory)); } @@ -33,7 +34,7 @@ public TargetingHttpContextMiddleware(RequestDelegate next, ILoggerFactory logge /// <summary> /// Adds targeting information to the HTTP context. /// </summary> - /// <param name="context">The <see cref="HttpContext"/> to add the targeting information to.</param> + /// <param name="httpContext">The <see cref="HttpContext"/> to add the targeting information to.</param> /// <param name="targetingContextAccessor">The <see cref="ITargetingContextAccessor"/> to retrieve the targeting information from.</param> /// <exception cref="ArgumentNullException">Thrown if the provided context or targetingContextAccessor is null.</exception> public async Task InvokeAsync(HttpContext httpContext, ITargetingContextAccessor targetingContextAccessor) @@ -53,7 +54,7 @@ public async Task InvokeAsync(HttpContext httpContext, ITargetingContextAccessor if (targetingContext != null) { var activityFeature = httpContext.Features.Get<IHttpActivityFeature>(); - activityFeature.Activity.AddBaggage(TargetingIdKey, targetingContext.UserId); + activityFeature?.Activity?.AddBaggage(TargetingIdKey, targetingContext.UserId); } else { diff --git a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs b/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs index 7ff7aa87..7c2948e6 100644 --- a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs +++ b/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs @@ -16,11 +16,6 @@ public class TargetingTelemetryInitializer : ITelemetryInitializer { private const string TargetingIdKey = $"Microsoft.FeatureManagement.TargetingId"; - /// <summary> - /// Creates an instance of the TargetingTelemetryInitializer - /// </summary> - public TargetingTelemetryInitializer() { } - /// <summary> /// When telemetry is initialized, adds targeting information to all relevant telemetry. /// </summary> From 4d61d157c7c51d2a0e8e595ce8cba84ef94eaad8 Mon Sep 17 00:00:00 2001 From: Ross Grambo <rossgrambo@microsoft.com> Date: Wed, 3 Jul 2024 15:11:50 -0700 Subject: [PATCH 4/4] Added debug logs for unexpected nulls --- .../TargetingHttpContextMiddleware.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs b/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs index 97db0c6e..6103bfa1 100644 --- a/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs +++ b/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs @@ -54,7 +54,19 @@ public async Task InvokeAsync(HttpContext httpContext, ITargetingContextAccessor if (targetingContext != null) { var activityFeature = httpContext.Features.Get<IHttpActivityFeature>(); - activityFeature?.Activity?.AddBaggage(TargetingIdKey, targetingContext.UserId); + + if (activityFeature == null) + { + _logger.LogDebug("The IHttpActivityFeature from the IFeatureCollection was null"); + } + else if (activityFeature.Activity == null) + { + _logger.LogDebug("The Activity on the IHttpActivityFeature was null"); + } + else + { + activityFeature.Activity.AddBaggage(TargetingIdKey, targetingContext.UserId); + } } else {