From 84eba5cd001f8eee8e357bde7cb0db575150643d Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 11 Mar 2021 15:32:41 -0800 Subject: [PATCH 01/93] getting started. defining classes and tests --- BASE/Microsoft.ApplicationInsights.sln | 23 +++++++++ .../CredentialEnvelopeTests.cs | 48 +++++++++++++++++++ ...cationInsights.Authentication.Tests.csproj | 26 ++++++++++ .../Authentication/ICredentialEnvelope.cs | 13 +++++ .../ReflectionCredentialEnvelope.cs | 45 +++++++++++++++++ .../Authentication/TokenCredentialEnvelope.cs | 25 ++++++++++ .../Extensibility/TelemetryConfiguration.cs | 15 ++++++ .../Microsoft.ApplicationInsights.csproj | 4 ++ 8 files changed, 199 insertions(+) create mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs create mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj create mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs create mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs create mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs diff --git a/BASE/Microsoft.ApplicationInsights.sln b/BASE/Microsoft.ApplicationInsights.sln index 694d831138..9fad27051b 100644 --- a/BASE/Microsoft.ApplicationInsights.sln +++ b/BASE/Microsoft.ApplicationInsights.sln @@ -42,6 +42,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ApplicationInsigh EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelemetryChannel.Tests", "Test\ServerTelemetryChannel.Test\TelemetryChannel.Tests\TelemetryChannel.Tests.csproj", "{7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.ApplicationInsights.Authentication.Tests", "Test\Microsoft.ApplicationInsights.Test\Microsoft.ApplicationInsights.Authentication.Tests\Microsoft.ApplicationInsights.Authentication.Tests.csproj", "{AADBCDDC-3BD4-434E-B474-B832133AFC84}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\Common\Common\Common.projitems*{3273d899-d9b3-44fe-b3ab-578e18b2ef90}*SharedItemsImports = 5 @@ -202,6 +204,26 @@ Global {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x64.Build.0 = Release|Any CPU {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x86.ActiveCfg = Release|Any CPU {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x86.Build.0 = Release|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|ARM.ActiveCfg = Debug|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|ARM.Build.0 = Debug|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|x64.ActiveCfg = Debug|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|x64.Build.0 = Debug|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|x86.ActiveCfg = Debug|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|x86.Build.0 = Debug|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|Any CPU.Build.0 = Release|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|ARM.ActiveCfg = Release|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|ARM.Build.0 = Release|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|x64.ActiveCfg = Release|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|x64.Build.0 = Release|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|x86.ActiveCfg = Release|Any CPU + {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -215,6 +237,7 @@ Global {3273D899-D9B3-44FE-B3AB-578E18B2EF90} = {E7B0521E-DA4D-40EA-B55D-ADCBDA69027C} {EF007559-EA01-4D4A-9BEB-8CC661797BE5} = {C2FEEDE5-8CAE-41A4-8932-42D284A86EA7} {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4} = {A61B048F-ECEA-4BED-A2ED-22834E7D4DFB} + {AADBCDDC-3BD4-434E-B474-B832133AFC84} = {C2FEEDE5-8CAE-41A4-8932-42D284A86EA7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F70D4C7C-02FB-4EE9-875A-A2F95EC90EAC} diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs new file mode 100644 index 0000000000..c159789dd2 --- /dev/null +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs @@ -0,0 +1,48 @@ +namespace Microsoft.ApplicationInsights.Authentication.Tests +{ + using System; + using System.Threading; + using System.Threading.Tasks; + + using Azure.Core; + + using Microsoft.ApplicationInsights.Extensibility; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class CredentialEnvelopeTests + { + [TestMethod] + public void VerifyCanSetCredential() + { + var defaultTokenCredential = new Azure.Identity.DefaultAzureCredential(); + + var telemetryConfiguration = new TelemetryConfiguration(); + telemetryConfiguration.SetCredential(defaultTokenCredential); + + + var credentialEnvelope = telemetryConfiguration.CredentialEnvelope; +#if NET461 + Assert.IsInstanceOfType(credentialEnvelope, typeof(ReflectionCredentialEnvelope)); +#elif NET5_0 + Assert.IsInstanceOfType(credentialEnvelope, typeof(TokenCredentialEnvelope)); +#else + throw new System.Exception("this is a testing gap."); +#endif + + Assert.AreEqual(defaultTokenCredential, telemetryConfiguration.CredentialEnvelope.Credential); + } + +#if NET461 + [TestMethod] + [ExpectedException(typeof(System.Exception))] + public void VerifyCannotSetInvalidType() + { + var telemetryConfiguration = new TelemetryConfiguration(); + telemetryConfiguration.SetCredential(Guid.Empty); + } +#endif + } + +} diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj new file mode 100644 index 0000000000..acfe90d218 --- /dev/null +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj @@ -0,0 +1,26 @@ + + + + net461;net5.0 + + false + + + + + + + + + + + + + + + + + + + + diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs new file mode 100644 index 0000000000..d948b49a29 --- /dev/null +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs @@ -0,0 +1,13 @@ +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +{ + using System.Threading.Tasks; + + public interface ICredentialEnvelope + { + object Credential { get; } + + string GetToken(); + + Task GetTokenAsync(); + } +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs new file mode 100644 index 0000000000..51233bfe96 --- /dev/null +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -0,0 +1,45 @@ +#if NET452 || NET46 +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + /// + /// + /// + /// + /// Our SDK currently targets net452, net46, and netstandard2.0. + /// Azure.Core.TokenCredential is only available for netstandard2.0. + /// I'm introducing this class as a wrapper so we can receive an instance of this class and pass it around within our SDK. + /// + public class ReflectionCredentialEnvelope : ICredentialEnvelope + { + /// + /// + /// + /// + /// Must use reflection to verify that this object is an instance of Azure.Core.TokenCredential. + /// + /// + public ReflectionCredentialEnvelope(object tokenCredential) + { + // TODO: VERIFY TYPE USING REFLECTION + } + + public object Credential { get; private set; } + + public string GetToken() + { + throw new NotImplementedException(); + } + + public Task GetTokenAsync() + { + throw new NotImplementedException(); + } + } +} +#endif \ No newline at end of file diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs new file mode 100644 index 0000000000..9d9c932a97 --- /dev/null +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -0,0 +1,25 @@ +#if NETSTANDARD2_0 +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + using Azure.Core; + + public class TokenCredentialEnvelope : ICredentialEnvelope + { + private readonly TokenCredential tokenCredential; + + public TokenCredentialEnvelope(TokenCredential tokenCredential) => this.tokenCredential = tokenCredential; + + public object Credential => this.tokenCredential; + + public string GetToken() => null;//this.Credential.GetToken().Token; + + public async Task GetTokenAsync() => await Task.FromResult(null);//await this.Credential.GetTokenAsync().Token; + } +} +#endif \ No newline at end of file diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 6b75788ead..0f69f46190 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -11,6 +11,7 @@ using Microsoft.ApplicationInsights.DataContracts; using Microsoft.ApplicationInsights.Extensibility.Implementation; using Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints; using Microsoft.ApplicationInsights.Extensibility.Implementation.Sampling; using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; @@ -397,6 +398,20 @@ public void Dispose() GC.SuppressFinalize(this); } + public ICredentialEnvelope CredentialEnvelope { get; private set; } + +#if NETSTANDARD2_0 + public void SetCredential(Azure.Core.TokenCredential tokenCredential) + { + this.CredentialEnvelope = new TokenCredentialEnvelope(tokenCredential); + } +#else + public void SetCredential(object tokenCredential) + { + this.CredentialEnvelope = new ReflectionCredentialEnvelope(tokenCredential); + } +#endif + internal MetricManager GetMetricManager(bool createIfNotExists) { MetricManager manager = this.metricManager; diff --git a/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj b/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj index 82a3c97939..ccac63e268 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj +++ b/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj @@ -30,6 +30,10 @@ + + + + From 180c039b0533fef5dd84ad5f95cae14facb6be83 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 11 Mar 2021 16:03:22 -0800 Subject: [PATCH 02/93] more tests. currently passing --- .../CredentialEnvelopeTests.cs | 6 +- .../ReflectionCredentialEnvelopeTests.cs | 74 +++++++++++++++++++ .../ReflectionCredentialEnvelope.cs | 26 ++++++- 3 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs index c159789dd2..8e1af87ad7 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs @@ -1,10 +1,6 @@ namespace Microsoft.ApplicationInsights.Authentication.Tests { using System; - using System.Threading; - using System.Threading.Tasks; - - using Azure.Core; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; @@ -36,7 +32,7 @@ public void VerifyCanSetCredential() #if NET461 [TestMethod] - [ExpectedException(typeof(System.Exception))] + [ExpectedException(typeof(ArgumentException))] public void VerifyCannotSetInvalidType() { var telemetryConfiguration = new TelemetryConfiguration(); diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs new file mode 100644 index 0000000000..edc3492dab --- /dev/null +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs @@ -0,0 +1,74 @@ +namespace Microsoft.ApplicationInsights.Authentication.Tests +{ + using System; + using System.Threading; + using System.Threading.Tasks; + + using Azure.Core; + + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + /// + /// The cannot take a dependency on . + /// We must use reflection to interact with this class. + /// These tests are to confirm that we can correctly identity + /// + [TestClass] + public class ReflectionCredentialEnvelopeTests + { + [TestMethod] + public void VerifyCanIdentifyValidClass() + { + var testClass2 = new TestClass2(); + _ = new ReflectionCredentialEnvelope(testClass2); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentException))] + public void VerifyCanIdentityInvalidClass() + { + var notTokenCredential2 = new NotTokenCredential2(); + _ = new ReflectionCredentialEnvelope(notTokenCredential2); + } + + #region TestClasses + private class TestClass1 : Azure.Core.TokenCredential + { + public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public override ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + } + + private class TestClass2 : TestClass1 { } + + private abstract class NotTokenCredential + { + public abstract AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken); + + public abstract ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken); + } + + private class NotTokenCredential1 : NotTokenCredential + { + public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public override ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + } + + private class NotTokenCredential2 : NotTokenCredential1 { } + #endregion + } +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 51233bfe96..cf2f888352 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -1,5 +1,4 @@ -#if NET452 || NET46 -namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { using System; using System.Collections.Generic; @@ -26,7 +25,14 @@ public class ReflectionCredentialEnvelope : ICredentialEnvelope /// public ReflectionCredentialEnvelope(object tokenCredential) { - // TODO: VERIFY TYPE USING REFLECTION + if (this.IsTokenCredential(tokenCredential.GetType())) + { + this.Credential = tokenCredential; + } + else + { + throw new ArgumentException($"The provided {nameof(tokenCredential)} must inherit Azure.Core.TokenCredential", nameof(tokenCredential)); + } } public object Credential { get; private set; } @@ -40,6 +46,18 @@ public Task GetTokenAsync() { throw new NotImplementedException(); } + + private bool IsTokenCredential(Type inputType) + { + for (var evalType = inputType; evalType != null; evalType = evalType.BaseType) + { + if (evalType.FullName == "Azure.Core.TokenCredential") + { + return true; + } + } + + return false; + } } } -#endif \ No newline at end of file From d501eef099af13d64c9b794da5aebed887097ee7 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 11 Mar 2021 16:31:32 -0800 Subject: [PATCH 03/93] cleanup --- .../Authentication/ReflectionCredentialEnvelope.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index cf2f888352..1606514fea 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -1,9 +1,6 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; using System.Threading.Tasks; /// @@ -51,7 +48,8 @@ private bool IsTokenCredential(Type inputType) { for (var evalType = inputType; evalType != null; evalType = evalType.BaseType) { - if (evalType.FullName == "Azure.Core.TokenCredential") + if (evalType.FullName == "Azure.Core.TokenCredential" + && evalType.Assembly.FullName.StartsWith("Azure.Core, Version=1.")) { return true; } From 5a556d3a916cb55e604266bc50fe3bf80f7c6ef9 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Tue, 23 Mar 2021 16:59:49 -0700 Subject: [PATCH 04/93] saving work in progress --- .../CredentialEnvelopeTests.cs | 42 ++++++++++++++++++- .../ReflectionCredentialEnvelopeTests.cs | 2 +- .../Authentication/CredentialEnvelope.cs | 21 ++++++++++ .../Authentication/ICredentialEnvelope.cs | 13 ------ .../ReflectionCredentialEnvelope.cs | 13 +++--- .../Authentication/TokenCredentialEnvelope.cs | 33 ++++++++++++--- .../Extensibility/TelemetryConfiguration.cs | 2 +- 7 files changed, 99 insertions(+), 27 deletions(-) create mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs delete mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs index 8e1af87ad7..65e91d9461 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs @@ -1,6 +1,12 @@ namespace Microsoft.ApplicationInsights.Authentication.Tests { using System; + using System.Threading; + using System.Threading.Tasks; + + using Azure.Core; + using Azure.Core.Pipeline; + using Azure.Identity; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; @@ -12,7 +18,7 @@ public class CredentialEnvelopeTests [TestMethod] public void VerifyCanSetCredential() { - var defaultTokenCredential = new Azure.Identity.DefaultAzureCredential(); + var defaultTokenCredential = new MockCredential(); var telemetryConfiguration = new TelemetryConfiguration(); telemetryConfiguration.SetCredential(defaultTokenCredential); @@ -39,6 +45,38 @@ public void VerifyCannotSetInvalidType() telemetryConfiguration.SetCredential(Guid.Empty); } #endif - } +#if NET5_0 + [TestMethod] + public void VerifyCanGetTokenString() + { + var mockCredential = new MockCredential(); + + var tokenCredentialEnvelope = new TokenCredentialEnvelope(mockCredential); + var token = tokenCredentialEnvelope.GetToken(); + Assert.IsNotNull(token); + + var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); + var tokenFromReflection = reflectionCredentialEnvelope.GetToken(); + Assert.IsNotNull(tokenFromReflection); + + Assert.AreEqual(token, tokenFromReflection); + } +#endif + /// + /// Copied from (https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core.TestFramework/src/MockCredential.cs). + /// + private class MockCredential : TokenCredential + { + public override ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + return new ValueTask(GetToken(requestContext, cancellationToken)); + } + + public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + return new AccessToken("TEST TOKEN " + string.Join(" ", requestContext.Scopes), DateTimeOffset.MaxValue); + } + } + } } diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs index edc3492dab..1a114fcd26 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs @@ -12,7 +12,7 @@ /// /// The cannot take a dependency on . /// We must use reflection to interact with this class. - /// These tests are to confirm that we can correctly identity + /// These tests are to confirm that we can correctly identity classes that implement TokenCredential and address it's methods. /// [TestClass] public class ReflectionCredentialEnvelopeTests diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs new file mode 100644 index 0000000000..7b71d1d81d --- /dev/null +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -0,0 +1,21 @@ +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +{ + using System.Threading; + using System.Threading.Tasks; + + public abstract class CredentialEnvelope + { + /// + /// The default scope used for token authentication. + /// + private const string Scope = "https://storage.azure.com/.default"; // example from Blob Storage. TODO: NEED OUR OWN SCOPE + + protected string[] Scopes => new string[] { Scope }; + + public abstract object Credential { get; } + + public abstract string GetToken(); + + public abstract Task GetTokenAsync(CancellationToken cancellationToken); + } +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs deleted file mode 100644 index d948b49a29..0000000000 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication -{ - using System.Threading.Tasks; - - public interface ICredentialEnvelope - { - object Credential { get; } - - string GetToken(); - - Task GetTokenAsync(); - } -} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 1606514fea..05872d4a1c 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -1,6 +1,7 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { using System; + using System.Threading; using System.Threading.Tasks; /// @@ -11,8 +12,10 @@ /// Azure.Core.TokenCredential is only available for netstandard2.0. /// I'm introducing this class as a wrapper so we can receive an instance of this class and pass it around within our SDK. /// - public class ReflectionCredentialEnvelope : ICredentialEnvelope + public class ReflectionCredentialEnvelope : CredentialEnvelope { + private readonly object credential; + /// /// /// @@ -24,7 +27,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) { if (this.IsTokenCredential(tokenCredential.GetType())) { - this.Credential = tokenCredential; + this.credential = tokenCredential; } else { @@ -32,14 +35,14 @@ public ReflectionCredentialEnvelope(object tokenCredential) } } - public object Credential { get; private set; } + public override object Credential => this.credential; - public string GetToken() + public override string GetToken() { throw new NotImplementedException(); } - public Task GetTokenAsync() + public override Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index 9d9c932a97..e2e00a676d 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -5,21 +5,44 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authenticat using System.Collections.Generic; using System.Linq; using System.Text; + using System.Threading; using System.Threading.Tasks; using Azure.Core; - public class TokenCredentialEnvelope : ICredentialEnvelope + public class TokenCredentialEnvelope : CredentialEnvelope { private readonly TokenCredential tokenCredential; + private readonly TokenRequestContext tokenRequestContext; - public TokenCredentialEnvelope(TokenCredential tokenCredential) => this.tokenCredential = tokenCredential; + public TokenCredentialEnvelope(TokenCredential tokenCredential) + { + this.tokenCredential = tokenCredential; + this.tokenRequestContext = new TokenRequestContext(scopes: this.Scopes); + } - public object Credential => this.tokenCredential; + public override object Credential => this.tokenCredential; - public string GetToken() => null;//this.Credential.GetToken().Token; + public override string GetToken() + { + var accessToken = this.tokenCredential.GetToken(requestContext: this.tokenRequestContext, cancellationToken: CancellationToken.None); + return accessToken.Token; + } - public async Task GetTokenAsync() => await Task.FromResult(null);//await this.Credential.GetTokenAsync().Token; + /// + /// + /// + /// + /// You can also use the C# default(CancellationToken) statement to create an empty cancellation token. + /// Source: (https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.none). + /// + /// + /// + public override async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var accessToken = await this.tokenCredential.GetTokenAsync(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); + return accessToken.Token; + } } } #endif \ No newline at end of file diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 0f69f46190..292ce0d058 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -398,7 +398,7 @@ public void Dispose() GC.SuppressFinalize(this); } - public ICredentialEnvelope CredentialEnvelope { get; private set; } + public CredentialEnvelope CredentialEnvelope { get; private set; } #if NETSTANDARD2_0 public void SetCredential(Azure.Core.TokenCredential tokenCredential) From 2f7f7f8c7b6d89bebcced5a1dee79589a815d2ef Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 24 Mar 2021 14:32:03 -0700 Subject: [PATCH 05/93] cleanup --- .../CredentialEnvelopeTests.cs | 12 +++++++---- .../ReflectionCredentialEnvelopeTests.cs | 7 +++++++ .../Authentication/AuthConstants.cs | 20 ++++++++++++++++++ .../Authentication/CredentialEnvelope.cs | 21 ------------------- .../Authentication/ICredentialEnvelope.cs | 12 +++++++++++ .../ReflectionCredentialEnvelope.cs | 15 ++++--------- .../Authentication/TokenCredentialEnvelope.cs | 14 ++++--------- .../Extensibility/TelemetryConfiguration.cs | 12 +++-------- 8 files changed, 58 insertions(+), 55 deletions(-) create mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs delete mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs create mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs index 65e91d9461..84cd17e8d8 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs @@ -37,9 +37,13 @@ public void VerifyCanSetCredential() } #if NET461 + /// + /// For older frameworks, TelemetryConfiguration accepts an parameter. + /// This test is to verify that we cannot set invalid types. + /// [TestMethod] [ExpectedException(typeof(ArgumentException))] - public void VerifyCannotSetInvalidType() + public void VerifyCannotSetInvalidObjectOnTelemetryConfiguration() { var telemetryConfiguration = new TelemetryConfiguration(); telemetryConfiguration.SetCredential(Guid.Empty); @@ -48,16 +52,16 @@ public void VerifyCannotSetInvalidType() #if NET5_0 [TestMethod] - public void VerifyCanGetTokenString() + public async Task VerifyCanGetTokenString() { var mockCredential = new MockCredential(); var tokenCredentialEnvelope = new TokenCredentialEnvelope(mockCredential); - var token = tokenCredentialEnvelope.GetToken(); + var token = await tokenCredentialEnvelope.GetTokenAsync(); Assert.IsNotNull(token); var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); - var tokenFromReflection = reflectionCredentialEnvelope.GetToken(); + var tokenFromReflection = await reflectionCredentialEnvelope.GetTokenAsync(); Assert.IsNotNull(tokenFromReflection); Assert.AreEqual(token, tokenFromReflection); diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs index 1a114fcd26..4d3d3a880a 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs @@ -32,6 +32,13 @@ public void VerifyCanIdentityInvalidClass() _ = new ReflectionCredentialEnvelope(notTokenCredential2); } + [TestMethod] + [ExpectedException(typeof(ArgumentException))] + public void VerifyCannotSetInvalidType() + { + _ = new ReflectionCredentialEnvelope(Guid.Empty); + } + #region TestClasses private class TestClass1 : Azure.Core.TokenCredential { diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs new file mode 100644 index 0000000000..b50c9342d2 --- /dev/null +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs @@ -0,0 +1,20 @@ +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + internal static class AuthConstants + { + /// + /// https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens + /// + /// Other APIs might require that no scheme or host is included in the scope value, and expect only the app ID (a GUID) and the scope name, for example: 11111111-1111-1111-1111-111111111111/api.read + /// + public const string Scope = "https://storage.azure.com/.default"; // example from Blob Storage. TODO: NEED OUR OWN SCOPE + + public static string[] GetScopes() => new string[] { Scope }; + } +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs deleted file mode 100644 index 7b71d1d81d..0000000000 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication -{ - using System.Threading; - using System.Threading.Tasks; - - public abstract class CredentialEnvelope - { - /// - /// The default scope used for token authentication. - /// - private const string Scope = "https://storage.azure.com/.default"; // example from Blob Storage. TODO: NEED OUR OWN SCOPE - - protected string[] Scopes => new string[] { Scope }; - - public abstract object Credential { get; } - - public abstract string GetToken(); - - public abstract Task GetTokenAsync(CancellationToken cancellationToken); - } -} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs new file mode 100644 index 0000000000..d2f288aa54 --- /dev/null +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs @@ -0,0 +1,12 @@ +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +{ + using System.Threading; + using System.Threading.Tasks; + + public interface ICredentialEnvelope + { + object Credential { get; } + + Task GetTokenAsync(CancellationToken cancellationToken); + } +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 05872d4a1c..c7f974e035 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -12,10 +12,8 @@ /// Azure.Core.TokenCredential is only available for netstandard2.0. /// I'm introducing this class as a wrapper so we can receive an instance of this class and pass it around within our SDK. /// - public class ReflectionCredentialEnvelope : CredentialEnvelope + public class ReflectionCredentialEnvelope : ICredentialEnvelope { - private readonly object credential; - /// /// /// @@ -27,7 +25,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) { if (this.IsTokenCredential(tokenCredential.GetType())) { - this.credential = tokenCredential; + this.Credential = tokenCredential; } else { @@ -35,14 +33,9 @@ public ReflectionCredentialEnvelope(object tokenCredential) } } - public override object Credential => this.credential; - - public override string GetToken() - { - throw new NotImplementedException(); - } + public object Credential { get; private set; } - public override Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) + public Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { throw new NotImplementedException(); } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index e2e00a676d..1318dc1197 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -10,7 +10,7 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authenticat using Azure.Core; - public class TokenCredentialEnvelope : CredentialEnvelope + public class TokenCredentialEnvelope : ICredentialEnvelope { private readonly TokenCredential tokenCredential; private readonly TokenRequestContext tokenRequestContext; @@ -18,16 +18,10 @@ public class TokenCredentialEnvelope : CredentialEnvelope public TokenCredentialEnvelope(TokenCredential tokenCredential) { this.tokenCredential = tokenCredential; - this.tokenRequestContext = new TokenRequestContext(scopes: this.Scopes); + this.tokenRequestContext = new TokenRequestContext(scopes: AuthConstants.GetScopes()); } - public override object Credential => this.tokenCredential; - - public override string GetToken() - { - var accessToken = this.tokenCredential.GetToken(requestContext: this.tokenRequestContext, cancellationToken: CancellationToken.None); - return accessToken.Token; - } + public object Credential => this.tokenCredential; /// /// @@ -38,7 +32,7 @@ public override string GetToken() /// /// /// - public override async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) + public async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { var accessToken = await this.tokenCredential.GetTokenAsync(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); return accessToken.Token; diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 292ce0d058..b29d178b92 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -398,18 +398,12 @@ public void Dispose() GC.SuppressFinalize(this); } - public CredentialEnvelope CredentialEnvelope { get; private set; } + public ICredentialEnvelope CredentialEnvelope { get; private set; } #if NETSTANDARD2_0 - public void SetCredential(Azure.Core.TokenCredential tokenCredential) - { - this.CredentialEnvelope = new TokenCredentialEnvelope(tokenCredential); - } + public void SetCredential(Azure.Core.TokenCredential tokenCredential) => this.CredentialEnvelope = new TokenCredentialEnvelope(tokenCredential); #else - public void SetCredential(object tokenCredential) - { - this.CredentialEnvelope = new ReflectionCredentialEnvelope(tokenCredential); - } + public void SetCredential(object tokenCredential) => this.CredentialEnvelope = new ReflectionCredentialEnvelope(tokenCredential); #endif internal MetricManager GetMetricManager(bool createIfNotExists) From 9beac17a530343c34c72492840da71852b16d01e Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 24 Mar 2021 14:37:39 -0700 Subject: [PATCH 06/93] cleanup --- .../Microsoft.ApplicationInsights.Authentication.Tests.csproj | 1 + .../Authentication/ReflectionCredentialEnvelope.cs | 2 +- .../Implementation/Authentication/TokenCredentialEnvelope.cs | 2 +- .../Microsoft.ApplicationInsights/Properties/AssemblyInfo.cs | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj index acfe90d218..b2185d88de 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj @@ -1,4 +1,5 @@ + net461;net5.0 diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index c7f974e035..2e1857e534 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -12,7 +12,7 @@ /// Azure.Core.TokenCredential is only available for netstandard2.0. /// I'm introducing this class as a wrapper so we can receive an instance of this class and pass it around within our SDK. /// - public class ReflectionCredentialEnvelope : ICredentialEnvelope + internal class ReflectionCredentialEnvelope : ICredentialEnvelope { /// /// diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index 1318dc1197..10b031e5a6 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -10,7 +10,7 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authenticat using Azure.Core; - public class TokenCredentialEnvelope : ICredentialEnvelope + internal class TokenCredentialEnvelope : ICredentialEnvelope { private readonly TokenCredential tokenCredential; private readonly TokenRequestContext tokenRequestContext; diff --git a/BASE/src/Microsoft.ApplicationInsights/Properties/AssemblyInfo.cs b/BASE/src/Microsoft.ApplicationInsights/Properties/AssemblyInfo.cs index ede21ce5ee..e7f57053e2 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Properties/AssemblyInfo.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Properties/AssemblyInfo.cs @@ -5,6 +5,7 @@ [assembly: ComVisible(false)] [assembly: InternalsVisibleTo("Microsoft.ApplicationInsights.Tests, PublicKey=" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("Microsoft.ApplicationInsights.Authentication.Tests, PublicKey=" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("Microsoft.ApplicationInsights.TelemetryChannel.Tests, PublicKey=" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("Microsoft.ApplicationInsights.AspNetCore.Tests, PublicKey=" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("Microsoft.ApplicationInsights.WorkerService.Tests, PublicKey=" + AssemblyInfo.PublicKey)] From 14b65b2653a378ddd610f54fb2407456b15c24af Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 24 Mar 2021 14:38:45 -0700 Subject: [PATCH 07/93] cleanup --- .../Microsoft.ApplicationInsights.Authentication.Tests.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj index b2185d88de..97eff3e356 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj @@ -17,9 +17,6 @@ - - - From 844607515576fbd241d623c5918b09ab1db437cd Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 24 Mar 2021 16:46:30 -0700 Subject: [PATCH 08/93] save work in progress. all tests passing --- .../ReflectionCredentialEnvelope.cs | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 2e1857e534..0754ac2bdd 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -1,6 +1,7 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { using System; + using System.Reflection; using System.Threading; using System.Threading.Tasks; @@ -14,6 +15,11 @@ /// internal class ReflectionCredentialEnvelope : ICredentialEnvelope { + private readonly object tokenRequestContext; + private readonly MethodInfo getTokenAsyncMethod; + private readonly MethodInfo getTokenMethod; + private readonly Type accessTokenType; + /// /// /// @@ -26,6 +32,20 @@ public ReflectionCredentialEnvelope(object tokenCredential) if (this.IsTokenCredential(tokenCredential.GetType())) { this.Credential = tokenCredential; + + // (https://docs.microsoft.com/en-us/dotnet/api/azure.core.tokenrequestcontext.-ctor?view=azure-dotnet). + // Invoking this constructor: Azure.Core.TokenRequestContext(String[], String, String). + var tokenRequestContextType = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + var paramArray = new object[] { AuthConstants.GetScopes(), null, null }; + this.tokenRequestContext = Activator.CreateInstance(tokenRequestContextType, args: paramArray); + + // (https://docs.microsoft.com/en-us/dotnet/api/azure.core.tokencredential.gettokenasync?view=azure-dotnet). + // Getting a handle for this method: Azure.Core.TokenCredential.GetTokenAsync(). + this.getTokenAsyncMethod = this.Credential.GetType().GetMethod("GetTokenAsync"); + this.getTokenMethod = this.Credential.GetType().GetMethod("GetToken"); + + // xxx + var accessTokenType = Type.GetType("Azure.Core.AccessToken, Azure.Core"); } else { @@ -35,23 +55,30 @@ public ReflectionCredentialEnvelope(object tokenCredential) public object Credential { get; private set; } - public Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) + public string GetToken(CancellationToken cancellationToken = default(CancellationToken)) { - throw new NotImplementedException(); + var accessToken = this.getTokenMethod.Invoke(this.Credential, new object[] { this.tokenRequestContext, cancellationToken }); + var tokenProperty = accessToken.GetType().GetProperty("Token"); + return (string)tokenProperty.GetValue(accessToken); } - private bool IsTokenCredential(Type inputType) + public async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { - for (var evalType = inputType; evalType != null; evalType = evalType.BaseType) - { - if (evalType.FullName == "Azure.Core.TokenCredential" - && evalType.Assembly.FullName.StartsWith("Azure.Core, Version=1.")) - { - return true; - } - } + return await Task.Run(() => this.GetToken(cancellationToken)); - return false; + // (https://stackoverflow.com/questions/39674988/how-to-call-a-generic-async-method-using-reflection/39679855). + // 'Unable to cast object of type 'System.Threading.Tasks.ValueTask`1[Azure.Core.AccessToken]' to type 'System.Threading.Tasks.Task'.' + //var task = (Task)this.getTokenAsyncMethod.Invoke(this.Credential, new object[] { this.tokenRequestContext, cancellationToken }); + //await task.ConfigureAwait(false); + //var resultProperty = task.GetType().GetProperty("Result"); + //var accessToken = resultProperty.GetValue(task); + //var tokenProperty = accessToken.GetType().GetProperty("Token"); + //return (string)tokenProperty.GetValue(accessToken); } + + /// + /// Checks if the input inherits + /// + private bool IsTokenCredential(Type inputType) => inputType.IsSubclassOf(Type.GetType("Azure.Core.TokenCredential, Azure.Core")); } } From 0fe4b8ce661e2691e23efbc84e82be6df500b422 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 24 Mar 2021 16:55:54 -0700 Subject: [PATCH 09/93] cleanup --- .../CredentialEnvelopeTests.cs | 18 +++++++++++++++++- .../Authentication/ICredentialEnvelope.cs | 2 ++ .../ReflectionCredentialEnvelope.cs | 8 ++++---- .../Authentication/TokenCredentialEnvelope.cs | 6 ++++++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs index 84cd17e8d8..aa26319095 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs @@ -52,7 +52,23 @@ public void VerifyCannotSetInvalidObjectOnTelemetryConfiguration() #if NET5_0 [TestMethod] - public async Task VerifyCanGetTokenString() + public void VerifyCanGetTokenString() + { + var mockCredential = new MockCredential(); + + var tokenCredentialEnvelope = new TokenCredentialEnvelope(mockCredential); + var token = tokenCredentialEnvelope.GetToken(); + Assert.IsNotNull(token); + + var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); + var tokenFromReflection = reflectionCredentialEnvelope.GetToken(); + Assert.IsNotNull(tokenFromReflection); + + Assert.AreEqual(token, tokenFromReflection); + } + + [TestMethod] + public async Task VerifyCanGetTokenStringAsync() { var mockCredential = new MockCredential(); diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs index d2f288aa54..facb72d966 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs @@ -7,6 +7,8 @@ public interface ICredentialEnvelope { object Credential { get; } + string GetToken(CancellationToken cancellationToken); + Task GetTokenAsync(CancellationToken cancellationToken); } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 0754ac2bdd..f77f7ddd73 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -18,7 +18,7 @@ internal class ReflectionCredentialEnvelope : ICredentialEnvelope private readonly object tokenRequestContext; private readonly MethodInfo getTokenAsyncMethod; private readonly MethodInfo getTokenMethod; - private readonly Type accessTokenType; + //private readonly Type accessTokenType; /// /// @@ -44,8 +44,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) this.getTokenAsyncMethod = this.Credential.GetType().GetMethod("GetTokenAsync"); this.getTokenMethod = this.Credential.GetType().GetMethod("GetToken"); - // xxx - var accessTokenType = Type.GetType("Azure.Core.AccessToken, Azure.Core"); + // this.accessTokenType = Type.GetType("Azure.Core.AccessToken, Azure.Core"); } else { @@ -66,8 +65,9 @@ public ReflectionCredentialEnvelope(object tokenCredential) { return await Task.Run(() => this.GetToken(cancellationToken)); - // (https://stackoverflow.com/questions/39674988/how-to-call-a-generic-async-method-using-reflection/39679855). + // TODO: THIS DOESN'T WORK. CAN CIRCLE BACK AND INVESTIGATE THIS LATER. // 'Unable to cast object of type 'System.Threading.Tasks.ValueTask`1[Azure.Core.AccessToken]' to type 'System.Threading.Tasks.Task'.' + // (https://stackoverflow.com/questions/39674988/how-to-call-a-generic-async-method-using-reflection/39679855). //var task = (Task)this.getTokenAsyncMethod.Invoke(this.Credential, new object[] { this.tokenRequestContext, cancellationToken }); //await task.ConfigureAwait(false); //var resultProperty = task.GetType().GetProperty("Result"); diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index 10b031e5a6..f24d6ccc0f 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -23,6 +23,12 @@ public TokenCredentialEnvelope(TokenCredential tokenCredential) public object Credential => this.tokenCredential; + public string GetToken(CancellationToken cancellationToken = default(CancellationToken)) + { + var accessToken = this.tokenCredential.GetToken(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); + return accessToken.Token; + } + /// /// /// From 52785bb62284bba89c7766447d1e3f87e456d9f8 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 25 Mar 2021 13:54:03 -0700 Subject: [PATCH 10/93] change interface to abstract class. change reflection to use a compiled expression. --- .../Authentication/ICredentialEnvelope.cs | 9 +-- .../ReflectionCredentialEnvelope.cs | 70 +++++++++++++++---- .../Authentication/TokenCredentialEnvelope.cs | 10 +-- .../Extensibility/TelemetryConfiguration.cs | 2 +- 4 files changed, 68 insertions(+), 23 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs index facb72d966..07b1fca28d 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs @@ -1,14 +1,15 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { + using System; using System.Threading; using System.Threading.Tasks; - public interface ICredentialEnvelope + public abstract class CredentialEnvelope { - object Credential { get; } + public abstract object Credential { get;} - string GetToken(CancellationToken cancellationToken); + public abstract string GetToken(CancellationToken cancellationToken); - Task GetTokenAsync(CancellationToken cancellationToken); + public abstract Task GetTokenAsync(CancellationToken cancellationToken); } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index f77f7ddd73..627e09d71d 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -1,6 +1,7 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { using System; + using System.Linq.Expressions; using System.Reflection; using System.Threading; using System.Threading.Tasks; @@ -13,8 +14,9 @@ /// Azure.Core.TokenCredential is only available for netstandard2.0. /// I'm introducing this class as a wrapper so we can receive an instance of this class and pass it around within our SDK. /// - internal class ReflectionCredentialEnvelope : ICredentialEnvelope + internal class ReflectionCredentialEnvelope : CredentialEnvelope { + private readonly object tokenCredential; private readonly object tokenRequestContext; private readonly MethodInfo getTokenAsyncMethod; private readonly MethodInfo getTokenMethod; @@ -29,10 +31,10 @@ internal class ReflectionCredentialEnvelope : ICredentialEnvelope /// public ReflectionCredentialEnvelope(object tokenCredential) { - if (this.IsTokenCredential(tokenCredential.GetType())) - { - this.Credential = tokenCredential; + this.tokenCredential = tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential)); + if (tokenCredential.GetType().IsSubclassOf(Type.GetType("Azure.Core.TokenCredential, Azure.Core"))) + { // (https://docs.microsoft.com/en-us/dotnet/api/azure.core.tokenrequestcontext.-ctor?view=azure-dotnet). // Invoking this constructor: Azure.Core.TokenRequestContext(String[], String, String). var tokenRequestContextType = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); @@ -52,16 +54,63 @@ public ReflectionCredentialEnvelope(object tokenCredential) } } - public object Credential { get; private set; } + public override object Credential => this.tokenCredential; - public string GetToken(CancellationToken cancellationToken = default(CancellationToken)) + /// + /// + /// + /// + /// This is a wrapper for the following method: + /// public abstract Azure.Core.AccessToken GetToken (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);. + /// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettoken). + /// + /// + /// + public override string GetToken(CancellationToken cancellationToken = default(CancellationToken)) { - var accessToken = this.getTokenMethod.Invoke(this.Credential, new object[] { this.tokenRequestContext, cancellationToken }); + var tokenCredentialType = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); + var tokenRequestContextType = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + var accessTokenType = Type.GetType("Azure.Core.AccessToken, Azure.Core"); + + var parameterExpression_requestContext = Expression.Parameter(type: tokenRequestContextType, name: "parameterExpression_requestContext"); + var parameterExpression_cancellationToken = Expression.Parameter(type: typeof(CancellationToken), name: "parameterExpression_cancellationToken"); + + Expression callExpr = Expression.Call( + instance: Expression.New(this.Credential.GetType()), + method: tokenCredentialType.GetMethod(name: "GetToken", types: new Type[] { tokenRequestContextType, typeof(CancellationToken) }), + arg0: parameterExpression_requestContext, + arg1: parameterExpression_cancellationToken + ); + + var lambdaTest = Expression.Lambda( + body: callExpr, + new ParameterExpression[] + { + parameterExpression_requestContext, + parameterExpression_cancellationToken + }); + + var compileTest = lambdaTest.Compile(); // TODO: THIS NEEDS TO BE STORED AS A PRIVATE FIELD SO IT CAN BE REUSED. + + var accessToken = compileTest.DynamicInvoke(this.tokenRequestContext, cancellationToken); var tokenProperty = accessToken.GetType().GetProperty("Token"); return (string)tokenProperty.GetValue(accessToken); + + + // REILEY'S EXAMPLE + //var flags = BindingFlags.Instance | BindingFlags.NonPublic; + //var ctor = typeof(Batch).GetConstructor(flags, null, new Type[] { typeof(T) }, null); + //var value = Expression.Parameter(typeof(T), null); + //var lambda = Expression.Lambda>>(Expression.New(ctor, value), value); + //CreateBatch = lambda.Compile(); + + // THIS WORKS + //var accessToken = this.getTokenMethod.Invoke(this.Credential, new object[] { this.tokenRequestContext, cancellationToken }); + //var tokenProperty = accessToken.GetType().GetProperty("Token"); + //return (string)tokenProperty.GetValue(accessToken); } - public async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) + public override async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { return await Task.Run(() => this.GetToken(cancellationToken)); @@ -75,10 +124,5 @@ public ReflectionCredentialEnvelope(object tokenCredential) //var tokenProperty = accessToken.GetType().GetProperty("Token"); //return (string)tokenProperty.GetValue(accessToken); } - - /// - /// Checks if the input inherits - /// - private bool IsTokenCredential(Type inputType) => inputType.IsSubclassOf(Type.GetType("Azure.Core.TokenCredential, Azure.Core")); } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index f24d6ccc0f..2841b46040 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -10,20 +10,20 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authenticat using Azure.Core; - internal class TokenCredentialEnvelope : ICredentialEnvelope + internal class TokenCredentialEnvelope : CredentialEnvelope { private readonly TokenCredential tokenCredential; private readonly TokenRequestContext tokenRequestContext; public TokenCredentialEnvelope(TokenCredential tokenCredential) { - this.tokenCredential = tokenCredential; + this.tokenCredential = tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential)); this.tokenRequestContext = new TokenRequestContext(scopes: AuthConstants.GetScopes()); } - public object Credential => this.tokenCredential; + public override object Credential => this.tokenCredential; - public string GetToken(CancellationToken cancellationToken = default(CancellationToken)) + public override string GetToken(CancellationToken cancellationToken = default(CancellationToken)) { var accessToken = this.tokenCredential.GetToken(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); return accessToken.Token; @@ -38,7 +38,7 @@ public TokenCredentialEnvelope(TokenCredential tokenCredential) /// /// /// - public async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) + public override async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { var accessToken = await this.tokenCredential.GetTokenAsync(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); return accessToken.Token; diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index b29d178b92..8dfa84c344 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -398,7 +398,7 @@ public void Dispose() GC.SuppressFinalize(this); } - public ICredentialEnvelope CredentialEnvelope { get; private set; } + public CredentialEnvelope CredentialEnvelope { get; private set; } #if NETSTANDARD2_0 public void SetCredential(Azure.Core.TokenCredential tokenCredential) => this.CredentialEnvelope = new TokenCredentialEnvelope(tokenCredential); From acb3fd01d2ccc98c9e75988e13b10b338db8d7a0 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 25 Mar 2021 14:09:35 -0700 Subject: [PATCH 11/93] cleanup --- .../ReflectionCredentialEnvelope.cs | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 627e09d71d..34954adc7a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -91,23 +91,10 @@ public ReflectionCredentialEnvelope(object tokenCredential) }); var compileTest = lambdaTest.Compile(); // TODO: THIS NEEDS TO BE STORED AS A PRIVATE FIELD SO IT CAN BE REUSED. - var accessToken = compileTest.DynamicInvoke(this.tokenRequestContext, cancellationToken); - var tokenProperty = accessToken.GetType().GetProperty("Token"); - return (string)tokenProperty.GetValue(accessToken); - - - // REILEY'S EXAMPLE - //var flags = BindingFlags.Instance | BindingFlags.NonPublic; - //var ctor = typeof(Batch).GetConstructor(flags, null, new Type[] { typeof(T) }, null); - //var value = Expression.Parameter(typeof(T), null); - //var lambda = Expression.Lambda>>(Expression.New(ctor, value), value); - //CreateBatch = lambda.Compile(); - // THIS WORKS - //var accessToken = this.getTokenMethod.Invoke(this.Credential, new object[] { this.tokenRequestContext, cancellationToken }); - //var tokenProperty = accessToken.GetType().GetProperty("Token"); - //return (string)tokenProperty.GetValue(accessToken); + var tokenProperty = accessTokenType.GetProperty("Token"); + return (string)tokenProperty.GetValue(accessToken); } public override async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) From 66592c997ad229510ad8d1d404386e6c5357ae59 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 25 Mar 2021 16:18:02 -0700 Subject: [PATCH 12/93] working reflection for GetTokenAsync --- ...AuthConstants.cs => CredentialEnvelope.cs} | 16 +++--- .../Authentication/ICredentialEnvelope.cs | 15 ------ .../ReflectionCredentialEnvelope.cs | 53 ++++++++++++++----- .../Authentication/TokenCredentialEnvelope.cs | 2 +- 4 files changed, 50 insertions(+), 36 deletions(-) rename BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/{AuthConstants.cs => CredentialEnvelope.cs} (52%) delete mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs similarity index 52% rename from BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs rename to BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index b50c9342d2..3c3123f38f 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -1,20 +1,24 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; + using System.Threading; using System.Threading.Tasks; - internal static class AuthConstants + public abstract class CredentialEnvelope { /// /// https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens /// /// Other APIs might require that no scheme or host is included in the scope value, and expect only the app ID (a GUID) and the scope name, for example: 11111111-1111-1111-1111-111111111111/api.read /// - public const string Scope = "https://storage.azure.com/.default"; // example from Blob Storage. TODO: NEED OUR OWN SCOPE + private const string Scope = "https://storage.azure.com/.default"; // example from Blob Storage. TODO: NEED OUR OWN SCOPE - public static string[] GetScopes() => new string[] { Scope }; + protected static string[] GetScopes() => new string[] { Scope }; + + public abstract object Credential { get;} + + public abstract string GetToken(CancellationToken cancellationToken); + + public abstract Task GetTokenAsync(CancellationToken cancellationToken); } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs deleted file mode 100644 index 07b1fca28d..0000000000 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication -{ - using System; - using System.Threading; - using System.Threading.Tasks; - - public abstract class CredentialEnvelope - { - public abstract object Credential { get;} - - public abstract string GetToken(CancellationToken cancellationToken); - - public abstract Task GetTokenAsync(CancellationToken cancellationToken); - } -} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 34954adc7a..50ac2bf7a9 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -16,6 +16,9 @@ /// internal class ReflectionCredentialEnvelope : CredentialEnvelope { + private readonly Type tokenCredentialType = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); + private readonly Type tokenRequestContextType = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + private readonly object tokenCredential; private readonly object tokenRequestContext; private readonly MethodInfo getTokenAsyncMethod; @@ -33,12 +36,11 @@ public ReflectionCredentialEnvelope(object tokenCredential) { this.tokenCredential = tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential)); - if (tokenCredential.GetType().IsSubclassOf(Type.GetType("Azure.Core.TokenCredential, Azure.Core"))) + if (tokenCredential.GetType().IsSubclassOf(tokenCredentialType)) { // (https://docs.microsoft.com/en-us/dotnet/api/azure.core.tokenrequestcontext.-ctor?view=azure-dotnet). // Invoking this constructor: Azure.Core.TokenRequestContext(String[], String, String). - var tokenRequestContextType = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); - var paramArray = new object[] { AuthConstants.GetScopes(), null, null }; + var paramArray = new object[] { GetScopes(), null, null }; this.tokenRequestContext = Activator.CreateInstance(tokenRequestContextType, args: paramArray); // (https://docs.microsoft.com/en-us/dotnet/api/azure.core.tokencredential.gettokenasync?view=azure-dotnet). @@ -99,17 +101,40 @@ public ReflectionCredentialEnvelope(object tokenCredential) public override async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { - return await Task.Run(() => this.GetToken(cancellationToken)); - - // TODO: THIS DOESN'T WORK. CAN CIRCLE BACK AND INVESTIGATE THIS LATER. - // 'Unable to cast object of type 'System.Threading.Tasks.ValueTask`1[Azure.Core.AccessToken]' to type 'System.Threading.Tasks.Task'.' - // (https://stackoverflow.com/questions/39674988/how-to-call-a-generic-async-method-using-reflection/39679855). - //var task = (Task)this.getTokenAsyncMethod.Invoke(this.Credential, new object[] { this.tokenRequestContext, cancellationToken }); - //await task.ConfigureAwait(false); - //var resultProperty = task.GetType().GetProperty("Result"); - //var accessToken = resultProperty.GetValue(task); - //var tokenProperty = accessToken.GetType().GetProperty("Token"); - //return (string)tokenProperty.GetValue(accessToken); + var tokenCredentialType = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); + var tokenRequestContextType = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + var accessTokenType = Type.GetType("Azure.Core.AccessToken, Azure.Core"); + + var parameterExpression_requestContext = Expression.Parameter(type: tokenRequestContextType, name: "parameterExpression_requestContext"); + var parameterExpression_cancellationToken = Expression.Parameter(type: typeof(CancellationToken), name: "parameterExpression_cancellationToken"); + + Expression callExpr = Expression.Call( + instance: Expression.New(this.Credential.GetType()), + method: tokenCredentialType.GetMethod(name: "GetTokenAsync", types: new Type[] { tokenRequestContextType, typeof(CancellationToken) }), + arg0: parameterExpression_requestContext, + arg1: parameterExpression_cancellationToken + ); + + var lambdaTest = Expression.Lambda( + body: callExpr, + new ParameterExpression[] + { + parameterExpression_requestContext, + parameterExpression_cancellationToken + }); + + var compileTest = lambdaTest.Compile(); // TODO: THIS NEEDS TO BE STORED AS A PRIVATE FIELD SO IT CAN BE REUSED. + var valueTaskAccessToken = compileTest.DynamicInvoke(this.tokenRequestContext, cancellationToken); + + var asTaskMethod = valueTaskAccessToken.GetType().GetMethod("AsTask"); + + var task = (Task)asTaskMethod.Invoke(valueTaskAccessToken, null); + await task.ConfigureAwait(false); + var resultProperty = task.GetType().GetProperty("Result"); + var accessToken = resultProperty.GetValue(task); + + var tokenProperty = accessTokenType.GetProperty("Token"); + return (string)tokenProperty.GetValue(accessToken); } } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index 2841b46040..aee7f03684 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -18,7 +18,7 @@ internal class TokenCredentialEnvelope : CredentialEnvelope public TokenCredentialEnvelope(TokenCredential tokenCredential) { this.tokenCredential = tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential)); - this.tokenRequestContext = new TokenRequestContext(scopes: AuthConstants.GetScopes()); + this.tokenRequestContext = new TokenRequestContext(scopes: GetScopes()); } public override object Credential => this.tokenCredential; From 33570eceb20b487dffb7eaa9386ef42a1533274f Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 25 Mar 2021 16:35:37 -0700 Subject: [PATCH 13/93] cleanup. tests pass --- .../ReflectionCredentialEnvelope.cs | 19 ++++--------------- .../Authentication/TokenCredentialEnvelope.cs | 2 +- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 50ac2bf7a9..be846268a5 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -21,16 +21,12 @@ internal class ReflectionCredentialEnvelope : CredentialEnvelope private readonly object tokenCredential; private readonly object tokenRequestContext; - private readonly MethodInfo getTokenAsyncMethod; - private readonly MethodInfo getTokenMethod; - //private readonly Type accessTokenType; + //private readonly MethodInfo getTokenAsyncMethod; + //private readonly MethodInfo getTokenMethod; /// /// /// - /// - /// Must use reflection to verify that this object is an instance of Azure.Core.TokenCredential. - /// /// public ReflectionCredentialEnvelope(object tokenCredential) { @@ -42,13 +38,6 @@ public ReflectionCredentialEnvelope(object tokenCredential) // Invoking this constructor: Azure.Core.TokenRequestContext(String[], String, String). var paramArray = new object[] { GetScopes(), null, null }; this.tokenRequestContext = Activator.CreateInstance(tokenRequestContextType, args: paramArray); - - // (https://docs.microsoft.com/en-us/dotnet/api/azure.core.tokencredential.gettokenasync?view=azure-dotnet). - // Getting a handle for this method: Azure.Core.TokenCredential.GetTokenAsync(). - this.getTokenAsyncMethod = this.Credential.GetType().GetMethod("GetTokenAsync"); - this.getTokenMethod = this.Credential.GetType().GetMethod("GetToken"); - - // this.accessTokenType = Type.GetType("Azure.Core.AccessToken, Azure.Core"); } else { @@ -86,7 +75,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) var lambdaTest = Expression.Lambda( body: callExpr, - new ParameterExpression[] + parameters: new ParameterExpression[] { parameterExpression_requestContext, parameterExpression_cancellationToken @@ -117,7 +106,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) var lambdaTest = Expression.Lambda( body: callExpr, - new ParameterExpression[] + parameters: new ParameterExpression[] { parameterExpression_requestContext, parameterExpression_cancellationToken diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index aee7f03684..6320272b9a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -45,4 +45,4 @@ public TokenCredentialEnvelope(TokenCredential tokenCredential) } } } -#endif \ No newline at end of file +#endif From f181df55debb34dcade967ec1ad4af594ebc02a6 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 26 Mar 2021 14:32:25 -0700 Subject: [PATCH 14/93] cleanup --- .../ReflectionCredentialEnvelope.cs | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index be846268a5..f2db8706f7 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -18,11 +18,10 @@ internal class ReflectionCredentialEnvelope : CredentialEnvelope { private readonly Type tokenCredentialType = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); private readonly Type tokenRequestContextType = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + private readonly Type accessTokenType = Type.GetType("Azure.Core.AccessToken, Azure.Core"); private readonly object tokenCredential; private readonly object tokenRequestContext; - //private readonly MethodInfo getTokenAsyncMethod; - //private readonly MethodInfo getTokenMethod; /// /// @@ -34,10 +33,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) if (tokenCredential.GetType().IsSubclassOf(tokenCredentialType)) { - // (https://docs.microsoft.com/en-us/dotnet/api/azure.core.tokenrequestcontext.-ctor?view=azure-dotnet). - // Invoking this constructor: Azure.Core.TokenRequestContext(String[], String, String). - var paramArray = new object[] { GetScopes(), null, null }; - this.tokenRequestContext = Activator.CreateInstance(tokenRequestContextType, args: paramArray); + this.tokenRequestContext = GetTokenRequestContext(); } else { @@ -48,13 +44,20 @@ public ReflectionCredentialEnvelope(object tokenCredential) public override object Credential => this.tokenCredential; /// - /// + /// This is a wrapper for the following constructor: + /// public TokenRequestContext (string[] scopes, string? parentRequestId = default, string? claims = default); + /// (https://docs.microsoft.com/dotnet/api/azure.core.tokenrequestcontext.-ctor). /// - /// + private object GetTokenRequestContext() + { + return Activator.CreateInstance(tokenRequestContextType, args: new object[] { GetScopes(), null, null }); + } + + /// /// This is a wrapper for the following method: - /// public abstract Azure.Core.AccessToken GetToken (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken);. + /// public abstract Azure.Core.AccessToken GetToken (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); /// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettoken). - /// + /// /// /// public override string GetToken(CancellationToken cancellationToken = default(CancellationToken)) @@ -88,6 +91,13 @@ public ReflectionCredentialEnvelope(object tokenCredential) return (string)tokenProperty.GetValue(accessToken); } + /// + /// This is a wrapper for the following method: + /// public abstract System.Threading.Tasks.ValueTask<Azure.Core.AccessToken> GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); + /// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettokenasync). + /// + /// + /// public override async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { var tokenCredentialType = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); From 7b3040700ed195c7c09860fb010b138af62e7b9c Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 26 Mar 2021 17:14:44 -0700 Subject: [PATCH 15/93] rewriting reflection to fully use Expression.Lambda. tests partially passing. --- .../CredentialEnvelopeTests.cs | 22 ++----- .../MockCredential.cs | 25 ++++++++ .../ReflectionCredentialEnvelopeTests.cs | 27 +++++++++ .../ReflectionCredentialEnvelope.cs | 60 ++++++++++++------- 4 files changed, 96 insertions(+), 38 deletions(-) create mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/MockCredential.cs diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs index aa26319095..239b85e680 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs @@ -1,6 +1,7 @@ namespace Microsoft.ApplicationInsights.Authentication.Tests { using System; + using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; @@ -18,10 +19,10 @@ public class CredentialEnvelopeTests [TestMethod] public void VerifyCanSetCredential() { - var defaultTokenCredential = new MockCredential(); + var mockCredential = new MockCredential(); var telemetryConfiguration = new TelemetryConfiguration(); - telemetryConfiguration.SetCredential(defaultTokenCredential); + telemetryConfiguration.SetCredential(mockCredential); var credentialEnvelope = telemetryConfiguration.CredentialEnvelope; @@ -33,7 +34,7 @@ public void VerifyCanSetCredential() throw new System.Exception("this is a testing gap."); #endif - Assert.AreEqual(defaultTokenCredential, telemetryConfiguration.CredentialEnvelope.Credential); + Assert.AreEqual(mockCredential, telemetryConfiguration.CredentialEnvelope.Credential); } #if NET461 @@ -83,20 +84,5 @@ public async Task VerifyCanGetTokenStringAsync() Assert.AreEqual(token, tokenFromReflection); } #endif - /// - /// Copied from (https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core.TestFramework/src/MockCredential.cs). - /// - private class MockCredential : TokenCredential - { - public override ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) - { - return new ValueTask(GetToken(requestContext, cancellationToken)); - } - - public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) - { - return new AccessToken("TEST TOKEN " + string.Join(" ", requestContext.Scopes), DateTimeOffset.MaxValue); - } - } } } diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/MockCredential.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/MockCredential.cs new file mode 100644 index 0000000000..cc757ca853 --- /dev/null +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/MockCredential.cs @@ -0,0 +1,25 @@ +namespace Microsoft.ApplicationInsights.Authentication.Tests +{ + using System; + using System.Threading; + using System.Threading.Tasks; + + using Azure.Core; + + + /// + /// Copied from (https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core.TestFramework/src/MockCredential.cs). + /// + public class MockCredential : TokenCredential + { + public override ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + return new ValueTask(GetToken(requestContext, cancellationToken)); + } + + public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + return new AccessToken("TEST TOKEN " + string.Join(" ", requestContext.Scopes), DateTimeOffset.MaxValue); + } + } +} diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs index 4d3d3a880a..7a3cca9f80 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs @@ -39,6 +39,33 @@ public void VerifyCannotSetInvalidType() _ = new ReflectionCredentialEnvelope(Guid.Empty); } + [TestMethod] + public void VerifyGetTokenAsExpression_UsingCompileTimeTypes() + { + var mockCredential = new MockCredential(); + var requestContext = new TokenRequestContext(new string[] { "test/scope" }); + + var expression = ReflectionCredentialEnvelope.GetTokenAsExpression(mockCredential, requestContext).Compile(); + + var testResult = expression(mockCredential, requestContext, CancellationToken.None); + Assert.AreEqual("TEST TOKEN test/scope", testResult); + } + + /// + /// This more closely represents how this would be used in a production environment. + /// + [TestMethod] + public void VerifyGetTokenAsExpression_UsingDynamicTypes() + { + var mockCredential = (object)new MockCredential(); + var requestContext = ReflectionCredentialEnvelope.GetTokenRequestContext(new[] { "test/scope" }); + + var expression = ReflectionCredentialEnvelope.GetTokenAsExpression(mockCredential, requestContext).Compile(); + + var testResult = expression(mockCredential, requestContext, CancellationToken.None); + Assert.AreEqual("TEST TOKEN test/scope", testResult); + } + #region TestClasses private class TestClass1 : Azure.Core.TokenCredential { diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index f2db8706f7..ea9cf3882b 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -33,7 +33,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) if (tokenCredential.GetType().IsSubclassOf(tokenCredentialType)) { - this.tokenRequestContext = GetTokenRequestContext(); + this.tokenRequestContext = GetTokenRequestContext(scopes: GetScopes()); } else { @@ -48,9 +48,18 @@ public ReflectionCredentialEnvelope(object tokenCredential) /// public TokenRequestContext (string[] scopes, string? parentRequestId = default, string? claims = default); /// (https://docs.microsoft.com/dotnet/api/azure.core.tokenrequestcontext.-ctor). /// - private object GetTokenRequestContext() + internal static object GetTokenRequestContext(string[] scopes) { - return Activator.CreateInstance(tokenRequestContextType, args: new object[] { GetScopes(), null, null }); + return Activator.CreateInstance( + type: Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"), + args: new object[] { scopes, null, null }); + } + + public override string GetToken(CancellationToken cancellationToken = default(CancellationToken)) + { + var expression = GetTokenAsExpression(this.tokenCredential, this.tokenRequestContext); + var func = expression.Compile(); // TODO: THIS NEEDS TO BE STORED AS A PRIVATE FIELD SO IT CAN BE REUSED. + return func(this.tokenCredential, this.tokenRequestContext, cancellationToken); } /// @@ -58,37 +67,47 @@ private object GetTokenRequestContext() /// public abstract Azure.Core.AccessToken GetToken (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); /// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettoken). /// - /// + /// + /// + /// + /// /// - public override string GetToken(CancellationToken cancellationToken = default(CancellationToken)) + internal static Expression> GetTokenAsExpression(T1 T_TokenCredential, T2 T_TokenRequestContext) { - var tokenCredentialType = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); - var tokenRequestContextType = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); - var accessTokenType = Type.GetType("Azure.Core.AccessToken, Azure.Core"); + if (!T_TokenCredential.GetType().IsSubclassOf(Type.GetType("Azure.Core.TokenCredential, Azure.Core"))) + { + throw new ArgumentException("Must be an instance of Azure.Core.TokenCredential", nameof(T_TokenCredential)); + } - var parameterExpression_requestContext = Expression.Parameter(type: tokenRequestContextType, name: "parameterExpression_requestContext"); + if (!T_TokenRequestContext.GetType().IsEquivalentTo(Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"))) + { + throw new ArgumentException("Must be an instance of Azure.Core.TokenRequestContext", nameof(T_TokenRequestContext)); + } + + var parameterExpression_tokenCredential = Expression.Parameter(type: T_TokenCredential.GetType(), name: "parameterExpression_tokenCredential"); + var parameterExpression_requestContext = Expression.Parameter(type: T_TokenRequestContext.GetType(), name: "parameterExpression_requestContext"); var parameterExpression_cancellationToken = Expression.Parameter(type: typeof(CancellationToken), name: "parameterExpression_cancellationToken"); - Expression callExpr = Expression.Call( - instance: Expression.New(this.Credential.GetType()), - method: tokenCredentialType.GetMethod(name: "GetToken", types: new Type[] { tokenRequestContextType, typeof(CancellationToken) }), + var getTokenExpression = Expression.Call( + instance: Expression.New(T_TokenCredential.GetType()), + method: T_TokenCredential.GetType().GetMethod(name: "GetToken", types: new Type[] { T_TokenRequestContext.GetType(), typeof(CancellationToken) }), arg0: parameterExpression_requestContext, arg1: parameterExpression_cancellationToken ); - var lambdaTest = Expression.Lambda( - body: callExpr, + var tokenPropertyExpression = Expression.Property( + expression: getTokenExpression, + propertyName: "Token" + ); + + return Expression.Lambda>( + body: tokenPropertyExpression, parameters: new ParameterExpression[] { + parameterExpression_tokenCredential, parameterExpression_requestContext, parameterExpression_cancellationToken }); - - var compileTest = lambdaTest.Compile(); // TODO: THIS NEEDS TO BE STORED AS A PRIVATE FIELD SO IT CAN BE REUSED. - var accessToken = compileTest.DynamicInvoke(this.tokenRequestContext, cancellationToken); - - var tokenProperty = accessTokenType.GetProperty("Token"); - return (string)tokenProperty.GetValue(accessToken); } /// @@ -135,5 +154,6 @@ private object GetTokenRequestContext() var tokenProperty = accessTokenType.GetProperty("Token"); return (string)tokenProperty.GetValue(accessToken); } + } } From 4e38ac2b794dfe683b6b091e1126e06a8a9d5663 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 29 Mar 2021 15:30:56 -0700 Subject: [PATCH 16/93] cleanup --- .../ReflectionCredentialEnvelopeTests.cs | 7 +++- .../ReflectionCredentialEnvelope.cs | 32 +++++++++++-------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs index 7a3cca9f80..9694e96d03 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs @@ -57,8 +57,13 @@ public void VerifyGetTokenAsExpression_UsingCompileTimeTypes() [TestMethod] public void VerifyGetTokenAsExpression_UsingDynamicTypes() { + // This currently throws ArgumentExceptions: + // ParameterExpression of type 'Microsoft.ApplicationInsights.Authentication.Tests.MockCredential' cannot be used for delegate parameter of type 'System.Object' + // ParameterExpression of type 'Azure.Core.TokenRequestContext' cannot be used for delegate parameter of type 'System.Object' + + var mockCredential = (object)new MockCredential(); - var requestContext = ReflectionCredentialEnvelope.GetTokenRequestContext(new[] { "test/scope" }); + var requestContext = ReflectionCredentialEnvelope.MakeTokenRequestContext(new[] { "test/scope" }); var expression = ReflectionCredentialEnvelope.GetTokenAsExpression(mockCredential, requestContext).Compile(); diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index ea9cf3882b..50c9441823 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -13,6 +13,8 @@ /// Our SDK currently targets net452, net46, and netstandard2.0. /// Azure.Core.TokenCredential is only available for netstandard2.0. /// I'm introducing this class as a wrapper so we can receive an instance of this class and pass it around within our SDK. + /// This class uses compiled Expression Trees. + /// Read more here: (https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/expression-trees/). /// internal class ReflectionCredentialEnvelope : CredentialEnvelope { @@ -33,7 +35,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) if (tokenCredential.GetType().IsSubclassOf(tokenCredentialType)) { - this.tokenRequestContext = GetTokenRequestContext(scopes: GetScopes()); + this.tokenRequestContext = MakeTokenRequestContext(scopes: GetScopes()); } else { @@ -48,7 +50,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) /// public TokenRequestContext (string[] scopes, string? parentRequestId = default, string? claims = default); /// (https://docs.microsoft.com/dotnet/api/azure.core.tokenrequestcontext.-ctor). /// - internal static object GetTokenRequestContext(string[] scopes) + internal static object MakeTokenRequestContext(string[] scopes) { return Activator.CreateInstance( type: Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"), @@ -74,34 +76,38 @@ internal static object GetTokenRequestContext(string[] scopes) /// internal static Expression> GetTokenAsExpression(T1 T_TokenCredential, T2 T_TokenRequestContext) { - if (!T_TokenCredential.GetType().IsSubclassOf(Type.GetType("Azure.Core.TokenCredential, Azure.Core"))) + Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); + Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + Type typeCancellationToken = typeof(CancellationToken); + + if (!T_TokenCredential.GetType().IsSubclassOf(typeTokenCredential)) { throw new ArgumentException("Must be an instance of Azure.Core.TokenCredential", nameof(T_TokenCredential)); } - if (!T_TokenRequestContext.GetType().IsEquivalentTo(Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"))) + if (!T_TokenRequestContext.GetType().IsEquivalentTo(typeTokenRequestContext)) { throw new ArgumentException("Must be an instance of Azure.Core.TokenRequestContext", nameof(T_TokenRequestContext)); } - var parameterExpression_tokenCredential = Expression.Parameter(type: T_TokenCredential.GetType(), name: "parameterExpression_tokenCredential"); - var parameterExpression_requestContext = Expression.Parameter(type: T_TokenRequestContext.GetType(), name: "parameterExpression_requestContext"); - var parameterExpression_cancellationToken = Expression.Parameter(type: typeof(CancellationToken), name: "parameterExpression_cancellationToken"); + var parameterExpression_tokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); + var parameterExpression_requestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); + var parameterExpression_cancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); - var getTokenExpression = Expression.Call( - instance: Expression.New(T_TokenCredential.GetType()), - method: T_TokenCredential.GetType().GetMethod(name: "GetToken", types: new Type[] { T_TokenRequestContext.GetType(), typeof(CancellationToken) }), + var exprGetToken = Expression.Call( + instance: parameterExpression_tokenCredential, + method: typeTokenCredential.GetMethod(name: "GetToken", types: new Type[] { typeTokenRequestContext, typeCancellationToken }), arg0: parameterExpression_requestContext, arg1: parameterExpression_cancellationToken ); - var tokenPropertyExpression = Expression.Property( - expression: getTokenExpression, + var exprTokenProperty = Expression.Property( + expression: exprGetToken, propertyName: "Token" ); return Expression.Lambda>( - body: tokenPropertyExpression, + body: exprTokenProperty, parameters: new ParameterExpression[] { parameterExpression_tokenCredential, From 862d3f24340c0f351bb19f478561ee6ec7862d69 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 29 Mar 2021 15:48:17 -0700 Subject: [PATCH 17/93] change from Lambda to LambdaExpression. Tests pass --- .../ReflectionCredentialEnvelopeTests.cs | 44 +++++++-- .../ReflectionCredentialEnvelope.cs | 93 ++++++++++++++----- 2 files changed, 110 insertions(+), 27 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs index 9694e96d03..710b153c74 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs @@ -39,15 +39,47 @@ public void VerifyCannotSetInvalidType() _ = new ReflectionCredentialEnvelope(Guid.Empty); } + //[TestMethod] + //public void VerifyGetTokenAsExpression_UsingCompileTimeTypes() + //{ + // var mockCredential = new MockCredential(); + // var requestContext = new TokenRequestContext(new string[] { "test/scope" }); + + // var expression = ReflectionCredentialEnvelope.GetTokenAsExpression(mockCredential, requestContext).Compile(); + + // var testResult = expression(mockCredential, requestContext, CancellationToken.None); + // Assert.AreEqual("TEST TOKEN test/scope", testResult); + //} + + ///// + ///// This more closely represents how this would be used in a production environment. + ///// + //[TestMethod] + //public void VerifyGetTokenAsExpression_UsingDynamicTypes() + //{ + // // This currently throws ArgumentExceptions: + // // ParameterExpression of type 'Microsoft.ApplicationInsights.Authentication.Tests.MockCredential' cannot be used for delegate parameter of type 'System.Object' + // // ParameterExpression of type 'Azure.Core.TokenRequestContext' cannot be used for delegate parameter of type 'System.Object' + + + // var mockCredential = (object)new MockCredential(); + // var requestContext = ReflectionCredentialEnvelope.MakeTokenRequestContext(new[] { "test/scope" }); + + // var expression = ReflectionCredentialEnvelope.GetTokenAsExpression(mockCredential, requestContext).Compile(); + + // var testResult = expression(mockCredential, requestContext, CancellationToken.None); + // Assert.AreEqual("TEST TOKEN test/scope", testResult); + //} + [TestMethod] - public void VerifyGetTokenAsExpression_UsingCompileTimeTypes() + public void VerifyGetTokenAsLabmdaExpression_UsingCompileTimeTypes() { var mockCredential = new MockCredential(); var requestContext = new TokenRequestContext(new string[] { "test/scope" }); - var expression = ReflectionCredentialEnvelope.GetTokenAsExpression(mockCredential, requestContext).Compile(); + var expression = ReflectionCredentialEnvelope.GetTokenAsLambdaExpression().Compile(); - var testResult = expression(mockCredential, requestContext, CancellationToken.None); + var testResult = expression.DynamicInvoke(mockCredential, requestContext, CancellationToken.None); Assert.AreEqual("TEST TOKEN test/scope", testResult); } @@ -55,7 +87,7 @@ public void VerifyGetTokenAsExpression_UsingCompileTimeTypes() /// This more closely represents how this would be used in a production environment. /// [TestMethod] - public void VerifyGetTokenAsExpression_UsingDynamicTypes() + public void VerifyGetTokenAsLabmdaExpression_UsingDynamicTypes() { // This currently throws ArgumentExceptions: // ParameterExpression of type 'Microsoft.ApplicationInsights.Authentication.Tests.MockCredential' cannot be used for delegate parameter of type 'System.Object' @@ -65,9 +97,9 @@ public void VerifyGetTokenAsExpression_UsingDynamicTypes() var mockCredential = (object)new MockCredential(); var requestContext = ReflectionCredentialEnvelope.MakeTokenRequestContext(new[] { "test/scope" }); - var expression = ReflectionCredentialEnvelope.GetTokenAsExpression(mockCredential, requestContext).Compile(); + var expression = ReflectionCredentialEnvelope.GetTokenAsLambdaExpression().Compile(); - var testResult = expression(mockCredential, requestContext, CancellationToken.None); + var testResult = expression.DynamicInvoke(mockCredential, requestContext, CancellationToken.None); Assert.AreEqual("TEST TOKEN test/scope", testResult); } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 50c9441823..e51ffb0a98 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -59,37 +59,87 @@ internal static object MakeTokenRequestContext(string[] scopes) public override string GetToken(CancellationToken cancellationToken = default(CancellationToken)) { - var expression = GetTokenAsExpression(this.tokenCredential, this.tokenRequestContext); - var func = expression.Compile(); // TODO: THIS NEEDS TO BE STORED AS A PRIVATE FIELD SO IT CAN BE REUSED. - return func(this.tokenCredential, this.tokenRequestContext, cancellationToken); + var expression = GetTokenAsLambdaExpression(); + var @delegate = expression.Compile(); // TODO: THIS NEEDS TO BE STORED AS A PRIVATE FIELD SO IT CAN BE REUSED. + return (string)@delegate.DynamicInvoke(this.tokenCredential, this.tokenRequestContext, cancellationToken); } + ///// + ///// This is a wrapper for the following method: + ///// public abstract Azure.Core.AccessToken GetToken (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); + ///// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettoken). + ///// + ///// + ///// + ///// + ///// + ///// + //internal static Expression> GetTokenAsExpression(T1 T_TokenCredential, T2 T_TokenRequestContext) + //{ + // Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); + // Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + // Type typeCancellationToken = typeof(CancellationToken); + + // if (!T_TokenCredential.GetType().IsSubclassOf(typeTokenCredential)) + // { + // throw new ArgumentException("Must be an instance of Azure.Core.TokenCredential", nameof(T_TokenCredential)); + // } + + // if (!T_TokenRequestContext.GetType().IsEquivalentTo(typeTokenRequestContext)) + // { + // throw new ArgumentException("Must be an instance of Azure.Core.TokenRequestContext", nameof(T_TokenRequestContext)); + // } + + // var parameterExpression_tokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); + // var parameterExpression_requestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); + // var parameterExpression_cancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); + + // var exprGetToken = Expression.Call( + // instance: parameterExpression_tokenCredential, + // method: typeTokenCredential.GetMethod(name: "GetToken", types: new Type[] { typeTokenRequestContext, typeCancellationToken }), + // arg0: parameterExpression_requestContext, + // arg1: parameterExpression_cancellationToken + // ); + + // var exprTokenProperty = Expression.Property( + // expression: exprGetToken, + // propertyName: "Token" + // ); + + + // var test = Expression.Lambda( + // body: exprTokenProperty, + // parameters: new ParameterExpression[] + // { + // parameterExpression_tokenCredential, + // parameterExpression_requestContext, + // parameterExpression_cancellationToken + // }); + // var test2 = test.Compile(); + // var result = test2.DynamicInvoke(T_TokenCredential, T_TokenRequestContext, CancellationToken.None); + + + // return Expression.Lambda>( + // body: exprTokenProperty, + // parameters: new ParameterExpression[] + // { + // parameterExpression_tokenCredential, + // parameterExpression_requestContext, + // parameterExpression_cancellationToken + // }); + //} + /// - /// This is a wrapper for the following method: + /// This creates a wrapper for the following method: /// public abstract Azure.Core.AccessToken GetToken (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); /// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettoken). /// - /// - /// - /// - /// - /// - internal static Expression> GetTokenAsExpression(T1 T_TokenCredential, T2 T_TokenRequestContext) + internal static LambdaExpression GetTokenAsLambdaExpression() { Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); Type typeCancellationToken = typeof(CancellationToken); - if (!T_TokenCredential.GetType().IsSubclassOf(typeTokenCredential)) - { - throw new ArgumentException("Must be an instance of Azure.Core.TokenCredential", nameof(T_TokenCredential)); - } - - if (!T_TokenRequestContext.GetType().IsEquivalentTo(typeTokenRequestContext)) - { - throw new ArgumentException("Must be an instance of Azure.Core.TokenRequestContext", nameof(T_TokenRequestContext)); - } - var parameterExpression_tokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); var parameterExpression_requestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); var parameterExpression_cancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); @@ -106,7 +156,7 @@ internal static Expression> GetTokenAsEx propertyName: "Token" ); - return Expression.Lambda>( + return Expression.Lambda( body: exprTokenProperty, parameters: new ParameterExpression[] { @@ -116,6 +166,7 @@ internal static Expression> GetTokenAsEx }); } + /// /// This is a wrapper for the following method: /// public abstract System.Threading.Tasks.ValueTask<Azure.Core.AccessToken> GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); From ddcbecda8265367cb00fc1e24837be8670286054 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 29 Mar 2021 17:35:25 -0700 Subject: [PATCH 18/93] have a working example of aysnc + Expression tree. need to cleanup --- .../ReflectionCredentialEnvelopeTests.cs | 39 +++++++++-- .../ReflectionCredentialEnvelope.cs | 65 ++++++++++++++++++- 2 files changed, 96 insertions(+), 8 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs index 710b153c74..10742ec570 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs @@ -1,6 +1,7 @@ namespace Microsoft.ApplicationInsights.Authentication.Tests { using System; + using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; @@ -72,7 +73,7 @@ public void VerifyCannotSetInvalidType() //} [TestMethod] - public void VerifyGetTokenAsLabmdaExpression_UsingCompileTimeTypes() + public void VerifyGetToken_AsLambdaExpression_UsingCompileTimeTypes() { var mockCredential = new MockCredential(); var requestContext = new TokenRequestContext(new string[] { "test/scope" }); @@ -87,13 +88,8 @@ public void VerifyGetTokenAsLabmdaExpression_UsingCompileTimeTypes() /// This more closely represents how this would be used in a production environment. /// [TestMethod] - public void VerifyGetTokenAsLabmdaExpression_UsingDynamicTypes() + public void VerifyGetToken_AsLambdaExpression_UsingDynamicTypes() { - // This currently throws ArgumentExceptions: - // ParameterExpression of type 'Microsoft.ApplicationInsights.Authentication.Tests.MockCredential' cannot be used for delegate parameter of type 'System.Object' - // ParameterExpression of type 'Azure.Core.TokenRequestContext' cannot be used for delegate parameter of type 'System.Object' - - var mockCredential = (object)new MockCredential(); var requestContext = ReflectionCredentialEnvelope.MakeTokenRequestContext(new[] { "test/scope" }); @@ -103,6 +99,35 @@ public void VerifyGetTokenAsLabmdaExpression_UsingDynamicTypes() Assert.AreEqual("TEST TOKEN test/scope", testResult); } + + [TestMethod] + public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingCompileTimeTypes() + { + var mockCredential = new MockCredential(); + var requestContext = new TokenRequestContext(new string[] { "test/scope" }); + + var testResult = await ReflectionCredentialEnvelope.GetTokenAsyncAsExpression(mockCredential, requestContext, CancellationToken.None); + + Assert.AreEqual("TEST TOKEN test/scope", testResult); + } + + /// + /// This more closely represents how this would be used in a production environment. + /// + [TestMethod] + public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingDynamicTypes() + { + var mockCredential = (object)new MockCredential(); + var requestContext = ReflectionCredentialEnvelope.MakeTokenRequestContext(new[] { "test/scope" }); + + var testResult = await ReflectionCredentialEnvelope.GetTokenAsyncAsExpression(mockCredential, requestContext, CancellationToken.None); + + Assert.AreEqual("TEST TOKEN test/scope", testResult); + + + + } + #region TestClasses private class TestClass1 : Azure.Core.TokenCredential { diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index e51ffb0a98..496de2a970 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -14,7 +14,9 @@ /// Azure.Core.TokenCredential is only available for netstandard2.0. /// I'm introducing this class as a wrapper so we can receive an instance of this class and pass it around within our SDK. /// This class uses compiled Expression Trees. - /// Read more here: (https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/expression-trees/). + /// Read more here: + /// (https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/expression-trees/). + /// (https://docs.microsoft.com/dotnet/csharp/expression-trees). /// internal class ReflectionCredentialEnvelope : CredentialEnvelope { @@ -212,5 +214,66 @@ internal static LambdaExpression GetTokenAsLambdaExpression() return (string)tokenProperty.GetValue(accessToken); } + /// TODO: CONVERT THIS INTO A PARAMETER-LESS METHOD THAT RETURNS THE EXPRESSION + public static async Task GetTokenAsyncAsExpression(object tokenCredential, object tokenRequestContext, CancellationToken cancellationToken) + { + Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); + Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + Type typeCancellationToken = typeof(CancellationToken); + + var parameterExpression_TokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); + var parameterExpression_RequestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); + var parameterExpression_CancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); + + // public abstract System.Threading.Tasks.ValueTask GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); + var methodInfo_GetTokenAsync = typeTokenCredential.GetMethod(name: "GetTokenAsync", types: new Type[] { typeTokenRequestContext, typeCancellationToken }); + + var exprGetTokenAsync = Expression.Call( + instance: parameterExpression_TokenCredential, + method: methodInfo_GetTokenAsync, + arg0: parameterExpression_RequestContext, + arg1: parameterExpression_CancellationToken + ); + + var methodInfo_AsTask = methodInfo_GetTokenAsync.ReturnType.GetMethod("AsTask"); + + var exprAsTask = Expression.Call( + instance: exprGetTokenAsync, + method: methodInfo_AsTask + ); + + var delegateGetTokenAsyncAsTask = Expression.Lambda( + body: exprAsTask, + parameters: new ParameterExpression[] + { + parameterExpression_TokenCredential, + parameterExpression_RequestContext, + parameterExpression_CancellationToken + }).Compile(); + + var task = (Task)delegateGetTokenAsyncAsTask.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken); + await task.ConfigureAwait(false); + + var parameterExpression_Task = Expression.Parameter(type: methodInfo_AsTask.ReturnType, name: "parameterExpression_Task"); + + var exprResultProperty = Expression.Property( + expression: parameterExpression_Task, + propertyName: "Result" + ); + + var exprTokenProperty = Expression.Property( + expression: exprResultProperty, + propertyName: "Token" + ); + + var delegateToken = Expression.Lambda( + body: exprTokenProperty, + parameters: new ParameterExpression[] + { + parameterExpression_Task, + }).Compile(); + + return (string)delegateToken.DynamicInvoke(task); + } } } From 0a82f7b69d1522f3ed03db8e7ba967dfde043755 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 29 Mar 2021 17:52:32 -0700 Subject: [PATCH 19/93] this works. tests pass. needs significant cleanup. --- .../ReflectionCredentialEnvelopeTests.cs | 11 +-- .../ReflectionCredentialEnvelope.cs | 81 +++++++++++++++++++ 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs index 10742ec570..550113d2a3 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs @@ -106,7 +106,9 @@ public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingCompileTimeTypes() var mockCredential = new MockCredential(); var requestContext = new TokenRequestContext(new string[] { "test/scope" }); - var testResult = await ReflectionCredentialEnvelope.GetTokenAsyncAsExpression(mockCredential, requestContext, CancellationToken.None); + var expression = ReflectionCredentialEnvelope.GetTokenAsyncAsExpression(); + + var testResult = await expression.Run(mockCredential, requestContext, CancellationToken.None); Assert.AreEqual("TEST TOKEN test/scope", testResult); } @@ -120,12 +122,11 @@ public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingDynamicTypes() var mockCredential = (object)new MockCredential(); var requestContext = ReflectionCredentialEnvelope.MakeTokenRequestContext(new[] { "test/scope" }); - var testResult = await ReflectionCredentialEnvelope.GetTokenAsyncAsExpression(mockCredential, requestContext, CancellationToken.None); - - Assert.AreEqual("TEST TOKEN test/scope", testResult); - + var expression = ReflectionCredentialEnvelope.GetTokenAsyncAsExpression(); + var testResult = await expression.Run(mockCredential, requestContext, CancellationToken.None); + Assert.AreEqual("TEST TOKEN test/scope", testResult); } #region TestClasses diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 496de2a970..aac5b0596f 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -275,5 +275,86 @@ public static async Task GetTokenAsyncAsExpression(object tokenCredentia return (string)delegateToken.DynamicInvoke(task); } + + public static AsyncHack GetTokenAsyncAsExpression() + { + + Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); + Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + Type typeCancellationToken = typeof(CancellationToken); + + var parameterExpression_TokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); + var parameterExpression_RequestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); + var parameterExpression_CancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); + + // public abstract System.Threading.Tasks.ValueTask GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); + var methodInfo_GetTokenAsync = typeTokenCredential.GetMethod(name: "GetTokenAsync", types: new Type[] { typeTokenRequestContext, typeCancellationToken }); + + var exprGetTokenAsync = Expression.Call( + instance: parameterExpression_TokenCredential, + method: methodInfo_GetTokenAsync, + arg0: parameterExpression_RequestContext, + arg1: parameterExpression_CancellationToken + ); + + var methodInfo_AsTask = methodInfo_GetTokenAsync.ReturnType.GetMethod("AsTask"); + + var exprAsTask = Expression.Call( + instance: exprGetTokenAsync, + method: methodInfo_AsTask + ); + + var delegateGetTokenAsync = Expression.Lambda( + body: exprAsTask, + parameters: new ParameterExpression[] + { + parameterExpression_TokenCredential, + parameterExpression_RequestContext, + parameterExpression_CancellationToken + }).Compile(); + + //var task = (Task)delegateGetTokenAsyncAsTask.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken); + //await task.ConfigureAwait(false); + + var parameterExpression_Task = Expression.Parameter(type: methodInfo_AsTask.ReturnType, name: "parameterExpression_Task"); + + var exprResultProperty = Expression.Property( + expression: parameterExpression_Task, + propertyName: "Result" + ); + + var exprTokenProperty = Expression.Property( + expression: exprResultProperty, + propertyName: "Token" + ); + + var delegateTokenProperty = Expression.Lambda( + body: exprTokenProperty, + parameters: new ParameterExpression[] + { + parameterExpression_Task, + }).Compile(); + + return new AsyncHack(delegateGetTokenAsync, delegateTokenProperty); + } + + internal class AsyncHack + { + private readonly Delegate getTokenAsync; + private readonly Delegate getTokenProperty; + + public AsyncHack(Delegate gettokenAsync, Delegate getTokenProperty) + { + this.getTokenAsync = gettokenAsync; + this.getTokenProperty = getTokenProperty; + } + + public async Task Run(object tokenCredential, object tokenRequestContext, CancellationToken cancellationToken) + { + var task = (Task)this.getTokenAsync.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken); + await task.ConfigureAwait(false); + return (string)this.getTokenProperty.DynamicInvoke(task); + } + } } } From 47ce7e507b4771e422726578420a529750834e9b Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Tue, 30 Mar 2021 14:52:39 -0700 Subject: [PATCH 20/93] significant refactor. cleanup. all tests pass --- .../net452/PublicAPI.Unshipped.txt | 8 + .../net46/PublicAPI.Unshipped.txt | 20 + .../netstandard2.0/PublicAPI.Unshipped.txt | 8 + .../CredentialEnvelopeTests.cs | 6 - .../ReflectionCredentialEnvelopeTests.cs | 19 +- .../Authentication/CredentialEnvelope.cs | 33 +- .../ReflectionCredentialEnvelope.cs | 447 ++++++------------ .../Authentication/TokenCredentialEnvelope.cs | 17 +- .../Extensibility/TelemetryConfiguration.cs | 11 +- 9 files changed, 225 insertions(+), 344 deletions(-) diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt index e69de29bb2..6b7fb8748a 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(object tokenCredential) -> void +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] \ No newline at end of file diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt index e69de29bb2..61251cb65f 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +Microsoft.ApplicationInsights.Channel.Transmission.EndpointAddress.get -> Uri +Microsoft.ApplicationInsights.Channel.Transmission.Transmission(Uri address, System.Collections.Generic.ICollection telemetryItems, System.TimeSpan timeout = default(System.TimeSpan)) -> void +Microsoft.ApplicationInsights.Channel.Transmission.Transmission(Uri address, byte[] content, string contentType, string contentEncoding, System.TimeSpan timeout = default(System.TimeSpan)) -> void +Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Url.get -> Uri +Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.Url.get -> Uri +Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Url.get -> Uri +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Ingestion.get -> Uri +Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Live.get -> Uri +Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Profiler.get -> Uri +Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Snapshot.get -> Uri +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(object tokenCredential) -> void +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] +virtual Microsoft.ApplicationInsights.Channel.Transmission.CreateRequest(Uri address) -> WebRequest +virtual Microsoft.ApplicationInsights.Channel.Transmission.CreateRequestMessage(Uri address, System.IO.Stream contentStream) -> System.Net.Http.HttpRequestMessage \ No newline at end of file diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..9aae3d025d 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(Azure.Core.TokenCredential tokenCredential) -> void +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] \ No newline at end of file diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs index 239b85e680..9cbcd3d9b1 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs @@ -1,14 +1,8 @@ namespace Microsoft.ApplicationInsights.Authentication.Tests { using System; - using System.Linq.Expressions; - using System.Threading; using System.Threading.Tasks; - using Azure.Core; - using Azure.Core.Pipeline; - using Azure.Identity; - using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs index 550113d2a3..f705aba489 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs @@ -1,7 +1,6 @@ namespace Microsoft.ApplicationInsights.Authentication.Tests { using System; - using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; @@ -78,9 +77,8 @@ public void VerifyGetToken_AsLambdaExpression_UsingCompileTimeTypes() var mockCredential = new MockCredential(); var requestContext = new TokenRequestContext(new string[] { "test/scope" }); - var expression = ReflectionCredentialEnvelope.GetTokenAsLambdaExpression().Compile(); + var testResult = ReflectionCredentialEnvelope.AzureCore.InvokeGetToken(mockCredential, requestContext, CancellationToken.None); - var testResult = expression.DynamicInvoke(mockCredential, requestContext, CancellationToken.None); Assert.AreEqual("TEST TOKEN test/scope", testResult); } @@ -91,11 +89,10 @@ public void VerifyGetToken_AsLambdaExpression_UsingCompileTimeTypes() public void VerifyGetToken_AsLambdaExpression_UsingDynamicTypes() { var mockCredential = (object)new MockCredential(); - var requestContext = ReflectionCredentialEnvelope.MakeTokenRequestContext(new[] { "test/scope" }); + var requestContext = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(new[] { "test/scope" }); - var expression = ReflectionCredentialEnvelope.GetTokenAsLambdaExpression().Compile(); + var testResult = ReflectionCredentialEnvelope.AzureCore.InvokeGetToken(mockCredential, requestContext, CancellationToken.None); - var testResult = expression.DynamicInvoke(mockCredential, requestContext, CancellationToken.None); Assert.AreEqual("TEST TOKEN test/scope", testResult); } @@ -106,9 +103,7 @@ public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingCompileTimeTypes() var mockCredential = new MockCredential(); var requestContext = new TokenRequestContext(new string[] { "test/scope" }); - var expression = ReflectionCredentialEnvelope.GetTokenAsyncAsExpression(); - - var testResult = await expression.Run(mockCredential, requestContext, CancellationToken.None); + var testResult = await ReflectionCredentialEnvelope.AzureCore.InvokeGetTokenAsync(mockCredential, requestContext, CancellationToken.None); Assert.AreEqual("TEST TOKEN test/scope", testResult); } @@ -120,11 +115,9 @@ public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingCompileTimeTypes() public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingDynamicTypes() { var mockCredential = (object)new MockCredential(); - var requestContext = ReflectionCredentialEnvelope.MakeTokenRequestContext(new[] { "test/scope" }); - - var expression = ReflectionCredentialEnvelope.GetTokenAsyncAsExpression(); + var requestContext = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(new[] { "test/scope" }); - var testResult = await expression.Run(mockCredential, requestContext, CancellationToken.None); + var testResult = await ReflectionCredentialEnvelope.AzureCore.InvokeGetTokenAsync(mockCredential, requestContext, CancellationToken.None); Assert.AreEqual("TEST TOKEN test/scope", testResult); } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index 3c3123f38f..5bc326d2bf 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -1,24 +1,41 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { - using System; using System.Threading; using System.Threading.Tasks; + /// + /// An envelope for an instance of Azure.Core.TokenCredential. + /// public abstract class CredentialEnvelope { /// - /// https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens - /// - /// Other APIs might require that no scheme or host is included in the scope value, and expect only the app ID (a GUID) and the scope name, for example: 11111111-1111-1111-1111-111111111111/api.read + /// Source: (https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). /// - private const string Scope = "https://storage.azure.com/.default"; // example from Blob Storage. TODO: NEED OUR OWN SCOPE + private const string Scope = "https://monitor.azure.com"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. - protected static string[] GetScopes() => new string[] { Scope }; - - public abstract object Credential { get;} + /// + /// Gets the TokenCredential object held by this class. + /// + public abstract object Credential { get; } + /// + /// Gets an Azure.Core.AccessToken. + /// + /// The System.Threading.CancellationToken to use. + /// A valid Azure.Core.AccessToken. public abstract string GetToken(CancellationToken cancellationToken); + /// + /// Gets an Azure.Core.AccessToken. + /// + /// The System.Threading.CancellationToken to use. + /// A valid Azure.Core.AccessToken. public abstract Task GetTokenAsync(CancellationToken cancellationToken); + + /// + /// Get scopes for Azure Monitor as an array. + /// + /// An array of scopes. + protected static string[] GetScopes() => new string[] { Scope }; } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index aac5b0596f..418deeeecb 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -2,42 +2,32 @@ { using System; using System.Linq.Expressions; - using System.Reflection; using System.Threading; using System.Threading.Tasks; /// - /// + /// This is an implementation of that uses reflection to interact with the Azure.Core library. /// /// /// Our SDK currently targets net452, net46, and netstandard2.0. /// Azure.Core.TokenCredential is only available for netstandard2.0. - /// I'm introducing this class as a wrapper so we can receive an instance of this class and pass it around within our SDK. - /// This class uses compiled Expression Trees. - /// Read more here: - /// (https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/expression-trees/). - /// (https://docs.microsoft.com/dotnet/csharp/expression-trees). /// internal class ReflectionCredentialEnvelope : CredentialEnvelope { - private readonly Type tokenCredentialType = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); - private readonly Type tokenRequestContextType = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); - private readonly Type accessTokenType = Type.GetType("Azure.Core.AccessToken, Azure.Core"); - private readonly object tokenCredential; private readonly object tokenRequestContext; /// - /// + /// Create an instance of . /// - /// + /// An instance of Azure.Core.TokenCredential. public ReflectionCredentialEnvelope(object tokenCredential) { this.tokenCredential = tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential)); - if (tokenCredential.GetType().IsSubclassOf(tokenCredentialType)) + if (tokenCredential.GetType().IsSubclassOf(Type.GetType("Azure.Core.TokenCredential, Azure.Core"))) { - this.tokenRequestContext = MakeTokenRequestContext(scopes: GetScopes()); + this.tokenRequestContext = AzureCore.MakeTokenRequestContext(scopes: GetScopes()); } else { @@ -45,315 +35,168 @@ public ReflectionCredentialEnvelope(object tokenCredential) } } + /// public override object Credential => this.tokenCredential; - /// - /// This is a wrapper for the following constructor: - /// public TokenRequestContext (string[] scopes, string? parentRequestId = default, string? claims = default); - /// (https://docs.microsoft.com/dotnet/api/azure.core.tokenrequestcontext.-ctor). - /// - internal static object MakeTokenRequestContext(string[] scopes) - { - return Activator.CreateInstance( - type: Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"), - args: new object[] { scopes, null, null }); - } - + /// public override string GetToken(CancellationToken cancellationToken = default(CancellationToken)) { - var expression = GetTokenAsLambdaExpression(); - var @delegate = expression.Compile(); // TODO: THIS NEEDS TO BE STORED AS A PRIVATE FIELD SO IT CAN BE REUSED. - return (string)@delegate.DynamicInvoke(this.tokenCredential, this.tokenRequestContext, cancellationToken); + return AzureCore.InvokeGetToken(this.tokenCredential, this.tokenRequestContext, cancellationToken); } - ///// - ///// This is a wrapper for the following method: - ///// public abstract Azure.Core.AccessToken GetToken (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); - ///// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettoken). - ///// - ///// - ///// - ///// - ///// - ///// - //internal static Expression> GetTokenAsExpression(T1 T_TokenCredential, T2 T_TokenRequestContext) - //{ - // Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); - // Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); - // Type typeCancellationToken = typeof(CancellationToken); - - // if (!T_TokenCredential.GetType().IsSubclassOf(typeTokenCredential)) - // { - // throw new ArgumentException("Must be an instance of Azure.Core.TokenCredential", nameof(T_TokenCredential)); - // } - - // if (!T_TokenRequestContext.GetType().IsEquivalentTo(typeTokenRequestContext)) - // { - // throw new ArgumentException("Must be an instance of Azure.Core.TokenRequestContext", nameof(T_TokenRequestContext)); - // } - - // var parameterExpression_tokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); - // var parameterExpression_requestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); - // var parameterExpression_cancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); - - // var exprGetToken = Expression.Call( - // instance: parameterExpression_tokenCredential, - // method: typeTokenCredential.GetMethod(name: "GetToken", types: new Type[] { typeTokenRequestContext, typeCancellationToken }), - // arg0: parameterExpression_requestContext, - // arg1: parameterExpression_cancellationToken - // ); - - // var exprTokenProperty = Expression.Property( - // expression: exprGetToken, - // propertyName: "Token" - // ); - - - // var test = Expression.Lambda( - // body: exprTokenProperty, - // parameters: new ParameterExpression[] - // { - // parameterExpression_tokenCredential, - // parameterExpression_requestContext, - // parameterExpression_cancellationToken - // }); - // var test2 = test.Compile(); - // var result = test2.DynamicInvoke(T_TokenCredential, T_TokenRequestContext, CancellationToken.None); - - - // return Expression.Lambda>( - // body: exprTokenProperty, - // parameters: new ParameterExpression[] - // { - // parameterExpression_tokenCredential, - // parameterExpression_requestContext, - // parameterExpression_cancellationToken - // }); - //} - - /// - /// This creates a wrapper for the following method: - /// public abstract Azure.Core.AccessToken GetToken (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); - /// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettoken). - /// - internal static LambdaExpression GetTokenAsLambdaExpression() + /// + public override Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { - Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); - Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); - Type typeCancellationToken = typeof(CancellationToken); - - var parameterExpression_tokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); - var parameterExpression_requestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); - var parameterExpression_cancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); - - var exprGetToken = Expression.Call( - instance: parameterExpression_tokenCredential, - method: typeTokenCredential.GetMethod(name: "GetToken", types: new Type[] { typeTokenRequestContext, typeCancellationToken }), - arg0: parameterExpression_requestContext, - arg1: parameterExpression_cancellationToken - ); - - var exprTokenProperty = Expression.Property( - expression: exprGetToken, - propertyName: "Token" - ); - - return Expression.Lambda( - body: exprTokenProperty, - parameters: new ParameterExpression[] - { - parameterExpression_tokenCredential, - parameterExpression_requestContext, - parameterExpression_cancellationToken - }); + return AzureCore.InvokeGetTokenAsync(this.tokenCredential, this.tokenRequestContext, cancellationToken); } - /// - /// This is a wrapper for the following method: - /// public abstract System.Threading.Tasks.ValueTask<Azure.Core.AccessToken> GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); - /// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettokenasync). + /// This class provides Reflection based wrappers around types found in the Azure.Core library. + /// Because of framework incompatibilities, we cannot take a direct reference on these types. + /// + /// This class uses compiled Expression Trees. Read more here: + /// (https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/expression-trees/). + /// (https://docs.microsoft.com/dotnet/csharp/expression-trees). /// - /// - /// - public override async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) - { - var tokenCredentialType = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); - var tokenRequestContextType = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); - var accessTokenType = Type.GetType("Azure.Core.AccessToken, Azure.Core"); - - var parameterExpression_requestContext = Expression.Parameter(type: tokenRequestContextType, name: "parameterExpression_requestContext"); - var parameterExpression_cancellationToken = Expression.Parameter(type: typeof(CancellationToken), name: "parameterExpression_cancellationToken"); - - Expression callExpr = Expression.Call( - instance: Expression.New(this.Credential.GetType()), - method: tokenCredentialType.GetMethod(name: "GetTokenAsync", types: new Type[] { tokenRequestContextType, typeof(CancellationToken) }), - arg0: parameterExpression_requestContext, - arg1: parameterExpression_cancellationToken - ); - - var lambdaTest = Expression.Lambda( - body: callExpr, - parameters: new ParameterExpression[] - { - parameterExpression_requestContext, - parameterExpression_cancellationToken - }); - - var compileTest = lambdaTest.Compile(); // TODO: THIS NEEDS TO BE STORED AS A PRIVATE FIELD SO IT CAN BE REUSED. - var valueTaskAccessToken = compileTest.DynamicInvoke(this.tokenRequestContext, cancellationToken); - - var asTaskMethod = valueTaskAccessToken.GetType().GetMethod("AsTask"); - - var task = (Task)asTaskMethod.Invoke(valueTaskAccessToken, null); - await task.ConfigureAwait(false); - var resultProperty = task.GetType().GetProperty("Result"); - var accessToken = resultProperty.GetValue(task); - - var tokenProperty = accessTokenType.GetProperty("Token"); - return (string)tokenProperty.GetValue(accessToken); - } - - /// TODO: CONVERT THIS INTO A PARAMETER-LESS METHOD THAT RETURNS THE EXPRESSION - public static async Task GetTokenAsyncAsExpression(object tokenCredential, object tokenRequestContext, CancellationToken cancellationToken) + internal static class AzureCore { - Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); - Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); - Type typeCancellationToken = typeof(CancellationToken); - - var parameterExpression_TokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); - var parameterExpression_RequestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); - var parameterExpression_CancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); + private static readonly Delegate GetTokenValue; + private static readonly Delegate GetTokenAsyncValue; + private static readonly Delegate GetTokenProperty; - // public abstract System.Threading.Tasks.ValueTask GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); - var methodInfo_GetTokenAsync = typeTokenCredential.GetMethod(name: "GetTokenAsync", types: new Type[] { typeTokenRequestContext, typeCancellationToken }); - - var exprGetTokenAsync = Expression.Call( - instance: parameterExpression_TokenCredential, - method: methodInfo_GetTokenAsync, - arg0: parameterExpression_RequestContext, - arg1: parameterExpression_CancellationToken - ); - - var methodInfo_AsTask = methodInfo_GetTokenAsync.ReturnType.GetMethod("AsTask"); - - var exprAsTask = Expression.Call( - instance: exprGetTokenAsync, - method: methodInfo_AsTask - ); - - var delegateGetTokenAsyncAsTask = Expression.Lambda( - body: exprAsTask, - parameters: new ParameterExpression[] - { - parameterExpression_TokenCredential, - parameterExpression_RequestContext, - parameterExpression_CancellationToken - }).Compile(); - - var task = (Task)delegateGetTokenAsyncAsTask.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken); - await task.ConfigureAwait(false); - - var parameterExpression_Task = Expression.Parameter(type: methodInfo_AsTask.ReturnType, name: "parameterExpression_Task"); - - var exprResultProperty = Expression.Property( - expression: parameterExpression_Task, - propertyName: "Result" - ); - - var exprTokenProperty = Expression.Property( - expression: exprResultProperty, - propertyName: "Token" - ); - - var delegateToken = Expression.Lambda( - body: exprTokenProperty, - parameters: new ParameterExpression[] - { - parameterExpression_Task, - }).Compile(); - - return (string)delegateToken.DynamicInvoke(task); - } - - public static AsyncHack GetTokenAsyncAsExpression() - { - - Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); - Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); - Type typeCancellationToken = typeof(CancellationToken); - - var parameterExpression_TokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); - var parameterExpression_RequestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); - var parameterExpression_CancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); - - // public abstract System.Threading.Tasks.ValueTask GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); - var methodInfo_GetTokenAsync = typeTokenCredential.GetMethod(name: "GetTokenAsync", types: new Type[] { typeTokenRequestContext, typeCancellationToken }); - - var exprGetTokenAsync = Expression.Call( - instance: parameterExpression_TokenCredential, - method: methodInfo_GetTokenAsync, - arg0: parameterExpression_RequestContext, - arg1: parameterExpression_CancellationToken - ); - - var methodInfo_AsTask = methodInfo_GetTokenAsync.ReturnType.GetMethod("AsTask"); - - var exprAsTask = Expression.Call( - instance: exprGetTokenAsync, - method: methodInfo_AsTask - ); - - var delegateGetTokenAsync = Expression.Lambda( - body: exprAsTask, - parameters: new ParameterExpression[] - { - parameterExpression_TokenCredential, - parameterExpression_RequestContext, - parameterExpression_CancellationToken - }).Compile(); - - //var task = (Task)delegateGetTokenAsyncAsTask.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken); - //await task.ConfigureAwait(false); - - var parameterExpression_Task = Expression.Parameter(type: methodInfo_AsTask.ReturnType, name: "parameterExpression_Task"); - - var exprResultProperty = Expression.Property( - expression: parameterExpression_Task, - propertyName: "Result" - ); + static AzureCore() + { + GetTokenValue = BuildDelegateGetToken(); - var exprTokenProperty = Expression.Property( - expression: exprResultProperty, - propertyName: "Token" - ); + var asyncDelegates = BuildDelegateGetTokenAsync(); + GetTokenAsyncValue = asyncDelegates[0]; + GetTokenProperty = asyncDelegates[1]; + } - var delegateTokenProperty = Expression.Lambda( - body: exprTokenProperty, - parameters: new ParameterExpression[] - { - parameterExpression_Task, - }).Compile(); + internal static string InvokeGetToken(object tokenCredential, object tokenRequestContext, CancellationToken cancellationToken) + { + return (string)GetTokenValue.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken); + } - return new AsyncHack(delegateGetTokenAsync, delegateTokenProperty); - } + internal static async Task InvokeGetTokenAsync(object tokenCredential, object tokenRequestContext, CancellationToken cancellationToken) + { + var task = (Task)GetTokenAsyncValue.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken); + await task.ConfigureAwait(false); + return (string)GetTokenProperty.DynamicInvoke(task); + } - internal class AsyncHack - { - private readonly Delegate getTokenAsync; - private readonly Delegate getTokenProperty; + /// + /// This is a wrapper for the following constructor: + /// public TokenRequestContext (string[] scopes, string? parentRequestId = default, string? claims = default); + /// (https://docs.microsoft.com/dotnet/api/azure.core.tokenrequestcontext.-ctor). + /// + internal static object MakeTokenRequestContext(string[] scopes) + { + return Activator.CreateInstance( + type: Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"), + args: new object[] { scopes, null, null }); + } - public AsyncHack(Delegate gettokenAsync, Delegate getTokenProperty) + /// This creates a wrapper for the following method: + /// public abstract Azure.Core.AccessToken GetToken (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken). + /// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettoken). + private static Delegate BuildDelegateGetToken() { - this.getTokenAsync = gettokenAsync; - this.getTokenProperty = getTokenProperty; + Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); + Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + Type typeCancellationToken = typeof(CancellationToken); + + var parameterExpression_tokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); + var parameterExpression_requestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); + var parameterExpression_cancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); + + var exprGetToken = Expression.Call( + instance: parameterExpression_tokenCredential, + method: typeTokenCredential.GetMethod(name: "GetToken", types: new Type[] { typeTokenRequestContext, typeCancellationToken }), + arg0: parameterExpression_requestContext, + arg1: parameterExpression_cancellationToken); + + var exprTokenProperty = Expression.Property( + expression: exprGetToken, + propertyName: "Token"); + + return Expression.Lambda( + body: exprTokenProperty, + parameters: new ParameterExpression[] + { + parameterExpression_tokenCredential, + parameterExpression_requestContext, + parameterExpression_cancellationToken, + }).Compile(); } - public async Task Run(object tokenCredential, object tokenRequestContext, CancellationToken cancellationToken) + /// + /// This is a wrapper for the following method: + /// public abstract System.Threading.Tasks.ValueTask<Azure.Core.AccessToken> GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); + /// (https://docs.microsoft.com/dotnet/api/azure.core.tokencredential.gettokenasync). + /// + /// + /// The Expression Tree library cannot handle async methods. + /// As a workaround, this method returns two Delegates. + /// First; + /// The first Delegate is a wrapper around GetTokenAsync which returns a ValueTask of AccessToken. + /// Then calls ValueTask.GetTask to convert that to a Task which is a known type for older frameworks. + /// Second; + /// The second Delegate is a wrapper around Task.Result which returns the AccessToken. + /// Then calls AccessToken.Token to get the string token. + /// + private static Delegate[] BuildDelegateGetTokenAsync() { - var task = (Task)this.getTokenAsync.DynamicInvoke(tokenCredential, tokenRequestContext, cancellationToken); - await task.ConfigureAwait(false); - return (string)this.getTokenProperty.DynamicInvoke(task); + Type typeTokenCredential = Type.GetType("Azure.Core.TokenCredential, Azure.Core"); + Type typeTokenRequestContext = Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"); + Type typeCancellationToken = typeof(CancellationToken); + + var parameterExpression_TokenCredential = Expression.Parameter(type: typeTokenCredential, name: "parameterExpression_TokenCredential"); + var parameterExpression_RequestContext = Expression.Parameter(type: typeTokenRequestContext, name: "parameterExpression_RequestContext"); + var parameterExpression_CancellationToken = Expression.Parameter(type: typeCancellationToken, name: "parameterExpression_CancellationToken"); + + // public abstract System.Threading.Tasks.ValueTask GetTokenAsync (Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken); + var methodInfo_GetTokenAsync = typeTokenCredential.GetMethod(name: "GetTokenAsync", types: new Type[] { typeTokenRequestContext, typeCancellationToken }); + + var exprGetTokenAsync = Expression.Call( + instance: parameterExpression_TokenCredential, + method: methodInfo_GetTokenAsync, + arg0: parameterExpression_RequestContext, + arg1: parameterExpression_CancellationToken); + + var methodInfo_AsTask = methodInfo_GetTokenAsync.ReturnType.GetMethod("AsTask"); + + var exprAsTask = Expression.Call( + instance: exprGetTokenAsync, + method: methodInfo_AsTask); + + var delegateGetTokenAsync = Expression.Lambda( + body: exprAsTask, + parameters: new ParameterExpression[] + { + parameterExpression_TokenCredential, + parameterExpression_RequestContext, + parameterExpression_CancellationToken, + }).Compile(); + + var parameterExpression_Task = Expression.Parameter(type: methodInfo_AsTask.ReturnType, name: "parameterExpression_Task"); + + var exprResultProperty = Expression.Property( + expression: parameterExpression_Task, + propertyName: "Result"); + + var exprTokenProperty = Expression.Property( + expression: exprResultProperty, + propertyName: "Token"); + + var delegateTokenProperty = Expression.Lambda( + body: exprTokenProperty, + parameters: new ParameterExpression[] + { + parameterExpression_Task, + }).Compile(); + + return new[] { delegateGetTokenAsync, delegateTokenProperty }; } } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index 6320272b9a..e8cec26dff 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -2,9 +2,6 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; using System.Threading; using System.Threading.Tasks; @@ -21,26 +18,20 @@ public TokenCredentialEnvelope(TokenCredential tokenCredential) this.tokenRequestContext = new TokenRequestContext(scopes: GetScopes()); } + /// public override object Credential => this.tokenCredential; + /// public override string GetToken(CancellationToken cancellationToken = default(CancellationToken)) { var accessToken = this.tokenCredential.GetToken(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); return accessToken.Token; } - /// - /// - /// - /// - /// You can also use the C# default(CancellationToken) statement to create an empty cancellation token. - /// Source: (https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.none). - /// - /// - /// + /// public override async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) { - var accessToken = await this.tokenCredential.GetTokenAsync(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); + var accessToken = await this.tokenCredential.GetTokenAsync(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken).ConfigureAwait(false); return accessToken.Token; } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 8dfa84c344..3f80365101 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -333,6 +333,11 @@ public string ConnectionString /// public TelemetrySink DefaultTelemetrySink => this.telemetrySinks.DefaultSink; + /// + /// Gets an envelope for Azure.Core.TokenCredential which provides an AAD Authenticated token. + /// + public CredentialEnvelope CredentialEnvelope { get; private set; } + /// /// Gets or sets the chain of processors. /// @@ -398,8 +403,10 @@ public void Dispose() GC.SuppressFinalize(this); } - public CredentialEnvelope CredentialEnvelope { get; private set; } - + /// + /// Set a TokenCredential for this configuration. + /// + /// An instance of Azure.Core.TokenCredential. #if NETSTANDARD2_0 public void SetCredential(Azure.Core.TokenCredential tokenCredential) => this.CredentialEnvelope = new TokenCredentialEnvelope(tokenCredential); #else From 76fd2d78bdaeeb9a1e31a06350434fa4c162fe85 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 31 Mar 2021 15:16:28 -0700 Subject: [PATCH 21/93] update scope --- .../Implementation/Authentication/CredentialEnvelope.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index 5bc326d2bf..9ffdee042f 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -1,5 +1,6 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { + using System; using System.Threading; using System.Threading.Tasks; @@ -9,9 +10,11 @@ public abstract class CredentialEnvelope { /// - /// Source: (https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). + /// Source: + /// (https://docs.microsoft.com/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). + /// (https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope). /// - private const string Scope = "https://monitor.azure.com"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. + private const string Scope = "https://monitor.azure.com//.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. /// /// Gets the TokenCredential object held by this class. From c5e44de7342d45dc90d24c6944f801eb10061d64 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 31 Mar 2021 15:58:10 -0700 Subject: [PATCH 22/93] save change to publicapi doc --- .../net46/PublicAPI.Unshipped.txt | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt index 61251cb65f..6b7fb8748a 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt @@ -1,20 +1,8 @@ -Microsoft.ApplicationInsights.Channel.Transmission.EndpointAddress.get -> Uri -Microsoft.ApplicationInsights.Channel.Transmission.Transmission(Uri address, System.Collections.Generic.ICollection telemetryItems, System.TimeSpan timeout = default(System.TimeSpan)) -> void -Microsoft.ApplicationInsights.Channel.Transmission.Transmission(Uri address, byte[] content, string contentType, string contentEncoding, System.TimeSpan timeout = default(System.TimeSpan)) -> void -Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Url.get -> Uri -Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.Url.get -> Uri -Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Url.get -> Uri Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void -Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Ingestion.get -> Uri -Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Live.get -> Uri -Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Profiler.get -> Uri -Microsoft.ApplicationInsights.Extensibility.Implementation.Endpoints.EndpointContainer.Snapshot.get -> Uri Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(object tokenCredential) -> void abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken) -> string abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task -static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] -virtual Microsoft.ApplicationInsights.Channel.Transmission.CreateRequest(Uri address) -> WebRequest -virtual Microsoft.ApplicationInsights.Channel.Transmission.CreateRequestMessage(Uri address, System.IO.Stream contentStream) -> System.Net.Http.HttpRequestMessage \ No newline at end of file +static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] \ No newline at end of file From 46f35e699c2e8b58b4eb055bcee3bcec762d566c Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 31 Mar 2021 16:09:00 -0700 Subject: [PATCH 23/93] cleanup --- .../Authentication/ReflectionCredentialEnvelope.cs | 6 ++++-- .../Authentication/TokenCredentialEnvelope.cs | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 418deeeecb..ae65f8a527 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -39,13 +39,13 @@ public ReflectionCredentialEnvelope(object tokenCredential) public override object Credential => this.tokenCredential; /// - public override string GetToken(CancellationToken cancellationToken = default(CancellationToken)) + public override string GetToken(CancellationToken cancellationToken = default) { return AzureCore.InvokeGetToken(this.tokenCredential, this.tokenRequestContext, cancellationToken); } /// - public override Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) + public override Task GetTokenAsync(CancellationToken cancellationToken = default) { return AzureCore.InvokeGetTokenAsync(this.tokenCredential, this.tokenRequestContext, cancellationToken); } @@ -64,6 +64,7 @@ internal static class AzureCore private static readonly Delegate GetTokenAsyncValue; private static readonly Delegate GetTokenProperty; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1810:Initialize reference type static fields inline", Justification = "For both optimization and readability, I'm building these objects in the same method.")] static AzureCore() { GetTokenValue = BuildDelegateGetToken(); @@ -141,6 +142,7 @@ private static Delegate BuildDelegateGetToken() /// First; /// The first Delegate is a wrapper around GetTokenAsync which returns a ValueTask of AccessToken. /// Then calls ValueTask.GetTask to convert that to a Task which is a known type for older frameworks. + /// This Task can be awaited. /// Second; /// The second Delegate is a wrapper around Task.Result which returns the AccessToken. /// Then calls AccessToken.Token to get the string token. diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index e8cec26dff..706b40ff1a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -22,14 +22,14 @@ public TokenCredentialEnvelope(TokenCredential tokenCredential) public override object Credential => this.tokenCredential; /// - public override string GetToken(CancellationToken cancellationToken = default(CancellationToken)) + public override string GetToken(CancellationToken cancellationToken = default) { var accessToken = this.tokenCredential.GetToken(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); return accessToken.Token; } /// - public override async Task GetTokenAsync(CancellationToken cancellationToken = default(CancellationToken)) + public override async Task GetTokenAsync(CancellationToken cancellationToken = default) { var accessToken = await this.tokenCredential.GetTokenAsync(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken).ConfigureAwait(false); return accessToken.Token; From dade2979d3d5cbac91081870f111e18bf835171e Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 5 Apr 2021 13:35:39 -0700 Subject: [PATCH 24/93] TokenCredential + QuickPulse --- .../Authentication/CredentialEnvelope.cs | 4 +- .../QuickPulse/QuickPulseServiceClient.cs | 15 ++- .../QuickPulse/QuickPulseServiceClient.cs | 15 ++- .../Mocks/QuickPulseServiceClientMock.cs | 2 + .../QuickPulseCollectionStateManagerTests.cs | 3 + .../QuickPulseServiceClientTests.cs | 110 ++++++++++-------- .../QuickPulse/IQuickPulseServiceClient.cs | 4 + .../QuickPulseCollectionStateManager.cs | 83 ++++--------- .../QuickPulseTelemetryModule.cs | 1 + 9 files changed, 119 insertions(+), 118 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index 9ffdee042f..2406ce823f 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -26,14 +26,14 @@ public abstract class CredentialEnvelope /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - public abstract string GetToken(CancellationToken cancellationToken); + public abstract string GetToken(CancellationToken cancellationToken = default); /// /// Gets an Azure.Core.AccessToken. /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - public abstract Task GetTokenAsync(CancellationToken cancellationToken); + public abstract Task GetTokenAsync(CancellationToken cancellationToken = default); /// /// Get scopes for Azure Monitor as an array. diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs index 26dbdbd3bd..bf01da0b6f 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -86,6 +86,7 @@ public Uri CurrentServiceUri DateTimeOffset timestamp, string configurationETag, string authApiKey, + string aadToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint) { @@ -100,6 +101,7 @@ public Uri CurrentServiceUri true, configurationETag, authApiKey, + aadToken, out configurationInfo, out servicePollingIntervalHint, requestStream => this.WritePingData(timestamp, requestStream)); @@ -110,6 +112,7 @@ public Uri CurrentServiceUri string instrumentationKey, string configurationETag, string authApiKey, + string aadToken, out CollectionConfigurationInfo configurationInfo, CollectionConfigurationError[] collectionConfigurationErrors) { @@ -124,6 +127,7 @@ public Uri CurrentServiceUri false, configurationETag, authApiKey, + aadToken, out configurationInfo, out _, requestStream => this.WriteSamples(samples, instrumentationKey, requestStream, collectionConfigurationErrors)); @@ -138,6 +142,7 @@ public void Dispose() bool includeIdentityHeaders, string configurationETag, string authApiKey, + string aadToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint, Action onWriteRequestBody) @@ -148,7 +153,7 @@ public void Dispose() request.Method = "POST"; request.Timeout = (int)this.timeout.TotalMilliseconds; - this.AddHeaders(request, includeIdentityHeaders, configurationETag, authApiKey); + this.AddHeaders(request, includeIdentityHeaders, configurationETag, authApiKey, aadToken); using (Stream requestStream = request.GetRequestStream()) { @@ -360,7 +365,7 @@ private static IEnumerable CreateDefaultMetrics(QuickPulseDataSampl }; } - private void AddHeaders(HttpWebRequest request, bool includeIdentityHeaders, string configurationETag, string authApiKey) + private void AddHeaders(HttpWebRequest request, bool includeIdentityHeaders, string configurationETag, string authApiKey, string aadToken) { request.Headers.Add(QuickPulseConstants.XMsQpsTransmissionTimeHeaderName, this.timeProvider.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture)); @@ -381,6 +386,12 @@ private void AddHeaders(HttpWebRequest request, bool includeIdentityHeaders, str request.Headers.Add(QuickPulseConstants.XMsQpsInvariantVersionHeaderName, MonitoringDataPoint.CurrentInvariantVersion.ToString(CultureInfo.InvariantCulture)); } + + // The AAD token is an optional feature. Only include if it is provided. + if (string.IsNullOrEmpty(aadToken)) + { + request.Headers.Add("x-aad-TODO", aadToken); //TODO: WHAT IS THE CORRECT HEADER NAKE? + } } } } \ No newline at end of file diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs index f0bee00ea0..31e3b90d60 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -92,6 +92,7 @@ public Uri CurrentServiceUri DateTimeOffset timestamp, string configurationETag, string authApiKey, + string aadToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint) { @@ -106,6 +107,7 @@ public Uri CurrentServiceUri true, configurationETag, authApiKey, + aadToken, out configurationInfo, out servicePollingIntervalHint, requestStream => this.WritePingData(timestamp, requestStream)); @@ -116,6 +118,7 @@ public Uri CurrentServiceUri string instrumentationKey, string configurationETag, string authApiKey, + string aadToken, out CollectionConfigurationInfo configurationInfo, CollectionConfigurationError[] collectionConfigurationErrors) { @@ -130,6 +133,7 @@ public Uri CurrentServiceUri false, configurationETag, authApiKey, + aadToken, out configurationInfo, out _, requestStream => this.WriteSamples(samples, instrumentationKey, requestStream, collectionConfigurationErrors)); @@ -146,6 +150,7 @@ public void Dispose() bool includeIdentityHeaders, string configurationETag, string authApiKey, + string aadToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint, Action onWriteRequestBody) @@ -154,7 +159,7 @@ public void Dispose() { using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri)) { - this.AddHeaders(request, includeIdentityHeaders, configurationETag, authApiKey); + this.AddHeaders(request, includeIdentityHeaders, configurationETag, authApiKey, aadToken); using (MemoryStream stream = new MemoryStream()) { @@ -389,7 +394,7 @@ private static IEnumerable CreateDefaultMetrics(QuickPulseDataSampl }; } - private void AddHeaders(HttpRequestMessage request, bool includeIdentityHeaders, string configurationETag, string authApiKey) + private void AddHeaders(HttpRequestMessage request, bool includeIdentityHeaders, string configurationETag, string authApiKey, string aadToken) { request.Headers.TryAddWithoutValidation(QuickPulseConstants.XMsQpsTransmissionTimeHeaderName, this.timeProvider.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture)); @@ -410,6 +415,12 @@ private void AddHeaders(HttpRequestMessage request, bool includeIdentityHeaders, request.Headers.TryAddWithoutValidation(QuickPulseConstants.XMsQpsInvariantVersionHeaderName, MonitoringDataPoint.CurrentInvariantVersion.ToString(CultureInfo.InvariantCulture)); } + + // The AAD token is an optional feature. Only include if it is provided. + if (string.IsNullOrEmpty(aadToken)) + { + request.Headers.TryAddWithoutValidation("x-aad-TODO", aadToken); //TODO: WHAT IS THE CORRECT HEADER NAKE? + } } private void Dispose(bool disposing) diff --git a/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/Mocks/QuickPulseServiceClientMock.cs b/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/Mocks/QuickPulseServiceClientMock.cs index 100fd9d196..4f408a1bc7 100644 --- a/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/Mocks/QuickPulseServiceClientMock.cs +++ b/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/Mocks/QuickPulseServiceClientMock.cs @@ -74,6 +74,7 @@ public void Reset() DateTimeOffset timestamp, string configurationETag, string authApiKey, + string aadToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint) { @@ -107,6 +108,7 @@ public void Reset() string instrumentationKey, string configurationETag, string authApiKey, + string aadToken, out CollectionConfigurationInfo configurationInfo, CollectionConfigurationError[] collectionConfigurationErrors) { diff --git a/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/QuickPulseCollectionStateManagerTests.cs b/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/QuickPulseCollectionStateManagerTests.cs index e487ba4fe7..91f77f7828 100644 --- a/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/QuickPulseCollectionStateManagerTests.cs +++ b/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/QuickPulseCollectionStateManagerTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; + using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility.Filtering; using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation; using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.Implementation.QuickPulse; @@ -54,6 +55,7 @@ public void QuickPulseCollectionStateManagerInitiallyInIdleState() var serviceClient = new QuickPulseServiceClientMock(); var manager = new QuickPulseCollectionStateManager( + TelemetryConfiguration.CreateDefault(), serviceClient, new Clock(), QuickPulseTimings.Default, @@ -726,6 +728,7 @@ private static QuickPulseCollectionStateManager CreateManager( List collectionConfigurationInfos = null) { var manager = new QuickPulseCollectionStateManager( + TelemetryConfiguration.CreateDefault(), serviceClient, timeProvider, timings ?? QuickPulseTimings.Default, diff --git a/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/QuickPulseServiceClientTests.cs b/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/QuickPulseServiceClientTests.cs index 04017b6239..9e7df19323 100644 --- a/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/QuickPulseServiceClientTests.cs +++ b/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/QuickPulseServiceClientTests.cs @@ -172,9 +172,9 @@ public void QuickPulseServiceClientPingsTheService() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping(string.Empty, timestamp, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); - serviceClient.Ping(string.Empty, timestamp, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); - serviceClient.Ping(string.Empty, timestamp, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping(string.Empty, timestamp, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); + serviceClient.Ping(string.Empty, timestamp, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); + serviceClient.Ping(string.Empty, timestamp, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 3); @@ -244,6 +244,7 @@ public void QuickPulseServiceClientSubmitsSamplesToService() string.Empty, string.Empty, string.Empty, + null, out configurationInfo, new CollectionConfigurationError[0]); @@ -319,6 +320,7 @@ public void QuickPulseServiceClientSetsTransmissionTimeCorrectly() string.Empty, string.Empty, string.Empty, + null, out configurationInfo, new CollectionConfigurationError[0]); @@ -362,7 +364,7 @@ public void QuickPulseServiceClientRoundsSampleValuesWhenSubmittingToService() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample1 }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample1 }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -412,7 +414,7 @@ public void QuickPulseServiceClientFillsInSampleWeightWhenSubmittingToService() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample1, sample2 }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample1, sample2 }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -486,7 +488,7 @@ public void QuickPulseServiceClientFillsInTelemetryDocumentsWhenSubmittingToServ // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -553,7 +555,7 @@ public void QuickPulseServiceClientFillsInGlobalDocumentQuotaReachedWhenSubmitti // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample1, sample2 }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample1, sample2 }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -581,7 +583,7 @@ public void QuickPulseServiceClientInterpretsPingResponseCorrectlyWhenHeaderTrue // ACT this.pingResponse = r => { r.Headers.Add(QuickPulseConstants.XMsQpsSubscribedHeaderName, true.ToString()); }; CollectionConfigurationInfo configurationInfo; - bool? response = serviceClient.Ping(string.Empty, DateTimeOffset.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + bool? response = serviceClient.Ping(string.Empty, DateTimeOffset.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -608,7 +610,7 @@ public void QuickPulseServiceClientInterpretsPingResponseCorrectlyWhenHeaderFals // ACT this.pingResponse = r => { r.Headers.Add(QuickPulseConstants.XMsQpsSubscribedHeaderName, false.ToString()); }; CollectionConfigurationInfo configurationInfo; - bool? response = serviceClient.Ping(string.Empty, DateTimeOffset.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + bool? response = serviceClient.Ping(string.Empty, DateTimeOffset.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -635,7 +637,7 @@ public void QuickPulseServiceClientInterpretsPingResponseCorrectlyWhenHeaderInva // ACT this.pingResponse = r => { r.Headers.Add(QuickPulseConstants.XMsQpsSubscribedHeaderName, "bla"); }; CollectionConfigurationInfo configurationInfo; - bool? response = serviceClient.Ping(string.Empty, DateTimeOffset.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + bool? response = serviceClient.Ping(string.Empty, DateTimeOffset.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -662,7 +664,7 @@ public void QuickPulseServiceClientInterpretsPingResponseCorrectlyWhenHeaderMiss // ACT this.pingResponse = r => { }; CollectionConfigurationInfo configurationInfo; - bool? response = serviceClient.Ping(string.Empty, DateTimeOffset.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + bool? response = serviceClient.Ping(string.Empty, DateTimeOffset.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -694,6 +696,7 @@ public void QuickPulseServiceClientInterpretsSubmitSamplesResponseCorrectlyWhenH string.Empty, string.Empty, string.Empty, + null, out configurationInfo, new CollectionConfigurationError[0]); @@ -727,6 +730,7 @@ public void QuickPulseServiceClientInterpretsSubmitSamplesResponseCorrectlyWhenH string.Empty, string.Empty, string.Empty, + null, out configurationInfo, new CollectionConfigurationError[0]); @@ -760,6 +764,7 @@ public void QuickPulseServiceClientInterpretsSubmitSamplesResponseCorrectlyWhenH string.Empty, string.Empty, string.Empty, + null, out configurationInfo, new CollectionConfigurationError[0]); @@ -793,6 +798,7 @@ public void QuickPulseServiceClientInterpretsSubmitSamplesResponseCorrectlyWhenH string.Empty, string.Empty, string.Empty, + null, out configurationInfo, new CollectionConfigurationError[0]); @@ -823,7 +829,7 @@ public void QuickPulseServiceClientDoesNotRetryPing() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping(string.Empty, DateTimeOffset.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping(string.Empty, DateTimeOffset.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -857,6 +863,7 @@ public void QuickPulseServiceClientDoesNotRetrySubmitSamples() string.Empty, string.Empty, string.Empty, + null, out configurationInfo, new CollectionConfigurationError[0]); @@ -900,7 +907,7 @@ public void QuickPulseServiceClientDoesNotReadCollectionConfigurationFromPingWhe // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping("ikey", now, "ETag1", string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping("ikey", now, "ETag1", string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -949,7 +956,7 @@ public void QuickPulseServiceClientDoesNotReadCollectionConfigurationFromPostWhe // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, "ETag1", string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, "ETag1", string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -991,7 +998,7 @@ public void QuickPulseServiceClientReadsCollectionConfigurationFromPingWhenETagI // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping("ikey", now, "ETag1", string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping("ikey", now, "ETag1", string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1042,7 +1049,7 @@ public void QuickPulseServiceClientReadsCollectionConfigurationFromPostWhenETagI // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, "ETag1", string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, "ETag1", string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1082,7 +1089,7 @@ public void QuickPulseServiceClientDoesNotReadCollectionConfigurationFromPingWhe // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping("ikey", now, "ETag2", string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping("ikey", now, "ETag2", string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1127,7 +1134,7 @@ public void QuickPulseServiceClientDoesNotReadCollectionConfigurationFromPostWhe // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, "ETag2", string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, "ETag2", string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1195,7 +1202,7 @@ public void QuickPulseServiceClientProducesCalculatedMetricsCorrectly() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, "ETag1", string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, "ETag1", string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1229,7 +1236,7 @@ public void QuickPulseServiceClientSubmitsRoleAndInstanceNameToServiceWithPing() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping(Guid.NewGuid().ToString(), DateTimeOffset.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping(Guid.NewGuid().ToString(), DateTimeOffset.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1258,7 +1265,7 @@ public void QuickPulseServiceClientSubmitsRoleNameWithNullValueValidation() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping(Guid.NewGuid().ToString(), DateTimeOffset.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping(Guid.NewGuid().ToString(), DateTimeOffset.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // ASSERT @@ -1293,7 +1300,7 @@ public void QuickPulseServiceClientSubmitsRoleAndInstanceNameToServiceWithSubmit // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1323,7 +1330,7 @@ public void QuickPulseServiceClientSubmitsStreamIdAndRoleNameToServiceWithPing() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping(Guid.NewGuid().ToString(), DateTimeOffset.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping(Guid.NewGuid().ToString(), DateTimeOffset.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1360,7 +1367,7 @@ public void QuickPulseServiceClientSubmitsStreamIdToServiceWithSubmitSamples() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1388,7 +1395,7 @@ public void QuickPulseServiceClientSubmitsMachineNameToServiceWithPing() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping(Guid.NewGuid().ToString(), DateTimeOffset.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping(Guid.NewGuid().ToString(), DateTimeOffset.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1424,7 +1431,7 @@ public void QuickPulseServiceClientSubmitsMachineNameToServiceWithSubmitSamples( // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1451,7 +1458,7 @@ public void QuickPulseServiceClientSubmitsInvariantVersionToServiceWithPing() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping(Guid.NewGuid().ToString(), DateTimeOffset.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping(Guid.NewGuid().ToString(), DateTimeOffset.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1486,7 +1493,7 @@ public void QuickPulseServiceClientSubmitsInvariantVersionToServiceWithSubmitSam // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1514,7 +1521,7 @@ public void QuickPulseServiceClientSubmitsTransmissionTimeToServiceWithPing() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping(Guid.NewGuid().ToString(), timeProvider.UtcNow, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping(Guid.NewGuid().ToString(), timeProvider.UtcNow, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1552,7 +1559,7 @@ public void QuickPulseServiceClientSubmitsTransmissionTimeToServiceWithSubmitSam // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1581,7 +1588,7 @@ public void QuickPulseServiceClientSubmitsVersionToServiceWithPing() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping("some ikey", now, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping("some ikey", now, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1616,7 +1623,7 @@ public void QuickPulseServiceClientSubmitsVersionToServiceWithSubmitSamples() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1646,7 +1653,7 @@ public void QuickPulseServiceClientSubmitsAuthApiKeyToServiceWithPing() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping("some ikey", now, string.Empty, authApiKey, out configurationInfo, out TimeSpan? _); + serviceClient.Ping("some ikey", now, string.Empty, authApiKey, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1681,7 +1688,7 @@ public void QuickPulseServiceClientSubmitsAuthApiKeyToServiceWithSubmitSamples() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, authApiKey, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, authApiKey, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1714,10 +1721,10 @@ public void QuickPulseServiceClientResubmitsAuthOpaqueHeadersToServiceWithPing() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.Ping("some ikey", now, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping("some ikey", now, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // received the proper headers, now re-submit them - serviceClient.Ping("some ikey", now, string.Empty, string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.Ping("some ikey", now, string.Empty, string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 2); @@ -1761,10 +1768,10 @@ public void QuickPulseServiceClientResubmitsAuthOpaqueHeadersToServiceWithSubmit // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // received the proper headers, now re-submit them - serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 2); @@ -1802,8 +1809,8 @@ public void QuickPulseServiceClientSubmitsCollectionConfigurationETagToService() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, string.Empty, "ETag1", string.Empty, out configurationInfo, new CollectionConfigurationError[0]); - serviceClient.Ping(string.Empty, now, "ETag1", string.Empty, out configurationInfo, out TimeSpan? _); + serviceClient.SubmitSamples(new[] { sample }, string.Empty, "ETag1", string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.Ping(string.Empty, now, "ETag1", string.Empty, null, out configurationInfo, out TimeSpan? _); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1855,6 +1862,7 @@ public void QuickPulseServiceClientSubmitsCollectionConfigurationErrorsToService string.Empty, string.Empty, string.Empty, + null, out configurationInfo, collectionConfigurationErrors); @@ -1902,7 +1910,7 @@ public void QuickPulseServiceClientSubmitsInstrumentationKeyToService() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, ikey, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, ikey, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1937,7 +1945,7 @@ public void QuickPulseServiceClientSubmitsIsWebAppToService() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, ikey, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, ikey, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -1972,7 +1980,7 @@ public void QuickPulseServiceClientSubmitsProcessorCountToService() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, ikey, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, ikey, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -2009,7 +2017,7 @@ public void QuickPulseServiceClientSubmitsTopCpuProcessesToService() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, ikey, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, ikey, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -2049,7 +2057,7 @@ public void QuickPulseServiceClientSubmitsTopCpuProcessesAccessDeniedToService() // ACT CollectionConfigurationInfo configurationInfo; - serviceClient.SubmitSamples(new[] { sample }, ikey, string.Empty, string.Empty, out configurationInfo, new CollectionConfigurationError[0]); + serviceClient.SubmitSamples(new[] { sample }, ikey, string.Empty, string.Empty, null, out configurationInfo, new CollectionConfigurationError[0]); // SYNC this.WaitForProcessing(requestCount: 1); @@ -2083,7 +2091,7 @@ public void QuickPulseServiceClientReturnsServicePollingIntervalHintWhenValid() }; // ACT - serviceClient.Ping("ikey", now, string.Empty, string.Empty, out _, out TimeSpan? servicePollingIntervalHint); + serviceClient.Ping("ikey", now, string.Empty, string.Empty, null, out _, out TimeSpan? servicePollingIntervalHint); // ASSERT Assert.AreEqual(TimeSpan.FromMilliseconds(ms), servicePollingIntervalHint); @@ -2112,7 +2120,7 @@ public void QuickPulseServiceClientReturnsNullForServicePollingIntervalHintWhenN }; // ACT - serviceClient.Ping("ikey", now, string.Empty, string.Empty, out _, out TimeSpan? servicePollingIntervalHint); + serviceClient.Ping("ikey", now, string.Empty, string.Empty, null, out _, out TimeSpan? servicePollingIntervalHint); // ASSERT Assert.IsNull(servicePollingIntervalHint); @@ -2141,7 +2149,7 @@ public void QuickPulseServiceClientReturnsNullForServicePollingIntervalHintWhenE }; // ACT - serviceClient.Ping("ikey", now, string.Empty, string.Empty, out _, out TimeSpan? servicePollingIntervalHint); + serviceClient.Ping("ikey", now, string.Empty, string.Empty, null, out _, out TimeSpan? servicePollingIntervalHint); // ASSERT Assert.IsNull(servicePollingIntervalHint); @@ -2171,7 +2179,7 @@ public void QuickPulseServiceClientUpdatesServiceEndpointWhenRedirectValid() }; // ACT - serviceClient.Ping("ikey", now, string.Empty, string.Empty, out _, out _); + serviceClient.Ping("ikey", now, string.Empty, string.Empty, null, out _, out _); // SYNC this.WaitForProcessing(1); @@ -2205,7 +2213,7 @@ public void QuickPulseServiceClientIgnoresServiceEndpointWhenRedirectInvalid() }; // ACT - serviceClient.Ping("ikey", now, string.Empty, string.Empty, out _, out _); + serviceClient.Ping("ikey", now, string.Empty, string.Empty, null, out _, out _); // SYNC this.WaitForProcessing(1); @@ -2239,7 +2247,7 @@ public void QuickPulseServiceClientIgnoresServiceEndpointWhenRedirectEmpty() }; // ACT - serviceClient.Ping("ikey", now, string.Empty, string.Empty, out _, out _); + serviceClient.Ping("ikey", now, string.Empty, string.Empty, null, out _, out _); // SYNC this.WaitForProcessing(1); diff --git a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs index eca3bc915c..363c7555e1 100644 --- a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs @@ -20,6 +20,7 @@ internal interface IQuickPulseServiceClient : IDisposable /// Timestamp to pass to the server. /// Current configuration ETag that the client has. /// Authentication API key. + /// /// When available, the deserialized response data received from the server. /// When available, a hint regarding what the period should be when pinging the server going forward. /// true if data is expected, otherwise false. @@ -28,6 +29,7 @@ internal interface IQuickPulseServiceClient : IDisposable DateTimeOffset timestamp, string configurationETag, string authApiKey, + string aadToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint); @@ -38,6 +40,7 @@ internal interface IQuickPulseServiceClient : IDisposable /// InstrumentationKey for which to submit data samples. /// Current configuration ETag that the client has. /// Authentication API key. + /// /// When available, the deserialized response data received from the server. /// Errors to be reported back to the server. /// true if the client is expected to keep sending data samples, false otherwise. @@ -46,6 +49,7 @@ internal interface IQuickPulseServiceClient : IDisposable string instrumentationKey, string configurationETag, string authApiKey, + string aadToken, out CollectionConfigurationInfo configurationInfo, CollectionConfigurationError[] collectionConfigurationErrors); } diff --git a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseCollectionStateManager.cs b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseCollectionStateManager.cs index 039b5e508e..3786521fd3 100644 --- a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseCollectionStateManager.cs +++ b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseCollectionStateManager.cs @@ -34,6 +34,8 @@ internal class QuickPulseCollectionStateManager private readonly List collectionConfigurationErrors = new List(); + private readonly TelemetryConfiguration telemetryConfiguration; + private DateTimeOffset lastSuccessfulPing; private DateTimeOffset lastSuccessfulSubmit; @@ -47,70 +49,27 @@ internal class QuickPulseCollectionStateManager private TimeSpan? latestServicePollingIntervalHint = null; public QuickPulseCollectionStateManager( - IQuickPulseServiceClient serviceClient, - Clock timeProvider, - QuickPulseTimings timings, - Action onStartCollection, - Action onStopCollection, - Func> onSubmitSamples, + TelemetryConfiguration telemetryConfiguration, + IQuickPulseServiceClient serviceClient, + Clock timeProvider, + QuickPulseTimings timings, + Action onStartCollection, + Action onStopCollection, + Func> onSubmitSamples, Action> onReturnFailedSamples, Func onUpdatedConfiguration, Action onUpdatedServiceEndpoint) { - if (serviceClient == null) - { - throw new ArgumentNullException(nameof(serviceClient)); - } - - if (timeProvider == null) - { - throw new ArgumentNullException(nameof(timeProvider)); - } - - if (timings == null) - { - throw new ArgumentNullException(nameof(timings)); - } - - if (onStartCollection == null) - { - throw new ArgumentNullException(nameof(onStartCollection)); - } - - if (onStopCollection == null) - { - throw new ArgumentNullException(nameof(onStopCollection)); - } - - if (onSubmitSamples == null) - { - throw new ArgumentNullException(nameof(onSubmitSamples)); - } - - if (onReturnFailedSamples == null) - { - throw new ArgumentNullException(nameof(onReturnFailedSamples)); - } - - if (onUpdatedConfiguration == null) - { - throw new ArgumentNullException(nameof(onUpdatedConfiguration)); - } - - if (onUpdatedServiceEndpoint == null) - { - throw new ArgumentNullException(nameof(onUpdatedServiceEndpoint)); - } - - this.serviceClient = serviceClient; - this.timeProvider = timeProvider; - this.timings = timings; - this.onStartCollection = onStartCollection; - this.onStopCollection = onStopCollection; - this.onSubmitSamples = onSubmitSamples; - this.onReturnFailedSamples = onReturnFailedSamples; - this.onUpdatedConfiguration = onUpdatedConfiguration; - this.onUpdatedServiceEndpoint = onUpdatedServiceEndpoint; + this.telemetryConfiguration = telemetryConfiguration ?? throw new ArgumentNullException(nameof(telemetryConfiguration)); + this.serviceClient = serviceClient ?? throw new ArgumentNullException(nameof(serviceClient)); + this.timeProvider = timeProvider ?? throw new ArgumentNullException(nameof(timeProvider)); + this.timings = timings ?? throw new ArgumentNullException(nameof(timings)); + this.onStartCollection = onStartCollection ?? throw new ArgumentNullException(nameof(onStartCollection)); + this.onStopCollection = onStopCollection ?? throw new ArgumentNullException(nameof(onStopCollection)); + this.onSubmitSamples = onSubmitSamples ?? throw new ArgumentNullException(nameof(onSubmitSamples)); + this.onReturnFailedSamples = onReturnFailedSamples ?? throw new ArgumentNullException(nameof(onReturnFailedSamples)); + this.onUpdatedConfiguration = onUpdatedConfiguration ?? throw new ArgumentNullException(nameof(onUpdatedConfiguration)); + this.onUpdatedServiceEndpoint = onUpdatedServiceEndpoint ?? throw new ArgumentNullException(nameof(onUpdatedServiceEndpoint)); this.coolDownTimeout = TimeSpan.FromMilliseconds(timings.CollectionInterval.TotalMilliseconds / 20); } @@ -179,8 +138,9 @@ public TimeSpan UpdateState(string instrumentationKey, string authApiKey) instrumentationKey, this.currentConfigurationETag, authApiKey, + this.telemetryConfiguration.CredentialEnvelope?.GetToken(), out configurationInfo, - this.collectionConfigurationErrors.ToArray()); + this.collectionConfigurationErrors.ToArray()); ; QuickPulseEventSource.Log.SampleSubmittedEvent(this.currentConfigurationETag, configurationInfo?.ETag, keepCollecting.ToString()); @@ -213,6 +173,7 @@ public TimeSpan UpdateState(string instrumentationKey, string authApiKey) this.timeProvider.UtcNow, this.currentConfigurationETag, authApiKey, + this.telemetryConfiguration.CredentialEnvelope?.GetToken(), out configurationInfo, out TimeSpan? servicePollingIntervalHint); diff --git a/WEB/Src/PerformanceCollector/PerformanceCollector/QuickPulseTelemetryModule.cs b/WEB/Src/PerformanceCollector/PerformanceCollector/QuickPulseTelemetryModule.cs index 043cd35915..2c5a832ad0 100644 --- a/WEB/Src/PerformanceCollector/PerformanceCollector/QuickPulseTelemetryModule.cs +++ b/WEB/Src/PerformanceCollector/PerformanceCollector/QuickPulseTelemetryModule.cs @@ -195,6 +195,7 @@ public void Initialize(TelemetryConfiguration configuration) this.InitializeServiceClient(configuration); this.stateManager = new QuickPulseCollectionStateManager( + configuration, this.ServiceClient, this.timeProvider, this.timings, From 246412575683557b114405fd2192053c9539ce1c Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 5 Apr 2021 13:39:55 -0700 Subject: [PATCH 25/93] set default in abstract class --- .../Implementation/Authentication/CredentialEnvelope.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index 9ffdee042f..2406ce823f 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -26,14 +26,14 @@ public abstract class CredentialEnvelope /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - public abstract string GetToken(CancellationToken cancellationToken); + public abstract string GetToken(CancellationToken cancellationToken = default); /// /// Gets an Azure.Core.AccessToken. /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - public abstract Task GetTokenAsync(CancellationToken cancellationToken); + public abstract Task GetTokenAsync(CancellationToken cancellationToken = default); /// /// Get scopes for Azure Monitor as an array. From c387eaa2de3ee9509c1c1fd1f4e801d5fd3ceac2 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 8 Apr 2021 13:56:50 -0700 Subject: [PATCH 26/93] update header key --- .../Implementation/QuickPulse/QuickPulseServiceClient.cs | 2 +- .../Implementation/QuickPulse/QuickPulseServiceClient.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs index bf01da0b6f..c6a74733db 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -390,7 +390,7 @@ private void AddHeaders(HttpWebRequest request, bool includeIdentityHeaders, str // The AAD token is an optional feature. Only include if it is provided. if (string.IsNullOrEmpty(aadToken)) { - request.Headers.Add("x-aad-TODO", aadToken); //TODO: WHAT IS THE CORRECT HEADER NAKE? + request.Headers.Add("authorization", "Bearer " + aadToken); //TODO: WHAT IS THE CORRECT HEADER NAKE? } } } diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs index 31e3b90d60..4735204a61 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -419,7 +419,7 @@ private void AddHeaders(HttpRequestMessage request, bool includeIdentityHeaders, // The AAD token is an optional feature. Only include if it is provided. if (string.IsNullOrEmpty(aadToken)) { - request.Headers.TryAddWithoutValidation("x-aad-TODO", aadToken); //TODO: WHAT IS THE CORRECT HEADER NAKE? + request.Headers.TryAddWithoutValidation("authorization", "Bearer " + aadToken); //TODO: WHAT IS THE CORRECT HEADER NAKE? } } From 9f5e5798b25a76ed88038eb9505a97cf78573cd8 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 9 Apr 2021 16:40:52 -0700 Subject: [PATCH 27/93] finished mapping out how to set CredentialEnvelope on all TelemetryChannels and QuickPulseModule. Need to write tests. --- .../net452/PublicAPI.Unshipped.txt | 2 ++ .../netstandard2.0/PublicAPI.Unshipped.txt | 2 ++ .../net452/PublicAPI.Unshipped.txt | 11 +++++-- .../net46/PublicAPI.Unshipped.txt | 11 +++++-- .../netstandard2.0/PublicAPI.Unshipped.txt | 11 +++++-- .../Channel/InMemoryChannel.cs | 20 ++++++++++++- .../Channel/InMemoryTransmitter.cs | 12 +++++++- .../Channel/Transmission.cs | 15 ++++++++++ .../ISupportCredentialEnvelope.cs | 19 ++++++++++++ .../Extensibility/TelemetryConfiguration.cs | 29 +++++++++++++++++-- .../Implementation/TransmissionSender.cs | 11 +++++++ .../Implementation/Transmitter.cs | 16 +++++++++- .../ServerTelemetryChannel.cs | 20 ++++++++++++- .../QuickPulse/QuickPulseServiceClient.cs | 2 +- .../QuickPulse/QuickPulseServiceClient.cs | 2 +- .../QuickPulse/IQuickPulseServiceClient.cs | 4 +-- .../QuickPulseCollectionStateManager.cs | 2 +- 17 files changed, 172 insertions(+), 17 deletions(-) create mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs diff --git a/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/net452/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/net452/PublicAPI.Unshipped.txt index e69de29bb2..4c1342ab20 100644 --- a/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/net452/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/net452/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.CredentialEnvelope.set -> void \ No newline at end of file diff --git a/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/netstandard2.0/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..4c1342ab20 100644 --- a/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/netstandard2.0/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.CredentialEnvelope.set -> void \ No newline at end of file diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt index 6b7fb8748a..860649320e 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt @@ -1,8 +1,15 @@ +Microsoft.ApplicationInsights.Channel.InMemoryChannel.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Channel.InMemoryChannel.CredentialEnvelope.set -> void +Microsoft.ApplicationInsights.Channel.Transmission.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Channel.Transmission.CredentialEnvelope.set -> void Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ISupportCredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ISupportCredentialEnvelope.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ISupportCredentialEnvelope.CredentialEnvelope.set -> void Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(object tokenCredential) -> void abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken) -> string -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] \ No newline at end of file diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt index 6b7fb8748a..860649320e 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt @@ -1,8 +1,15 @@ +Microsoft.ApplicationInsights.Channel.InMemoryChannel.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Channel.InMemoryChannel.CredentialEnvelope.set -> void +Microsoft.ApplicationInsights.Channel.Transmission.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Channel.Transmission.CredentialEnvelope.set -> void Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ISupportCredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ISupportCredentialEnvelope.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ISupportCredentialEnvelope.CredentialEnvelope.set -> void Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(object tokenCredential) -> void abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken) -> string -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] \ No newline at end of file diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt index 9aae3d025d..a7f0a4b98c 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,8 +1,15 @@ +Microsoft.ApplicationInsights.Channel.InMemoryChannel.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Channel.InMemoryChannel.CredentialEnvelope.set -> void +Microsoft.ApplicationInsights.Channel.Transmission.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Channel.Transmission.CredentialEnvelope.set -> void Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ISupportCredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ISupportCredentialEnvelope.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ISupportCredentialEnvelope.CredentialEnvelope.set -> void Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(Azure.Core.TokenCredential tokenCredential) -> void abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken) -> string -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] \ No newline at end of file diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs index 321a64ac4b..15ab9d92ba 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs @@ -1,15 +1,18 @@ namespace Microsoft.ApplicationInsights.Channel { using System; + using System.ComponentModel; using System.Diagnostics; using Microsoft.ApplicationInsights.Common; + using Microsoft.ApplicationInsights.Extensibility; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; /// /// Represents a communication channel for sending telemetry to Application Insights via HTTPS. There will be a buffer that will not be persisted, to enforce the /// queued telemetry items to be sent, should be called. /// - public class InMemoryChannel : ITelemetryChannel + public class InMemoryChannel : ITelemetryChannel, ISupportCredentialEnvelope { private readonly TelemetryBuffer buffer; private readonly InMemoryTransmitter transmitter; @@ -90,6 +93,21 @@ public TimeSpan SendingInterval } } + /// + /// Gets or sets the which is used for AAD. + /// FOR INTERNAL USE. Customers should use instead. + /// + /// + /// sets + /// which is used to set just before calling . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public CredentialEnvelope CredentialEnvelope + { + get => this.transmitter.CredentialEnvelope; + set => this.transmitter.CredentialEnvelope = value; + } + /// /// Gets or sets the HTTP address where the telemetry is sent. /// diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs index 9c80f20676..24e6af07bd 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs @@ -14,6 +14,7 @@ namespace Microsoft.ApplicationInsights.Channel using Microsoft.ApplicationInsights.Common.Extensions; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility.Implementation; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; /// @@ -63,6 +64,15 @@ internal TimeSpan SendingInterval set { this.sendingInterval = value; } } + /// + /// Gets or sets the which is used for AAD. + /// + /// + /// sets + /// which is used to set just before calling . + /// + internal CredentialEnvelope CredentialEnvelope { get; set; } + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// @@ -163,7 +173,7 @@ private Task Send(IEnumerable telemetryItems, TimeSpan timeout) } var transmission = new Transmission(this.EndpointAddress, data, JsonSerializer.ContentType, JsonSerializer.CompressionType, timeout); - + transmission.CredentialEnvelope = this.CredentialEnvelope; return transmission.SendAsync(); } diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index 100e165b3b..89f7ea3ead 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -2,6 +2,7 @@ { using System; using System.Collections.Generic; + using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Net; @@ -10,6 +11,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.ApplicationInsights.Extensibility.Implementation; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; /// @@ -139,6 +141,13 @@ public ICollection TelemetryItems get; private set; } + /// + /// Gets or sets the . + /// This is used include an AAD token on HTTP Requests sent to ingestion. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public CredentialEnvelope CredentialEnvelope { get; set; } + /// /// Executes the request that the current transmission represents. /// @@ -378,6 +387,12 @@ protected virtual HttpRequestMessage CreateRequestMessage(Uri address, Stream co request.Content.Headers.Add(ContentEncodingHeader, this.ContentEncoding); } + if (this.CredentialEnvelope != null) + { + var aadToken = this.CredentialEnvelope.GetToken(); + request.Content.Headers.Add("authorization", "Bearer " + aadToken); // TODO: WHAT IS THE CORRECT HEADER NAKE? + } + return request; } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs new file mode 100644 index 0000000000..3a79b29bbb --- /dev/null +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs @@ -0,0 +1,19 @@ +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + /// + /// This interface defines a class that accepts the as a property. + /// + public interface ISupportCredentialEnvelope + { + /// + /// Gets or sets the . + /// + CredentialEnvelope CredentialEnvelope { get; set; } + } +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 3f80365101..8da1e5df83 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -240,6 +240,7 @@ public ITelemetryChannel TelemetryChannel { this.telemetrySinks.DefaultSink.TelemetryChannel = value; SetTelemetryChannelEndpoint(this.telemetrySinks.DefaultSink.TelemetryChannel, this.EndpointContainer.FormattedIngestionEndpoint); + SetTelemetryChannelCredentialEnvelope(value, this.CredentialEnvelope); } } } @@ -408,9 +409,17 @@ public void Dispose() /// /// An instance of Azure.Core.TokenCredential. #if NETSTANDARD2_0 - public void SetCredential(Azure.Core.TokenCredential tokenCredential) => this.CredentialEnvelope = new TokenCredentialEnvelope(tokenCredential); + public void SetCredential(Azure.Core.TokenCredential tokenCredential) + { + this.CredentialEnvelope = new TokenCredentialEnvelope(tokenCredential); + this.SetTelemetryChannelCredentialEnvelope(); + } #else - public void SetCredential(object tokenCredential) => this.CredentialEnvelope = new ReflectionCredentialEnvelope(tokenCredential); + public void SetCredential(object tokenCredential) + { + this.CredentialEnvelope = new ReflectionCredentialEnvelope(tokenCredential); + this.SetTelemetryChannelCredentialEnvelope(); + } #endif internal MetricManager GetMetricManager(bool createIfNotExists) @@ -489,6 +498,22 @@ private static void SetTelemetryChannelEndpoint(ITelemetryChannel channel, strin } } + private static void SetTelemetryChannelCredentialEnvelope(ITelemetryChannel telemetryChannel, CredentialEnvelope credentialEnvelope) + { + if (telemetryChannel is ISupportCredentialEnvelope tc) + { + tc.CredentialEnvelope = credentialEnvelope; + } + } + + private void SetTelemetryChannelCredentialEnvelope() + { + foreach (var tSink in this.TelemetrySinks) + { + SetTelemetryChannelCredentialEnvelope(tSink.TelemetryChannel, this.CredentialEnvelope); + } + } + /// /// Disposes of resources. /// diff --git a/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs b/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs index 21e076167a..e3e912c538 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs @@ -11,6 +11,7 @@ using Microsoft.ApplicationInsights.Common.Extensions; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility.Implementation; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; internal class TransmissionSender { @@ -101,6 +102,15 @@ public virtual int ThrottleWindow } } + /// + /// Gets or sets the which is used for AAD. + /// + /// + /// sets and then sets + /// which is used to set just before calling . + /// + public CredentialEnvelope CredentialEnvelope { get; set; } + public virtual bool Enqueue(Func transmissionGetter) { bool enqueueSucceded = false; @@ -155,6 +165,7 @@ private async Task StartSending(Transmission transmission) try { TelemetryChannelEventSource.Log.TransmissionSendStarted(acceptedTransmission.Id); + acceptedTransmission.CredentialEnvelope = this.CredentialEnvelope; responseContent = await acceptedTransmission.SendAsync().ConfigureAwait(false); } catch (Exception e) diff --git a/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs b/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs index 04b387e200..cc62dbc53c 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs @@ -6,6 +6,7 @@ using System.Linq; using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.Channel.Implementation; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; /// /// Implements throttled and persisted transmission of telemetry to Application Insights. @@ -55,7 +56,20 @@ internal Transmitter( public event EventHandler TransmissionSent; - public string StorageFolder { get; set; } + public string StorageFolder { get; set; } + + /// + /// Gets or sets the which is used for AAD. + /// + /// + /// sets and then sets + /// which is used to set just before calling . + /// + public CredentialEnvelope CredentialEnvelope + { + get => this.Sender.CredentialEnvelope; + set => this.Sender.CredentialEnvelope = value; + } public int MaxBufferCapacity { diff --git a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs index b58398c91a..3d892c16b4 100644 --- a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs +++ b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs @@ -8,12 +8,13 @@ using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.Common; using Microsoft.ApplicationInsights.Extensibility; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.Implementation; /// /// Represents a communication channel for sending telemetry to Application Insights via HTTP/S. /// - public sealed class ServerTelemetryChannel : ITelemetryChannel, ITelemetryModule + public sealed class ServerTelemetryChannel : ITelemetryChannel, ITelemetryModule, ISupportCredentialEnvelope { internal TelemetrySerializer TelemetrySerializer; internal TelemetryBuffer TelemetryBuffer; @@ -241,6 +242,21 @@ public int LocalThrottleWindow set { this.Transmitter.ThrottleWindow = value; } } + /// + /// Gets or sets the which is used for AAD. + /// DO NOT SET DIRECTLY. Use instead. + /// + /// + /// sets and then sets + /// which is used to set just before calling . + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public CredentialEnvelope CredentialEnvelope + { + get => this.Transmitter.CredentialEnvelope; + set => this.Transmitter.CredentialEnvelope = value; + } + /// /// Gets or sets first TelemetryProcessor in processor call chain. /// @@ -337,6 +353,8 @@ public void Initialize(TelemetryConfiguration configuration) throw new ArgumentNullException(nameof(configuration)); } + this.CredentialEnvelope = configuration.CredentialEnvelope; + this.Transmitter.Initialize(); if (this.EndpointAddress == null) diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs index c6a74733db..ecac6d47d0 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -390,7 +390,7 @@ private void AddHeaders(HttpWebRequest request, bool includeIdentityHeaders, str // The AAD token is an optional feature. Only include if it is provided. if (string.IsNullOrEmpty(aadToken)) { - request.Headers.Add("authorization", "Bearer " + aadToken); //TODO: WHAT IS THE CORRECT HEADER NAKE? + request.Headers.Add("authorization", "Bearer " + aadToken); // TODO: WHAT IS THE CORRECT HEADER NAKE? } } } diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs index 4735204a61..1351f0dac6 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -419,7 +419,7 @@ private void AddHeaders(HttpRequestMessage request, bool includeIdentityHeaders, // The AAD token is an optional feature. Only include if it is provided. if (string.IsNullOrEmpty(aadToken)) { - request.Headers.TryAddWithoutValidation("authorization", "Bearer " + aadToken); //TODO: WHAT IS THE CORRECT HEADER NAKE? + request.Headers.TryAddWithoutValidation("authorization", "Bearer " + aadToken); // TODO: WHAT IS THE CORRECT HEADER NAKE? } } diff --git a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs index 363c7555e1..7e3f9ca012 100644 --- a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs @@ -20,7 +20,7 @@ internal interface IQuickPulseServiceClient : IDisposable /// Timestamp to pass to the server. /// Current configuration ETag that the client has. /// Authentication API key. - /// + /// AAD token to be included on Http messages. /// When available, the deserialized response data received from the server. /// When available, a hint regarding what the period should be when pinging the server going forward. /// true if data is expected, otherwise false. @@ -40,7 +40,7 @@ internal interface IQuickPulseServiceClient : IDisposable /// InstrumentationKey for which to submit data samples. /// Current configuration ETag that the client has. /// Authentication API key. - /// + /// AAD token to be included on Http messages. /// When available, the deserialized response data received from the server. /// Errors to be reported back to the server. /// true if the client is expected to keep sending data samples, false otherwise. diff --git a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseCollectionStateManager.cs b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseCollectionStateManager.cs index 3786521fd3..5d1d754526 100644 --- a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseCollectionStateManager.cs +++ b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseCollectionStateManager.cs @@ -140,7 +140,7 @@ public TimeSpan UpdateState(string instrumentationKey, string authApiKey) authApiKey, this.telemetryConfiguration.CredentialEnvelope?.GetToken(), out configurationInfo, - this.collectionConfigurationErrors.ToArray()); ; + this.collectionConfigurationErrors.ToArray()); QuickPulseEventSource.Log.SampleSubmittedEvent(this.currentConfigurationETag, configurationInfo?.ETag, keepCollecting.ToString()); From f2ac1d891caf365f1a55e1a1b8b71f2e64ff2c9d Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Tue, 13 Apr 2021 16:26:57 -0700 Subject: [PATCH 28/93] update request header. move to constants --- .../Channel/Transmission.cs | 2 +- .../Implementation/Authentication/AuthConstants.cs | 9 +++++++++ .../Implementation/QuickPulse/QuickPulseServiceClient.cs | 2 +- .../Implementation/QuickPulse/QuickPulseServiceClient.cs | 2 +- .../Implementation/QuickPulse/QuickPulseConstants.cs | 4 ++++ 5 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index 89f7ea3ead..134bf96005 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -390,7 +390,7 @@ protected virtual HttpRequestMessage CreateRequestMessage(Uri address, Stream co if (this.CredentialEnvelope != null) { var aadToken = this.CredentialEnvelope.GetToken(); - request.Content.Headers.Add("authorization", "Bearer " + aadToken); // TODO: WHAT IS THE CORRECT HEADER NAKE? + request.Content.Headers.Add(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + aadToken); } return request; diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs new file mode 100644 index 0000000000..3c7968a117 --- /dev/null +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs @@ -0,0 +1,9 @@ +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +{ + internal static class AuthConstants + { + public const string AuthorizationHeaderName = "Authorization"; + + public const string AuthorizationTokenPrefix = "Bearer "; + } +} diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs index ecac6d47d0..04b8f62929 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -390,7 +390,7 @@ private void AddHeaders(HttpWebRequest request, bool includeIdentityHeaders, str // The AAD token is an optional feature. Only include if it is provided. if (string.IsNullOrEmpty(aadToken)) { - request.Headers.Add("authorization", "Bearer " + aadToken); // TODO: WHAT IS THE CORRECT HEADER NAKE? + request.Headers.Add(QuickPulseConstants.AuthorizationHeaderName, QuickPulseConstants.AuthorizationTokenPrefix + aadToken); } } } diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs index 1351f0dac6..acc170306d 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -419,7 +419,7 @@ private void AddHeaders(HttpRequestMessage request, bool includeIdentityHeaders, // The AAD token is an optional feature. Only include if it is provided. if (string.IsNullOrEmpty(aadToken)) { - request.Headers.TryAddWithoutValidation("authorization", "Bearer " + aadToken); // TODO: WHAT IS THE CORRECT HEADER NAKE? + request.Headers.TryAddWithoutValidation(QuickPulseConstants.AuthorizationHeaderName, QuickPulseConstants.AuthorizationTokenPrefix + aadToken); } } diff --git a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseConstants.cs b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseConstants.cs index b7c0e965a1..fd0bf96070 100644 --- a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseConstants.cs +++ b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/QuickPulseConstants.cs @@ -5,6 +5,10 @@ /// internal static class QuickPulseConstants { + internal const string AuthorizationHeaderName = "Authorization"; + + internal const string AuthorizationTokenPrefix = "Bearer "; + /// /// Subscribed header. /// From 159bbc9b23b4333b0b9a9eb66e0e2b26f85aafb5 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 14 Apr 2021 15:00:41 -0700 Subject: [PATCH 29/93] update publicapi --- .../net452/PublicAPI.Unshipped.txt | 4 ++-- .../net46/PublicAPI.Unshipped.txt | 4 ++-- .../netstandard2.0/PublicAPI.Unshipped.txt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt index 6b7fb8748a..cfb4fd9019 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt @@ -3,6 +3,6 @@ Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.Creden Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(object tokenCredential) -> void abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken) -> string -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] \ No newline at end of file diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt index 6b7fb8748a..cfb4fd9019 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt @@ -3,6 +3,6 @@ Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.Creden Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(object tokenCredential) -> void abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken) -> string -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] \ No newline at end of file diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt index 9aae3d025d..b26f1be83c 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt @@ -3,6 +3,6 @@ Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.Creden Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(Azure.Core.TokenCredential tokenCredential) -> void abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken) -> string -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] \ No newline at end of file From d43a0a615e258cf693da1e06ba51c8e512632667 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 14 Apr 2021 17:18:28 -0700 Subject: [PATCH 30/93] sample app and some minor fixes --- .../Authentication/CredentialEnvelope.cs | 2 +- Everything.sln | 8 +- NETCORE/ApplicationInsights.AspNetCore.sln | 10 ++- SampleApp/Controllers/HomeController.cs | 47 ++++++++++++ SampleApp/Models/ErrorViewModel.cs | 11 +++ SampleApp/Program.cs | 27 +++++++ SampleApp/Properties/launchSettings.json | 28 +++++++ SampleApp/SampleApp.csproj | 17 +++++ SampleApp/Startup.cs | 70 ++++++++++++++++++ SampleApp/Views/Home/Index.cshtml | 8 ++ SampleApp/Views/Home/Privacy.cshtml | 6 ++ SampleApp/Views/Shared/Error.cshtml | 25 +++++++ SampleApp/Views/Shared/_Layout.cshtml | 48 ++++++++++++ .../Shared/_ValidationScriptsPartial.cshtml | 2 + SampleApp/Views/_ViewImports.cshtml | 3 + SampleApp/Views/_ViewStart.cshtml | 3 + SampleApp/appsettings.Development.json | 9 +++ SampleApp/appsettings.json | 10 +++ SampleApp/wwwroot/favicon.ico | Bin 0 -> 5430 bytes WEB/Src/Microsoft.ApplicationInsights.Web.sln | 2 - .../QuickPulse/QuickPulseServiceClient.cs | 2 +- 21 files changed, 329 insertions(+), 9 deletions(-) create mode 100644 SampleApp/Controllers/HomeController.cs create mode 100644 SampleApp/Models/ErrorViewModel.cs create mode 100644 SampleApp/Program.cs create mode 100644 SampleApp/Properties/launchSettings.json create mode 100644 SampleApp/SampleApp.csproj create mode 100644 SampleApp/Startup.cs create mode 100644 SampleApp/Views/Home/Index.cshtml create mode 100644 SampleApp/Views/Home/Privacy.cshtml create mode 100644 SampleApp/Views/Shared/Error.cshtml create mode 100644 SampleApp/Views/Shared/_Layout.cshtml create mode 100644 SampleApp/Views/Shared/_ValidationScriptsPartial.cshtml create mode 100644 SampleApp/Views/_ViewImports.cshtml create mode 100644 SampleApp/Views/_ViewStart.cshtml create mode 100644 SampleApp/appsettings.Development.json create mode 100644 SampleApp/appsettings.json create mode 100644 SampleApp/wwwroot/favicon.ico diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index 2406ce823f..b89d8401d3 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -14,7 +14,7 @@ public abstract class CredentialEnvelope /// (https://docs.microsoft.com/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). /// (https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope). /// - private const string Scope = "https://monitor.azure.com//.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. + private const string Scope = "https://monitor.azure.com/.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. /// /// Gets the TokenCredential object held by this class. diff --git a/Everything.sln b/Everything.sln index a62cd7b9f5..831d39279d 100644 --- a/Everything.sln +++ b/Everything.sln @@ -145,6 +145,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web", "WEB\Src\Web\Web\Web. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xdt.Tests", "LOGGING\test\Xdt.Tests\Xdt.Tests.csproj", "{8AAC8DC7-A2FC-4767-BDA8-380F86B64772}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp", "SampleApp\SampleApp.csproj", "{9DCEE07C-3D43-40F8-AAE0-F277F5A0BB76}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution WEB\Src\PerformanceCollector\Perf.Shared.NetFull\Perf.Shared.NetFull.projitems*{0196259c-3582-4f4e-a01f-a8f9ae83b0f3}*SharedItemsImports = 13 @@ -184,7 +186,6 @@ Global NETCORE\src\Shared\Shared.projitems*{ac399f09-b465-4cfd-8d82-f1d1c5c9347e}*SharedItemsImports = 5 LOGGING\test\CommonTestShared\CommonTestShared.projitems*{b1650e9b-6764-4dc0-8c71-96f0ff335c80}*SharedItemsImports = 5 LOGGING\test\Shared\Adapters.Shared.Tests.projitems*{b1650e9b-6764-4dc0-8c71-96f0ff335c80}*SharedItemsImports = 5 - BASE\src\Common\Common\Common.projitems*{c30a7eb8-a86c-49ee-927e-7d9e03572e82}*SharedItemsImports = 5 LOGGING\test\CommonTestShared\CommonTestShared.projitems*{ca21ed5e-ab4e-4277-a28d-e8840e92833f}*SharedItemsImports = 5 LOGGING\test\Shared\Adapters.Shared.Tests.projitems*{ca21ed5e-ab4e-4277-a28d-e8840e92833f}*SharedItemsImports = 5 WEB\Src\Common\Common.projitems*{ccab7a34-8dc5-4a6f-b637-46ceba93c687}*SharedItemsImports = 13 @@ -192,7 +193,6 @@ Global WEB\Src\PerformanceCollector\Perf.Shared.NetStandard\Perf.Shared.NetStandard.projitems*{d13c3ec7-b300-4158-9054-216156b203be}*SharedItemsImports = 13 NETCORE\src\Shared\Shared.projitems*{d56f2979-d6bc-4ef2-bb9b-4077b3290599}*SharedItemsImports = 13 WEB\Src\Common\Common.projitems*{deeaf599-83f9-4a05-add6-f612cdabe570}*SharedItemsImports = 5 - BASE\src\Common\Common\Common.projitems*{e3d160e8-7f8c-416f-946f-6fdfc6787461}*SharedItemsImports = 5 BASE\Test\TestFramework\Shared\TestFramework.Shared.projitems*{f76c6cbd-29b0-4564-bdcb-c969f8fec136}*SharedItemsImports = 13 LOGGING\test\Shared\Adapters.Shared.Tests.projitems*{fa775630-7917-4a99-a78c-fba46edf685c}*SharedItemsImports = 13 WEB\Src\TestFramework\Shared\TestFramework.Shared.projitems*{fac049e4-7011-45ff-bd06-69aca28921e8}*SharedItemsImports = 5 @@ -370,6 +370,10 @@ Global {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Debug|Any CPU.Build.0 = Debug|Any CPU {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Release|Any CPU.ActiveCfg = Release|Any CPU {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Release|Any CPU.Build.0 = Release|Any CPU + {9DCEE07C-3D43-40F8-AAE0-F277F5A0BB76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9DCEE07C-3D43-40F8-AAE0-F277F5A0BB76}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9DCEE07C-3D43-40F8-AAE0-F277F5A0BB76}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9DCEE07C-3D43-40F8-AAE0-F277F5A0BB76}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/NETCORE/ApplicationInsights.AspNetCore.sln b/NETCORE/ApplicationInsights.AspNetCore.sln index 59df6988bd..41fe73fced 100644 --- a/NETCORE/ApplicationInsights.AspNetCore.sln +++ b/NETCORE/ApplicationInsights.AspNetCore.sln @@ -61,13 +61,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests.MVC.Tests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests.WebApi.Tests", "test\FunctionalTests.WebApi.Tests\FunctionalTests.WebApi.Tests.csproj", "{E78404EA-CBAA-4366-B659-C3A46BC9DF15}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationTests.WebApp", "test\IntegrationTests.WebApp\IntegrationTests.WebApp.csproj", "{AFB5577E-1560-468C-91C7-042080202478}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests.WebApp", "test\IntegrationTests.WebApp\IntegrationTests.WebApp.csproj", "{AFB5577E-1560-468C-91C7-042080202478}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp", "..\SampleApp\SampleApp.csproj", "{0E049C07-AD2C-4760-B9C4-A8CB284368DE}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution - ..\BASE\src\Common\Common\Common.projitems*{0c91d961-b21e-4760-a192-14193f10b831}*SharedItemsImports = 5 ..\WEB\Src\Common\Common.projitems*{1056392c-387c-4530-ba3f-aa687ea453ae}*SharedItemsImports = 5 - ..\BASE\src\Common\Common\Common.projitems*{2c7ceedd-bb15-48df-b12a-b268e9d74859}*SharedItemsImports = 5 ..\WEB\Src\Common\Common.projitems*{3c157fc2-2e52-45fc-87e8-76e4fced4260}*SharedItemsImports = 5 ..\WEB\Src\PerformanceCollector\Perf.Shared.NetFull\Perf.Shared.NetFull.projitems*{3c157fc2-2e52-45fc-87e8-76e4fced4260}*SharedItemsImports = 5 ..\LOGGING\src\CommonShared\CommonShared.projitems*{4a9ec531-f8b2-4cd1-bd6b-745f33e52e7b}*SharedItemsImports = 5 @@ -150,6 +150,10 @@ Global {AFB5577E-1560-468C-91C7-042080202478}.Debug|Any CPU.Build.0 = Debug|Any CPU {AFB5577E-1560-468C-91C7-042080202478}.Release|Any CPU.ActiveCfg = Release|Any CPU {AFB5577E-1560-468C-91C7-042080202478}.Release|Any CPU.Build.0 = Release|Any CPU + {0E049C07-AD2C-4760-B9C4-A8CB284368DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E049C07-AD2C-4760-B9C4-A8CB284368DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E049C07-AD2C-4760-B9C4-A8CB284368DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E049C07-AD2C-4760-B9C4-A8CB284368DE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SampleApp/Controllers/HomeController.cs b/SampleApp/Controllers/HomeController.cs new file mode 100644 index 0000000000..6a079a5868 --- /dev/null +++ b/SampleApp/Controllers/HomeController.cs @@ -0,0 +1,47 @@ +namespace SampleApp.Controllers +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + using System.Threading.Tasks; + + using Microsoft.ApplicationInsights; + using Microsoft.ApplicationInsights.Extensibility; + using Microsoft.AspNetCore.Mvc; + using Microsoft.Extensions.Logging; + + using SampleApp.Models; + + public class HomeController : Controller + { + private readonly ILogger _logger; + private readonly TelemetryClient _telemetryClient; + private readonly TelemetryConfiguration _telemetryConfiguration; + + public HomeController(ILogger logger, TelemetryClient telemetryClient, TelemetryConfiguration telemetryConfiguration) + { + _logger = logger; + _telemetryClient = telemetryClient; + _telemetryConfiguration = telemetryConfiguration; + + var tokenTest = _telemetryConfiguration.CredentialEnvelope.GetToken(); + } + + public IActionResult Index() + { + return View(); + } + + public IActionResult Privacy() + { + return View(); + } + + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + public IActionResult Error() + { + return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); + } + } +} diff --git a/SampleApp/Models/ErrorViewModel.cs b/SampleApp/Models/ErrorViewModel.cs new file mode 100644 index 0000000000..23d087b16f --- /dev/null +++ b/SampleApp/Models/ErrorViewModel.cs @@ -0,0 +1,11 @@ +namespace SampleApp.Models +{ + using System; + + public class ErrorViewModel + { + public string RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + } +} diff --git a/SampleApp/Program.cs b/SampleApp/Program.cs new file mode 100644 index 0000000000..db20e8c8db --- /dev/null +++ b/SampleApp/Program.cs @@ -0,0 +1,27 @@ +namespace SampleApp +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + + using Microsoft.AspNetCore.Hosting; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.Hosting; + using Microsoft.Extensions.Logging; + + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/SampleApp/Properties/launchSettings.json b/SampleApp/Properties/launchSettings.json new file mode 100644 index 0000000000..f60c60a760 --- /dev/null +++ b/SampleApp/Properties/launchSettings.json @@ -0,0 +1,28 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:27315", + "sslPort": 44340 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "SampleApp": { + "commandName": "Project", + "dotnetRunMessages": "true", + "launchBrowser": true, + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/SampleApp/SampleApp.csproj b/SampleApp/SampleApp.csproj new file mode 100644 index 0000000000..6382758d27 --- /dev/null +++ b/SampleApp/SampleApp.csproj @@ -0,0 +1,17 @@ + + + + net5.0 + + + + + + + + + + + + + diff --git a/SampleApp/Startup.cs b/SampleApp/Startup.cs new file mode 100644 index 0000000000..a0aefb8b1f --- /dev/null +++ b/SampleApp/Startup.cs @@ -0,0 +1,70 @@ +namespace SampleApp +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + + using Azure.Identity; + + using Microsoft.ApplicationInsights.AspNetCore.Extensions; + using Microsoft.ApplicationInsights.Extensibility; + using Microsoft.AspNetCore.Builder; + using Microsoft.AspNetCore.Hosting; + using Microsoft.AspNetCore.HttpsPolicy; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddControllersWithViews(); + + services.Configure(config => + { + config.ConnectionString = ""; + config.SetCredential(new DefaultAzureCredential()); + }); + + services.AddApplicationInsightsTelemetry(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseExceptionHandler("/Home/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } + app.UseHttpsRedirection(); + app.UseStaticFiles(); + + app.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllerRoute( + name: "default", + pattern: "{controller=Home}/{action=Index}/{id?}"); + }); + } + } +} diff --git a/SampleApp/Views/Home/Index.cshtml b/SampleApp/Views/Home/Index.cshtml new file mode 100644 index 0000000000..d2d19bdf9f --- /dev/null +++ b/SampleApp/Views/Home/Index.cshtml @@ -0,0 +1,8 @@ +@{ + ViewData["Title"] = "Home Page"; +} + +
+

Welcome

+

Learn about building Web apps with ASP.NET Core.

+
diff --git a/SampleApp/Views/Home/Privacy.cshtml b/SampleApp/Views/Home/Privacy.cshtml new file mode 100644 index 0000000000..af4fb195a3 --- /dev/null +++ b/SampleApp/Views/Home/Privacy.cshtml @@ -0,0 +1,6 @@ +@{ + ViewData["Title"] = "Privacy Policy"; +} +

@ViewData["Title"]

+ +

Use this page to detail your site's privacy policy.

diff --git a/SampleApp/Views/Shared/Error.cshtml b/SampleApp/Views/Shared/Error.cshtml new file mode 100644 index 0000000000..a1e04783c6 --- /dev/null +++ b/SampleApp/Views/Shared/Error.cshtml @@ -0,0 +1,25 @@ +@model ErrorViewModel +@{ + ViewData["Title"] = "Error"; +} + +

Error.

+

An error occurred while processing your request.

+ +@if (Model.ShowRequestId) +{ +

+ Request ID: @Model.RequestId +

+} + +

Development Mode

+

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ The Development environment shouldn't be enabled for deployed applications. + It can result in displaying sensitive information from exceptions to end users. + For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development + and restarting the app. +

diff --git a/SampleApp/Views/Shared/_Layout.cshtml b/SampleApp/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000000..6ecda20665 --- /dev/null +++ b/SampleApp/Views/Shared/_Layout.cshtml @@ -0,0 +1,48 @@ + + + + + + @ViewData["Title"] - SampleApp + + + + +
+ +
+
+
+ @RenderBody() +
+
+ +
+
+ © 2021 - SampleApp - Privacy +
+
+ + + + @await RenderSectionAsync("Scripts", required: false) + + diff --git a/SampleApp/Views/Shared/_ValidationScriptsPartial.cshtml b/SampleApp/Views/Shared/_ValidationScriptsPartial.cshtml new file mode 100644 index 0000000000..5a16d80a9a --- /dev/null +++ b/SampleApp/Views/Shared/_ValidationScriptsPartial.cshtml @@ -0,0 +1,2 @@ + + diff --git a/SampleApp/Views/_ViewImports.cshtml b/SampleApp/Views/_ViewImports.cshtml new file mode 100644 index 0000000000..afe0c99241 --- /dev/null +++ b/SampleApp/Views/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using SampleApp +@using SampleApp.Models +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/SampleApp/Views/_ViewStart.cshtml b/SampleApp/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..a5f10045db --- /dev/null +++ b/SampleApp/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/SampleApp/appsettings.Development.json b/SampleApp/appsettings.Development.json new file mode 100644 index 0000000000..8983e0fc1c --- /dev/null +++ b/SampleApp/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/SampleApp/appsettings.json b/SampleApp/appsettings.json new file mode 100644 index 0000000000..d9d9a9bff6 --- /dev/null +++ b/SampleApp/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/SampleApp/wwwroot/favicon.ico b/SampleApp/wwwroot/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..63e859b476eff5055e0e557aaa151ca8223fbeef GIT binary patch literal 5430 zcmc&&Yj2xp8Fqnv;>&(QB_ve7>^E#o2mu=cO~A%R>DU-_hfbSRv1t;m7zJ_AMrntN zy0+^f&8be>q&YYzH%(88lQ?#KwiCzaCO*ZEo%j&v;<}&Lj_stKTKK>#U3nin@AF>w zb3ONSAFR{u(S1d?cdw53y}Gt1b-Hirbh;;bm(Rcbnoc*%@jiaXM|4jU^1WO~`TYZ~ zC-~jh9~b-f?fX`DmwvcguQzn*uV}c^Vd&~?H|RUs4Epv~gTAfR(B0lT&?RWQOtduM z^1vUD9{HQsW!{a9|0crA34m7Z6lpG^}f6f?={zD+ zXAzk^i^aKN_}s2$eX81wjSMONE#WVdzf|MT)Ap*}Vsn!XbvsI#6o&ij{87^d%$|A{ z=F{KB%)g%@z76yBzbb7seW**Ju8r4e*Z3PWNX3_tTDgzZatz7)Q6ytwB%@&@A|XT; zecM`Snxx5po$C)%yCP!KEtos~eOS)@2=kX-RIm)4glMCoagTEFxrBeSX%Euz734Fk z%7)x(k~T!@Hbg_37NSQL!vlTBXoURSzt~I**Zw`&F24fH*&kx=%nvZv|49SC*daD( zIw<~%#=lk8{2-l(BcIjy^Q$Q&m#KlWL9?UG{b8@qhlD z;umc+6p%|NsAT~0@DgV4-NKgQuWPWrmPIK&&XhV&n%`{l zOl^bbWYjQNuVXTXESO)@|iUKVmErPUDfz2Wh`4dF@OFiaCW|d`3paV^@|r^8T_ZxM)Z+$p5qx# z#K=z@%;aBPO=C4JNNGqVv6@UGolIz;KZsAro``Rz8X%vq_gpi^qEV&evgHb_=Y9-l z`)imdx0UC>GWZYj)3+3aKh?zVb}=@%oNzg7a8%kfVl)SV-Amp1Okw&+hEZ3|v(k8vRjXW9?ih`&FFM zV$~{j3IzhtcXk?Mu_!12;=+I7XK-IR2>Yd%VB^?oI9c^E&Chb&&je$NV0P-R;ujkP z;cbLCCPEF6|22NDj=S`F^2e~XwT1ZnRX8ra0#DaFa9-X|8(xNW_+JhD75WnSd7cxo z2>I_J5{c|WPfrgl7E2R)^c}F7ry()Z>$Jhk9CzZxiPKL#_0%`&{MX>P_%b~Dx0D^S z7xP1(DQ!d_Icpk!RN3I1w@~|O1ru#CO==h#9M~S4Chx*@?=EKUPGBv$tmU+7Zs_al z`!jR?6T&Z7(%uVq>#yLu`abWk!FBlnY{RFNHlj~6zh*;@u}+}viRKsD`IIxN#R-X3 z@vxu#EA_m}I503U(8Qmx^}u;)KfGP`O9E1H1Q|xeeksX8jC%@!{YT1)!lWgO=+Y3*jr=iSxvOW1}^HSy=y){tOMQJ@an>sOl4FYniE z;GOxd7AqxZNbYFNqobpv&HVO$c-w!Y*6r;$2oJ~h(a#(Bp<-)dg*mNigX~9rPqcHv z^;c*|Md?tD)$y?6FO$DWl$jUGV`F1G_^E&E>sY*YnA~ruv3=z9F8&&~Xpm<<75?N3 z>x~`I&M9q)O1=zWZHN9hZWx>RQ}zLP+iL57Q)%&_^$Sme^^G7;e-P~CR?kqU#Io#( z(nH1Wn*Ig)|M>WLGrxoU?FZrS`4GO&w;+39A3f8w{{Q7eg|$+dIlNFPAe+tN=FOYU z{A&Fg|H73+w1IK(W=j*L>JQgz$g0 z7JpKXLHIh}#$wm|N`s}o-@|L_`>*(gTQ~)wr3Eap7g%PVNisKw82im;Gdv#85x#s+ zoqqtnwu4ycd>cOQgRh-=aEJbnvVK`}ja%+FZx}&ehtX)n(9nVfe4{mn0bgijUbNr7Tf5X^$*{qh2%`?--%+sbSrjE^;1e3>% zqa%jdY16{Y)a1hSy*mr0JGU05Z%=qlx5vGvTjSpTt6k%nR06q}1DU`SQh_ZAeJ}A@`hL~xvv05U?0%=spP`R>dk?cOWM9^KNb7B?xjex>OZo%JMQQ1Q zB|q@}8RiP@DWn-(fB;phPaIOP2Yp)XN3-Fsn)S3w($4&+p8f5W_f%gac}QvmkHfCj$2=!t`boCvQ zCW;&Dto=f8v##}dy^wg3VNaBy&kCe3N;1|@n@pUaMPT?(aJ9b*(gJ28$}(2qFt$H~u5z94xcIQkcOI++)*exzbrk?WOOOf*|%k5#KV zL=&ky3)Eirv$wbRJ2F2s_ILQY--D~~7>^f}W|Aw^e7inXr#WLI{@h`0|jHud2Y~cI~Yn{r_kU^Vo{1gja Date: Wed, 14 Apr 2021 17:40:05 -0700 Subject: [PATCH 31/93] fix --- .../Implementation/QuickPulse/QuickPulseServiceClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs index 04b8f62929..7e4a47a438 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -388,7 +388,7 @@ private void AddHeaders(HttpWebRequest request, bool includeIdentityHeaders, str } // The AAD token is an optional feature. Only include if it is provided. - if (string.IsNullOrEmpty(aadToken)) + if (!string.IsNullOrEmpty(aadToken)) { request.Headers.Add(QuickPulseConstants.AuthorizationHeaderName, QuickPulseConstants.AuthorizationTokenPrefix + aadToken); } From 8a498d507f3caeb5f2cc28f8f09690d89da1eb28 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 15 Apr 2021 14:47:53 -0700 Subject: [PATCH 32/93] remove sample app --- Everything.sln | 6 -- SampleApp/Controllers/HomeController.cs | 47 ------------ SampleApp/Models/ErrorViewModel.cs | 11 --- SampleApp/Program.cs | 27 ------- SampleApp/Properties/launchSettings.json | 28 ------- SampleApp/SampleApp.csproj | 17 ----- SampleApp/Startup.cs | 70 ------------------ SampleApp/Views/Home/Index.cshtml | 8 -- SampleApp/Views/Home/Privacy.cshtml | 6 -- SampleApp/Views/Shared/Error.cshtml | 25 ------- SampleApp/Views/Shared/_Layout.cshtml | 48 ------------ .../Shared/_ValidationScriptsPartial.cshtml | 2 - SampleApp/Views/_ViewImports.cshtml | 3 - SampleApp/Views/_ViewStart.cshtml | 3 - SampleApp/appsettings.Development.json | 9 --- SampleApp/appsettings.json | 10 --- SampleApp/wwwroot/favicon.ico | Bin 5430 -> 0 bytes 17 files changed, 320 deletions(-) delete mode 100644 SampleApp/Controllers/HomeController.cs delete mode 100644 SampleApp/Models/ErrorViewModel.cs delete mode 100644 SampleApp/Program.cs delete mode 100644 SampleApp/Properties/launchSettings.json delete mode 100644 SampleApp/SampleApp.csproj delete mode 100644 SampleApp/Startup.cs delete mode 100644 SampleApp/Views/Home/Index.cshtml delete mode 100644 SampleApp/Views/Home/Privacy.cshtml delete mode 100644 SampleApp/Views/Shared/Error.cshtml delete mode 100644 SampleApp/Views/Shared/_Layout.cshtml delete mode 100644 SampleApp/Views/Shared/_ValidationScriptsPartial.cshtml delete mode 100644 SampleApp/Views/_ViewImports.cshtml delete mode 100644 SampleApp/Views/_ViewStart.cshtml delete mode 100644 SampleApp/appsettings.Development.json delete mode 100644 SampleApp/appsettings.json delete mode 100644 SampleApp/wwwroot/favicon.ico diff --git a/Everything.sln b/Everything.sln index a14af624ca..07c72a1cf6 100644 --- a/Everything.sln +++ b/Everything.sln @@ -143,8 +143,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web", "WEB\Src\Web\Web\Web. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xdt.Tests", "LOGGING\test\Xdt.Tests\Xdt.Tests.csproj", "{8AAC8DC7-A2FC-4767-BDA8-380F86B64772}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp", "SampleApp\SampleApp.csproj", "{9DCEE07C-3D43-40F8-AAE0-F277F5A0BB76}" -EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution WEB\Src\PerformanceCollector\Perf.Shared.NetFull\Perf.Shared.NetFull.projitems*{0196259c-3582-4f4e-a01f-a8f9ae83b0f3}*SharedItemsImports = 13 @@ -367,10 +365,6 @@ Global {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Debug|Any CPU.Build.0 = Debug|Any CPU {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Release|Any CPU.ActiveCfg = Release|Any CPU {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Release|Any CPU.Build.0 = Release|Any CPU - {9DCEE07C-3D43-40F8-AAE0-F277F5A0BB76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9DCEE07C-3D43-40F8-AAE0-F277F5A0BB76}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9DCEE07C-3D43-40F8-AAE0-F277F5A0BB76}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9DCEE07C-3D43-40F8-AAE0-F277F5A0BB76}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SampleApp/Controllers/HomeController.cs b/SampleApp/Controllers/HomeController.cs deleted file mode 100644 index 6a079a5868..0000000000 --- a/SampleApp/Controllers/HomeController.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace SampleApp.Controllers -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - using System.Threading.Tasks; - - using Microsoft.ApplicationInsights; - using Microsoft.ApplicationInsights.Extensibility; - using Microsoft.AspNetCore.Mvc; - using Microsoft.Extensions.Logging; - - using SampleApp.Models; - - public class HomeController : Controller - { - private readonly ILogger _logger; - private readonly TelemetryClient _telemetryClient; - private readonly TelemetryConfiguration _telemetryConfiguration; - - public HomeController(ILogger logger, TelemetryClient telemetryClient, TelemetryConfiguration telemetryConfiguration) - { - _logger = logger; - _telemetryClient = telemetryClient; - _telemetryConfiguration = telemetryConfiguration; - - var tokenTest = _telemetryConfiguration.CredentialEnvelope.GetToken(); - } - - public IActionResult Index() - { - return View(); - } - - public IActionResult Privacy() - { - return View(); - } - - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] - public IActionResult Error() - { - return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); - } - } -} diff --git a/SampleApp/Models/ErrorViewModel.cs b/SampleApp/Models/ErrorViewModel.cs deleted file mode 100644 index 23d087b16f..0000000000 --- a/SampleApp/Models/ErrorViewModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace SampleApp.Models -{ - using System; - - public class ErrorViewModel - { - public string RequestId { get; set; } - - public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); - } -} diff --git a/SampleApp/Program.cs b/SampleApp/Program.cs deleted file mode 100644 index db20e8c8db..0000000000 --- a/SampleApp/Program.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace SampleApp -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Threading.Tasks; - - using Microsoft.AspNetCore.Hosting; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Hosting; - using Microsoft.Extensions.Logging; - - public class Program - { - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); - } -} diff --git a/SampleApp/Properties/launchSettings.json b/SampleApp/Properties/launchSettings.json deleted file mode 100644 index f60c60a760..0000000000 --- a/SampleApp/Properties/launchSettings.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:27315", - "sslPort": 44340 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "SampleApp": { - "commandName": "Project", - "dotnetRunMessages": "true", - "launchBrowser": true, - "applicationUrl": "https://localhost:5001;http://localhost:5000", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/SampleApp/SampleApp.csproj b/SampleApp/SampleApp.csproj deleted file mode 100644 index 6382758d27..0000000000 --- a/SampleApp/SampleApp.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net5.0 - - - - - - - - - - - - - diff --git a/SampleApp/Startup.cs b/SampleApp/Startup.cs deleted file mode 100644 index a0aefb8b1f..0000000000 --- a/SampleApp/Startup.cs +++ /dev/null @@ -1,70 +0,0 @@ -namespace SampleApp -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Threading.Tasks; - - using Azure.Identity; - - using Microsoft.ApplicationInsights.AspNetCore.Extensions; - using Microsoft.ApplicationInsights.Extensibility; - using Microsoft.AspNetCore.Builder; - using Microsoft.AspNetCore.Hosting; - using Microsoft.AspNetCore.HttpsPolicy; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Hosting; - - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddControllersWithViews(); - - services.Configure(config => - { - config.ConnectionString = ""; - config.SetCredential(new DefaultAzureCredential()); - }); - - services.AddApplicationInsightsTelemetry(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Home/Error"); - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - app.UseHttpsRedirection(); - app.UseStaticFiles(); - - app.UseRouting(); - - app.UseAuthorization(); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllerRoute( - name: "default", - pattern: "{controller=Home}/{action=Index}/{id?}"); - }); - } - } -} diff --git a/SampleApp/Views/Home/Index.cshtml b/SampleApp/Views/Home/Index.cshtml deleted file mode 100644 index d2d19bdf9f..0000000000 --- a/SampleApp/Views/Home/Index.cshtml +++ /dev/null @@ -1,8 +0,0 @@ -@{ - ViewData["Title"] = "Home Page"; -} - -
-

Welcome

-

Learn about building Web apps with ASP.NET Core.

-
diff --git a/SampleApp/Views/Home/Privacy.cshtml b/SampleApp/Views/Home/Privacy.cshtml deleted file mode 100644 index af4fb195a3..0000000000 --- a/SampleApp/Views/Home/Privacy.cshtml +++ /dev/null @@ -1,6 +0,0 @@ -@{ - ViewData["Title"] = "Privacy Policy"; -} -

@ViewData["Title"]

- -

Use this page to detail your site's privacy policy.

diff --git a/SampleApp/Views/Shared/Error.cshtml b/SampleApp/Views/Shared/Error.cshtml deleted file mode 100644 index a1e04783c6..0000000000 --- a/SampleApp/Views/Shared/Error.cshtml +++ /dev/null @@ -1,25 +0,0 @@ -@model ErrorViewModel -@{ - ViewData["Title"] = "Error"; -} - -

Error.

-

An error occurred while processing your request.

- -@if (Model.ShowRequestId) -{ -

- Request ID: @Model.RequestId -

-} - -

Development Mode

-

- Swapping to Development environment will display more detailed information about the error that occurred. -

-

- The Development environment shouldn't be enabled for deployed applications. - It can result in displaying sensitive information from exceptions to end users. - For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development - and restarting the app. -

diff --git a/SampleApp/Views/Shared/_Layout.cshtml b/SampleApp/Views/Shared/_Layout.cshtml deleted file mode 100644 index 6ecda20665..0000000000 --- a/SampleApp/Views/Shared/_Layout.cshtml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - @ViewData["Title"] - SampleApp - - - - -
- -
-
-
- @RenderBody() -
-
- -
-
- © 2021 - SampleApp - Privacy -
-
- - - - @await RenderSectionAsync("Scripts", required: false) - - diff --git a/SampleApp/Views/Shared/_ValidationScriptsPartial.cshtml b/SampleApp/Views/Shared/_ValidationScriptsPartial.cshtml deleted file mode 100644 index 5a16d80a9a..0000000000 --- a/SampleApp/Views/Shared/_ValidationScriptsPartial.cshtml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/SampleApp/Views/_ViewImports.cshtml b/SampleApp/Views/_ViewImports.cshtml deleted file mode 100644 index afe0c99241..0000000000 --- a/SampleApp/Views/_ViewImports.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@using SampleApp -@using SampleApp.Models -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/SampleApp/Views/_ViewStart.cshtml b/SampleApp/Views/_ViewStart.cshtml deleted file mode 100644 index a5f10045db..0000000000 --- a/SampleApp/Views/_ViewStart.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@{ - Layout = "_Layout"; -} diff --git a/SampleApp/appsettings.Development.json b/SampleApp/appsettings.Development.json deleted file mode 100644 index 8983e0fc1c..0000000000 --- a/SampleApp/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - } -} diff --git a/SampleApp/appsettings.json b/SampleApp/appsettings.json deleted file mode 100644 index d9d9a9bff6..0000000000 --- a/SampleApp/appsettings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "AllowedHosts": "*" -} diff --git a/SampleApp/wwwroot/favicon.ico b/SampleApp/wwwroot/favicon.ico deleted file mode 100644 index 63e859b476eff5055e0e557aaa151ca8223fbeef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5430 zcmc&&Yj2xp8Fqnv;>&(QB_ve7>^E#o2mu=cO~A%R>DU-_hfbSRv1t;m7zJ_AMrntN zy0+^f&8be>q&YYzH%(88lQ?#KwiCzaCO*ZEo%j&v;<}&Lj_stKTKK>#U3nin@AF>w zb3ONSAFR{u(S1d?cdw53y}Gt1b-Hirbh;;bm(Rcbnoc*%@jiaXM|4jU^1WO~`TYZ~ zC-~jh9~b-f?fX`DmwvcguQzn*uV}c^Vd&~?H|RUs4Epv~gTAfR(B0lT&?RWQOtduM z^1vUD9{HQsW!{a9|0crA34m7Z6lpG^}f6f?={zD+ zXAzk^i^aKN_}s2$eX81wjSMONE#WVdzf|MT)Ap*}Vsn!XbvsI#6o&ij{87^d%$|A{ z=F{KB%)g%@z76yBzbb7seW**Ju8r4e*Z3PWNX3_tTDgzZatz7)Q6ytwB%@&@A|XT; zecM`Snxx5po$C)%yCP!KEtos~eOS)@2=kX-RIm)4glMCoagTEFxrBeSX%Euz734Fk z%7)x(k~T!@Hbg_37NSQL!vlTBXoURSzt~I**Zw`&F24fH*&kx=%nvZv|49SC*daD( zIw<~%#=lk8{2-l(BcIjy^Q$Q&m#KlWL9?UG{b8@qhlD z;umc+6p%|NsAT~0@DgV4-NKgQuWPWrmPIK&&XhV&n%`{l zOl^bbWYjQNuVXTXESO)@|iUKVmErPUDfz2Wh`4dF@OFiaCW|d`3paV^@|r^8T_ZxM)Z+$p5qx# z#K=z@%;aBPO=C4JNNGqVv6@UGolIz;KZsAro``Rz8X%vq_gpi^qEV&evgHb_=Y9-l z`)imdx0UC>GWZYj)3+3aKh?zVb}=@%oNzg7a8%kfVl)SV-Amp1Okw&+hEZ3|v(k8vRjXW9?ih`&FFM zV$~{j3IzhtcXk?Mu_!12;=+I7XK-IR2>Yd%VB^?oI9c^E&Chb&&je$NV0P-R;ujkP z;cbLCCPEF6|22NDj=S`F^2e~XwT1ZnRX8ra0#DaFa9-X|8(xNW_+JhD75WnSd7cxo z2>I_J5{c|WPfrgl7E2R)^c}F7ry()Z>$Jhk9CzZxiPKL#_0%`&{MX>P_%b~Dx0D^S z7xP1(DQ!d_Icpk!RN3I1w@~|O1ru#CO==h#9M~S4Chx*@?=EKUPGBv$tmU+7Zs_al z`!jR?6T&Z7(%uVq>#yLu`abWk!FBlnY{RFNHlj~6zh*;@u}+}viRKsD`IIxN#R-X3 z@vxu#EA_m}I503U(8Qmx^}u;)KfGP`O9E1H1Q|xeeksX8jC%@!{YT1)!lWgO=+Y3*jr=iSxvOW1}^HSy=y){tOMQJ@an>sOl4FYniE z;GOxd7AqxZNbYFNqobpv&HVO$c-w!Y*6r;$2oJ~h(a#(Bp<-)dg*mNigX~9rPqcHv z^;c*|Md?tD)$y?6FO$DWl$jUGV`F1G_^E&E>sY*YnA~ruv3=z9F8&&~Xpm<<75?N3 z>x~`I&M9q)O1=zWZHN9hZWx>RQ}zLP+iL57Q)%&_^$Sme^^G7;e-P~CR?kqU#Io#( z(nH1Wn*Ig)|M>WLGrxoU?FZrS`4GO&w;+39A3f8w{{Q7eg|$+dIlNFPAe+tN=FOYU z{A&Fg|H73+w1IK(W=j*L>JQgz$g0 z7JpKXLHIh}#$wm|N`s}o-@|L_`>*(gTQ~)wr3Eap7g%PVNisKw82im;Gdv#85x#s+ zoqqtnwu4ycd>cOQgRh-=aEJbnvVK`}ja%+FZx}&ehtX)n(9nVfe4{mn0bgijUbNr7Tf5X^$*{qh2%`?--%+sbSrjE^;1e3>% zqa%jdY16{Y)a1hSy*mr0JGU05Z%=qlx5vGvTjSpTt6k%nR06q}1DU`SQh_ZAeJ}A@`hL~xvv05U?0%=spP`R>dk?cOWM9^KNb7B?xjex>OZo%JMQQ1Q zB|q@}8RiP@DWn-(fB;phPaIOP2Yp)XN3-Fsn)S3w($4&+p8f5W_f%gac}QvmkHfCj$2=!t`boCvQ zCW;&Dto=f8v##}dy^wg3VNaBy&kCe3N;1|@n@pUaMPT?(aJ9b*(gJ28$}(2qFt$H~u5z94xcIQkcOI++)*exzbrk?WOOOf*|%k5#KV zL=&ky3)Eirv$wbRJ2F2s_ILQY--D~~7>^f}W|Aw^e7inXr#WLI{@h`0|jHud2Y~cI~Yn{r_kU^Vo{1gja Date: Thu, 15 Apr 2021 14:48:58 -0700 Subject: [PATCH 33/93] remove samples app --- NETCORE/ApplicationInsights.AspNetCore.sln | 6 ------ 1 file changed, 6 deletions(-) diff --git a/NETCORE/ApplicationInsights.AspNetCore.sln b/NETCORE/ApplicationInsights.AspNetCore.sln index 41fe73fced..95c14524a2 100644 --- a/NETCORE/ApplicationInsights.AspNetCore.sln +++ b/NETCORE/ApplicationInsights.AspNetCore.sln @@ -63,8 +63,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests.WebApi.Test EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests.WebApp", "test\IntegrationTests.WebApp\IntegrationTests.WebApp.csproj", "{AFB5577E-1560-468C-91C7-042080202478}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp", "..\SampleApp\SampleApp.csproj", "{0E049C07-AD2C-4760-B9C4-A8CB284368DE}" -EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ..\WEB\Src\Common\Common.projitems*{1056392c-387c-4530-ba3f-aa687ea453ae}*SharedItemsImports = 5 @@ -150,10 +148,6 @@ Global {AFB5577E-1560-468C-91C7-042080202478}.Debug|Any CPU.Build.0 = Debug|Any CPU {AFB5577E-1560-468C-91C7-042080202478}.Release|Any CPU.ActiveCfg = Release|Any CPU {AFB5577E-1560-468C-91C7-042080202478}.Release|Any CPU.Build.0 = Release|Any CPU - {0E049C07-AD2C-4760-B9C4-A8CB284368DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0E049C07-AD2C-4760-B9C4-A8CB284368DE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0E049C07-AD2C-4760-B9C4-A8CB284368DE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0E049C07-AD2C-4760-B9C4-A8CB284368DE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 4f2a33dcc2c4ad08e148d39b6cdea25dddef6098 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 15 Apr 2021 14:51:14 -0700 Subject: [PATCH 34/93] undo --- NETCORE/ApplicationInsights.AspNetCore.sln | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NETCORE/ApplicationInsights.AspNetCore.sln b/NETCORE/ApplicationInsights.AspNetCore.sln index 95c14524a2..3301bcfbcd 100644 --- a/NETCORE/ApplicationInsights.AspNetCore.sln +++ b/NETCORE/ApplicationInsights.AspNetCore.sln @@ -61,7 +61,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests.MVC.Tests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests.WebApi.Tests", "test\FunctionalTests.WebApi.Tests\FunctionalTests.WebApi.Tests.csproj", "{E78404EA-CBAA-4366-B659-C3A46BC9DF15}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests.WebApp", "test\IntegrationTests.WebApp\IntegrationTests.WebApp.csproj", "{AFB5577E-1560-468C-91C7-042080202478}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationTests.WebApp", "test\IntegrationTests.WebApp\IntegrationTests.WebApp.csproj", "{AFB5577E-1560-468C-91C7-042080202478}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution From 5ad8a6d91b0cd8fc4776fec7800a4a965fca4719 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 15 Apr 2021 15:13:36 -0700 Subject: [PATCH 35/93] fix --- .../Channel/Transmission.cs | 2 +- .../Authentication/TokenCredentialEnvelope.cs | 24 +++++++++++++++---- .../WebApp.AspNetCore.csproj | 4 ++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index 134bf96005..3ca8d52b10 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -390,7 +390,7 @@ protected virtual HttpRequestMessage CreateRequestMessage(Uri address, Stream co if (this.CredentialEnvelope != null) { var aadToken = this.CredentialEnvelope.GetToken(); - request.Content.Headers.Add(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + aadToken); + request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + aadToken); } return request; diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index 706b40ff1a..39375337ba 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -24,15 +24,31 @@ public TokenCredentialEnvelope(TokenCredential tokenCredential) /// public override string GetToken(CancellationToken cancellationToken = default) { - var accessToken = this.tokenCredential.GetToken(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); - return accessToken.Token; + SdkInternalOperationsMonitor.Enter(); + try + { + var accessToken = this.tokenCredential.GetToken(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); + return accessToken.Token; + } + finally + { + SdkInternalOperationsMonitor.Exit(); + } } /// public override async Task GetTokenAsync(CancellationToken cancellationToken = default) { - var accessToken = await this.tokenCredential.GetTokenAsync(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken).ConfigureAwait(false); - return accessToken.Token; + SdkInternalOperationsMonitor.Enter(); + try + { + var accessToken = await this.tokenCredential.GetTokenAsync(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken).ConfigureAwait(false); + return accessToken.Token; + } + finally + { + SdkInternalOperationsMonitor.Exit(); + } } } } diff --git a/examples/WebApp.AspNetCore/WebApp.AspNetCore.csproj b/examples/WebApp.AspNetCore/WebApp.AspNetCore.csproj index dc91dd6be7..78d303fe61 100644 --- a/examples/WebApp.AspNetCore/WebApp.AspNetCore.csproj +++ b/examples/WebApp.AspNetCore/WebApp.AspNetCore.csproj @@ -4,6 +4,10 @@ net5.0 + + + + From 7940b0f631b552760687aa3bbb595a36f6f2c96c Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 15 Apr 2021 15:54:25 -0700 Subject: [PATCH 36/93] changing scope --- .../Implementation/Authentication/CredentialEnvelope.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index b89d8401d3..2406ce823f 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -14,7 +14,7 @@ public abstract class CredentialEnvelope /// (https://docs.microsoft.com/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). /// (https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope). ///
- private const string Scope = "https://monitor.azure.com/.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. + private const string Scope = "https://monitor.azure.com//.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. /// /// Gets the TokenCredential object held by this class. From e3cefeb263023199f3af64aa7497fa9be478b162 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 30 Apr 2021 14:41:16 -0700 Subject: [PATCH 37/93] fxcop --- .../Channel/Transmission.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index 4d7a813fa4..9f2ca8cf3a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -142,6 +142,13 @@ public ICollection TelemetryItems get; private set; } + /// + /// Gets or sets the . + /// This is used include an AAD token on HTTP Requests sent to ingestion. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public CredentialEnvelope CredentialEnvelope { get; set; } + /// /// Gets the flush async id for the transmission. /// @@ -152,13 +159,6 @@ public ICollection TelemetryItems /// internal bool IsFlushAsyncInProgress { get; set; } = false; - /// - /// Gets or sets the . - /// This is used include an AAD token on HTTP Requests sent to ingestion. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public CredentialEnvelope CredentialEnvelope { get; set; } - /// /// Executes the request that the current transmission represents. /// From 1ff482a300461011ca5081a4f3801120cc7b84c1 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 7 May 2021 13:55:33 -0700 Subject: [PATCH 38/93] fix dependencies --- .../Microsoft.ApplicationInsights.csproj | 2 +- .../Microsoft.ApplicationInsights.AspNetCore.csproj | 2 +- .../test/IntegrationTests.Tests/IntegrationTests.Tests.csproj | 2 +- .../test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj b/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj index e7f390977c..1ed8dd0863 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj +++ b/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj @@ -31,7 +31,7 @@ - + diff --git a/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj b/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj index c5cff312b8..b129fffaca 100644 --- a/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj +++ b/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj @@ -57,7 +57,7 @@ - + diff --git a/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj b/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj index 0f4ff428b8..6f1e0a3471 100644 --- a/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj +++ b/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj @@ -41,7 +41,7 @@ - + diff --git a/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj b/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj index 0133fe47d0..2bd3a1f09c 100644 --- a/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj +++ b/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj @@ -9,7 +9,7 @@ - + From 87876f25a6bc57cdab6149c3e3a90b6cec21ef2d Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 7 May 2021 14:00:28 -0700 Subject: [PATCH 39/93] fix dependencies --- .../Microsoft.ApplicationInsights.Authentication.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj index 97eff3e356..6621a65021 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj @@ -14,7 +14,7 @@ - + From c9735a9766378f3636f7eead2ea93165e904b801 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 10:10:12 -0700 Subject: [PATCH 40/93] add new project --- BASE/Microsoft.ApplicationInsights.sln | 23 +++++++++++++++++++ .../Class1.cs | 17 ++++++++++++++ ...cationInsights.Authentication.Tests.csproj | 23 +++++++++++++++++++ Everything.sln | 7 ++++++ 4 files changed, 70 insertions(+) create mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Class1.cs create mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj diff --git a/BASE/Microsoft.ApplicationInsights.sln b/BASE/Microsoft.ApplicationInsights.sln index 624abee285..3d4dcf286b 100644 --- a/BASE/Microsoft.ApplicationInsights.sln +++ b/BASE/Microsoft.ApplicationInsights.sln @@ -40,6 +40,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ApplicationInsigh EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelemetryChannel.Tests", "Test\ServerTelemetryChannel.Test\TelemetryChannel.Tests\TelemetryChannel.Tests.csproj", "{7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ApplicationInsights.Authentication.Tests", "Test\Microsoft.ApplicationInsights.Test\Microsoft.ApplicationInsights.Authentication.Tests\Microsoft.ApplicationInsights.Authentication.Tests.csproj", "{2147F73A-5217-43F2-A409-07667DC952E6}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution Test\TestFramework\Shared\TestFramework.Shared.projitems*{f76c6cbd-29b0-4564-bdcb-c969f8fec136}*SharedItemsImports = 13 @@ -197,6 +199,26 @@ Global {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x64.Build.0 = Release|Any CPU {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x86.ActiveCfg = Release|Any CPU {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x86.Build.0 = Release|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|ARM.ActiveCfg = Debug|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|ARM.Build.0 = Debug|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|x64.ActiveCfg = Debug|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|x64.Build.0 = Debug|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|x86.ActiveCfg = Debug|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|x86.Build.0 = Debug|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Release|Any CPU.Build.0 = Release|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Release|ARM.ActiveCfg = Release|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Release|ARM.Build.0 = Release|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Release|x64.ActiveCfg = Release|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Release|x64.Build.0 = Release|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Release|x86.ActiveCfg = Release|Any CPU + {2147F73A-5217-43F2-A409-07667DC952E6}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -210,6 +232,7 @@ Global {3273D899-D9B3-44FE-B3AB-578E18B2EF90} = {E7B0521E-DA4D-40EA-B55D-ADCBDA69027C} {EF007559-EA01-4D4A-9BEB-8CC661797BE5} = {C2FEEDE5-8CAE-41A4-8932-42D284A86EA7} {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4} = {A61B048F-ECEA-4BED-A2ED-22834E7D4DFB} + {2147F73A-5217-43F2-A409-07667DC952E6} = {C2FEEDE5-8CAE-41A4-8932-42D284A86EA7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F70D4C7C-02FB-4EE9-875A-A2F95EC90EAC} diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Class1.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Class1.cs new file mode 100644 index 0000000000..8c731c50ee --- /dev/null +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Class1.cs @@ -0,0 +1,17 @@ +namespace Microsoft.ApplicationInsights.Authentication.Tests +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class Class1 + { + /// + /// The purpose of this test is to verify that the build system discovers and runs this project. + /// + [TestMethod] + public void HelloWorldTest() + { + Assert.IsTrue(true); + } + } +} diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj new file mode 100644 index 0000000000..d5444c64f5 --- /dev/null +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj @@ -0,0 +1,23 @@ + + + + + net461;net5.0 + + false + + + + + + + + + + + + + + + + diff --git a/Everything.sln b/Everything.sln index 07c72a1cf6..b629e74bbf 100644 --- a/Everything.sln +++ b/Everything.sln @@ -143,6 +143,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web", "WEB\Src\Web\Web\Web. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xdt.Tests", "LOGGING\test\Xdt.Tests\Xdt.Tests.csproj", "{8AAC8DC7-A2FC-4767-BDA8-380F86B64772}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ApplicationInsights.Authentication.Tests", "BASE\Test\Microsoft.ApplicationInsights.Test\Microsoft.ApplicationInsights.Authentication.Tests\Microsoft.ApplicationInsights.Authentication.Tests.csproj", "{3BD71891-E7AC-4546-AC2F-A12F2649D03F}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution WEB\Src\PerformanceCollector\Perf.Shared.NetFull\Perf.Shared.NetFull.projitems*{0196259c-3582-4f4e-a01f-a8f9ae83b0f3}*SharedItemsImports = 13 @@ -365,6 +367,10 @@ Global {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Debug|Any CPU.Build.0 = Debug|Any CPU {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Release|Any CPU.ActiveCfg = Release|Any CPU {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Release|Any CPU.Build.0 = Release|Any CPU + {3BD71891-E7AC-4546-AC2F-A12F2649D03F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3BD71891-E7AC-4546-AC2F-A12F2649D03F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3BD71891-E7AC-4546-AC2F-A12F2649D03F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3BD71891-E7AC-4546-AC2F-A12F2649D03F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -414,6 +420,7 @@ Global {A1891190-0E43-4E2E-BEFE-1AF0068A0D1E} = {DFCBB4ED-976C-4239-BCAF-8AA21E684E8C} {6062A897-6E55-44C9-BA7A-E1C42946EE51} = {07076842-9CAA-4B4A-8AEF-88DE88CD37AC} {8AAC8DC7-A2FC-4767-BDA8-380F86B64772} = {D2A0AA36-57F7-436C-A7AF-7322927F1734} + {3BD71891-E7AC-4546-AC2F-A12F2649D03F} = {632FB9CE-540D-4451-9FF2-12E89C1492BD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0E0415AF-37CC-4999-8E5B-DD36F75BFD4D} From b0b4b7e0640dd2d37687c74c65e22d0ce44f3e49 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 10:16:39 -0700 Subject: [PATCH 41/93] add .Net v5 to linux build definition --- BASE/.vsts/linux-build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BASE/.vsts/linux-build.yml b/BASE/.vsts/linux-build.yml index 40360a2ed8..6574fe4dd2 100644 --- a/BASE/.vsts/linux-build.yml +++ b/BASE/.vsts/linux-build.yml @@ -20,6 +20,11 @@ steps: displayName: install dotnet core 3.1 inputs: version: 3.1.x + +- task: UseDotNet@2 + displayName: install dotnet 5.0 + inputs: + version: '5.0.x' - task: DotNetCoreCLI@2 displayName: DotNetCoreCLI - Restore Solution From ca89417023e5556e2985e53bfceae4bf63a4ac08 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 10:57:31 -0700 Subject: [PATCH 42/93] cleanup --- .../Microsoft.ApplicationInsights.Authentication.Tests.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj index d5444c64f5..43188a7b8a 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj @@ -3,8 +3,6 @@ net461;net5.0 - - false From 5a4d63e5b955f67b168c8e43155cb1d1502df19d Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 11:05:11 -0700 Subject: [PATCH 43/93] testing change to linux definition --- BASE/.vsts/linux-build.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/BASE/.vsts/linux-build.yml b/BASE/.vsts/linux-build.yml index 6574fe4dd2..5bd21e5f7c 100644 --- a/BASE/.vsts/linux-build.yml +++ b/BASE/.vsts/linux-build.yml @@ -7,6 +7,8 @@ strategy: framework: netcoreapp2.1 netcoreapp3_1: framework: netcoreapp3.1 + net5_0: + framework: net5.0 maxParallel: 2 steps: @@ -39,11 +41,18 @@ steps: projects: "BASE/*.sln" arguments: "--configuration Release --no-restore" +#- task: DotNetCoreCLI@2 +# displayName: DotNetCoreCLI - Test $(framework) +# inputs: +# command: "test" +# projects: "BASE/Test/**/Microsoft.ApplicationInsights.Tests.csproj" +# arguments: "--configuration Release --framework $(framework) --no-build -l trx --filter TestCategory!=WindowsOnly" + - task: DotNetCoreCLI@2 displayName: DotNetCoreCLI - Test $(framework) inputs: command: "test" - projects: "BASE/Test/**/Microsoft.ApplicationInsights.Tests.csproj" + projects: "BASE/Test/**/*.Tests.csproj" arguments: "--configuration Release --framework $(framework) --no-build -l trx --filter TestCategory!=WindowsOnly" ## Publish Test results From e4050ec0d8309aaa7bdffa5ce2becb15424476f7 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 12:18:49 -0700 Subject: [PATCH 44/93] add support for net5.0 to Microsoft.ApplicationInsights.Tests.csproj --- .../Channel/TransmissionTest.cs | 5 +++++ .../Extensibility/TelemetryConfigurationFactoryTest.cs | 2 +- .../Microsoft.ApplicationInsights.Tests.csproj | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Channel/TransmissionTest.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Channel/TransmissionTest.cs index e62cb72d9c..c77a15a1b2 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Channel/TransmissionTest.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Channel/TransmissionTest.cs @@ -220,7 +220,12 @@ public async Task SendAsyncHandleResponseForPartialContentResponse() // VALIDATE Assert.AreEqual(206, result.StatusCode); Assert.AreEqual("5", result.RetryAfterHeader); + +#if NET5_0 + Assert.IsTrue(result.Content == string.Empty); +#else Assert.IsNull(result.Content); +#endif } } diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/TelemetryConfigurationFactoryTest.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/TelemetryConfigurationFactoryTest.cs index 87f084e723..6ce0f6e1ed 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/TelemetryConfigurationFactoryTest.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/TelemetryConfigurationFactoryTest.cs @@ -504,7 +504,7 @@ public void LoadInstanceSetsInstancePropertiesOfTimeSpanTypeFromChildElementValu } [TestMethod] -#if NETCOREAPP3_1 +#if NETCOREAPP3_1 || NET5_0 [ExpectedExceptionWithMessage(typeof(ArgumentException), "Failed to parse configuration value. Property: 'TimeSpanProperty' Reason: String 'TestValue' was not recognized as a valid TimeSpan.")] #else [ExpectedExceptionWithMessage(typeof(ArgumentException), "Failed to parse configuration value. Property: 'TimeSpanProperty' Reason: String was not recognized as a valid TimeSpan.")] diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj index ba15b0357e..5e3625fe58 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj @@ -2,7 +2,7 @@ - net452;net46;netcoreapp2.1;netcoreapp3.1 + net452;net46;netcoreapp2.1;netcoreapp3.1;net5.0 netcoreapp2.1;netcoreapp3.1 true From 5773479c25c37b1b7878ddea79fe22052e0e827f Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 12:25:42 -0700 Subject: [PATCH 45/93] fix for TimeSpan cannot be null --- .../DataContracts/RequestTelemetryTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/DataContracts/RequestTelemetryTest.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/DataContracts/RequestTelemetryTest.cs index af15c7e30b..074f3bdd53 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/DataContracts/RequestTelemetryTest.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/DataContracts/RequestTelemetryTest.cs @@ -34,7 +34,7 @@ public void ParameterlessConstructorInitializesRequiredFields() Assert.IsFalse(request.Source == null); Assert.IsFalse(request.Name == null); Assert.IsFalse(request.ResponseCode == null); - Assert.IsFalse(request.Duration == null); + Assert.IsFalse(request.Duration == default); Assert.IsTrue(request.Success == null); Assert.IsTrue(request.Data.success); Assert.AreEqual(SamplingDecision.None, request.ProactiveSamplingDecision); From 926a6e7ba5a0fa2999ac5f1eeb952d0baae837a0 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 12:52:25 -0700 Subject: [PATCH 46/93] fix --- .../DataContracts/RequestTelemetryTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/DataContracts/RequestTelemetryTest.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/DataContracts/RequestTelemetryTest.cs index 074f3bdd53..5389b27a06 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/DataContracts/RequestTelemetryTest.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/DataContracts/RequestTelemetryTest.cs @@ -34,7 +34,7 @@ public void ParameterlessConstructorInitializesRequiredFields() Assert.IsFalse(request.Source == null); Assert.IsFalse(request.Name == null); Assert.IsFalse(request.ResponseCode == null); - Assert.IsFalse(request.Duration == default); + Assert.IsTrue(request.Duration == default); Assert.IsTrue(request.Success == null); Assert.IsTrue(request.Data.success); Assert.AreEqual(SamplingDecision.None, request.ProactiveSamplingDecision); From 041234197bc028cc048cbc670cb49f75f1535fa7 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 13:04:59 -0700 Subject: [PATCH 47/93] remove extra test project --- BASE/Microsoft.ApplicationInsights.sln | 23 ------------------- .../Class1.cs | 17 -------------- ...cationInsights.Authentication.Tests.csproj | 21 ----------------- Everything.sln | 7 ------ 4 files changed, 68 deletions(-) delete mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Class1.cs delete mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj diff --git a/BASE/Microsoft.ApplicationInsights.sln b/BASE/Microsoft.ApplicationInsights.sln index 3d4dcf286b..624abee285 100644 --- a/BASE/Microsoft.ApplicationInsights.sln +++ b/BASE/Microsoft.ApplicationInsights.sln @@ -40,8 +40,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ApplicationInsigh EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelemetryChannel.Tests", "Test\ServerTelemetryChannel.Test\TelemetryChannel.Tests\TelemetryChannel.Tests.csproj", "{7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ApplicationInsights.Authentication.Tests", "Test\Microsoft.ApplicationInsights.Test\Microsoft.ApplicationInsights.Authentication.Tests\Microsoft.ApplicationInsights.Authentication.Tests.csproj", "{2147F73A-5217-43F2-A409-07667DC952E6}" -EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution Test\TestFramework\Shared\TestFramework.Shared.projitems*{f76c6cbd-29b0-4564-bdcb-c969f8fec136}*SharedItemsImports = 13 @@ -199,26 +197,6 @@ Global {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x64.Build.0 = Release|Any CPU {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x86.ActiveCfg = Release|Any CPU {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x86.Build.0 = Release|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|ARM.ActiveCfg = Debug|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|ARM.Build.0 = Debug|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|x64.ActiveCfg = Debug|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|x64.Build.0 = Debug|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|x86.ActiveCfg = Debug|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Debug|x86.Build.0 = Debug|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Release|Any CPU.Build.0 = Release|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Release|ARM.ActiveCfg = Release|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Release|ARM.Build.0 = Release|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Release|x64.ActiveCfg = Release|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Release|x64.Build.0 = Release|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Release|x86.ActiveCfg = Release|Any CPU - {2147F73A-5217-43F2-A409-07667DC952E6}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -232,7 +210,6 @@ Global {3273D899-D9B3-44FE-B3AB-578E18B2EF90} = {E7B0521E-DA4D-40EA-B55D-ADCBDA69027C} {EF007559-EA01-4D4A-9BEB-8CC661797BE5} = {C2FEEDE5-8CAE-41A4-8932-42D284A86EA7} {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4} = {A61B048F-ECEA-4BED-A2ED-22834E7D4DFB} - {2147F73A-5217-43F2-A409-07667DC952E6} = {C2FEEDE5-8CAE-41A4-8932-42D284A86EA7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F70D4C7C-02FB-4EE9-875A-A2F95EC90EAC} diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Class1.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Class1.cs deleted file mode 100644 index 8c731c50ee..0000000000 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Class1.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Microsoft.ApplicationInsights.Authentication.Tests -{ - using Microsoft.VisualStudio.TestTools.UnitTesting; - - [TestClass] - public class Class1 - { - /// - /// The purpose of this test is to verify that the build system discovers and runs this project. - /// - [TestMethod] - public void HelloWorldTest() - { - Assert.IsTrue(true); - } - } -} diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj deleted file mode 100644 index 43188a7b8a..0000000000 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - - net461;net5.0 - - - - - - - - - - - - - - - - diff --git a/Everything.sln b/Everything.sln index b629e74bbf..07c72a1cf6 100644 --- a/Everything.sln +++ b/Everything.sln @@ -143,8 +143,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Web", "WEB\Src\Web\Web\Web. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xdt.Tests", "LOGGING\test\Xdt.Tests\Xdt.Tests.csproj", "{8AAC8DC7-A2FC-4767-BDA8-380F86B64772}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ApplicationInsights.Authentication.Tests", "BASE\Test\Microsoft.ApplicationInsights.Test\Microsoft.ApplicationInsights.Authentication.Tests\Microsoft.ApplicationInsights.Authentication.Tests.csproj", "{3BD71891-E7AC-4546-AC2F-A12F2649D03F}" -EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution WEB\Src\PerformanceCollector\Perf.Shared.NetFull\Perf.Shared.NetFull.projitems*{0196259c-3582-4f4e-a01f-a8f9ae83b0f3}*SharedItemsImports = 13 @@ -367,10 +365,6 @@ Global {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Debug|Any CPU.Build.0 = Debug|Any CPU {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Release|Any CPU.ActiveCfg = Release|Any CPU {8AAC8DC7-A2FC-4767-BDA8-380F86B64772}.Release|Any CPU.Build.0 = Release|Any CPU - {3BD71891-E7AC-4546-AC2F-A12F2649D03F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3BD71891-E7AC-4546-AC2F-A12F2649D03F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3BD71891-E7AC-4546-AC2F-A12F2649D03F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3BD71891-E7AC-4546-AC2F-A12F2649D03F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -420,7 +414,6 @@ Global {A1891190-0E43-4E2E-BEFE-1AF0068A0D1E} = {DFCBB4ED-976C-4239-BCAF-8AA21E684E8C} {6062A897-6E55-44C9-BA7A-E1C42946EE51} = {07076842-9CAA-4B4A-8AEF-88DE88CD37AC} {8AAC8DC7-A2FC-4767-BDA8-380F86B64772} = {D2A0AA36-57F7-436C-A7AF-7322927F1734} - {3BD71891-E7AC-4546-AC2F-A12F2649D03F} = {632FB9CE-540D-4451-9FF2-12E89C1492BD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0E0415AF-37CC-4999-8E5B-DD36F75BFD4D} From 0bcd87f3e79559763ca67e46e7146d7bf23a26f6 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 13:06:17 -0700 Subject: [PATCH 48/93] cleanup yml --- BASE/.vsts/linux-build.yml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/BASE/.vsts/linux-build.yml b/BASE/.vsts/linux-build.yml index 5bd21e5f7c..75fe34e0a8 100644 --- a/BASE/.vsts/linux-build.yml +++ b/BASE/.vsts/linux-build.yml @@ -41,13 +41,6 @@ steps: projects: "BASE/*.sln" arguments: "--configuration Release --no-restore" -#- task: DotNetCoreCLI@2 -# displayName: DotNetCoreCLI - Test $(framework) -# inputs: -# command: "test" -# projects: "BASE/Test/**/Microsoft.ApplicationInsights.Tests.csproj" -# arguments: "--configuration Release --framework $(framework) --no-build -l trx --filter TestCategory!=WindowsOnly" - - task: DotNetCoreCLI@2 displayName: DotNetCoreCLI - Test $(framework) inputs: @@ -63,16 +56,3 @@ steps: testRunner: "VSTest" testResultsFiles: "**/*.trx" failTaskOnFailedTests: true - -#- task: DotNetCoreCLI@2 -# inputs: -# command: "publish" -# publishWebProjects: "True" -# arguments: "--configuration Release --output $(build.artifactstagingdirectory)" -# zipAfterPublish: "True" - -#- task: PublishBuildArtifacts@1 -# inputs: -# PathtoPublish: "$(build.artifactstagingdirectory)" -# ArtifactName: "drop" -# ArtifactType: "Container" From 57088cb006662775602e93c4492e21dcecf7d331 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 14:49:27 -0700 Subject: [PATCH 49/93] disabling netcoreapp 2.1 in linux build. --- BASE/.vsts/linux-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BASE/.vsts/linux-build.yml b/BASE/.vsts/linux-build.yml index 75fe34e0a8..f60dd3e7ac 100644 --- a/BASE/.vsts/linux-build.yml +++ b/BASE/.vsts/linux-build.yml @@ -3,8 +3,8 @@ pool: strategy: matrix: - netcoreapp2_1: - framework: netcoreapp2.1 + #netcoreapp2_1: + # framework: netcoreapp2.1 netcoreapp3_1: framework: netcoreapp3.1 net5_0: From a7c34626ae59a0bfbebbd652c28c6c51528d28a8 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 17:45:29 -0700 Subject: [PATCH 50/93] migrate AAD tests to Base Test project --- .../Implementation/Authentication}/CredentialEnvelopeTests.cs | 2 +- .../Implementation/Authentication}/MockCredential.cs | 2 +- .../Authentication}/ReflectionCredentialEnvelopeTests.cs | 2 +- .../Microsoft.ApplicationInsights.Tests.csproj | 4 ++++ 4 files changed, 7 insertions(+), 3 deletions(-) rename BASE/Test/Microsoft.ApplicationInsights.Test/{Microsoft.ApplicationInsights.Authentication.Tests => Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication}/CredentialEnvelopeTests.cs (96%) rename BASE/Test/Microsoft.ApplicationInsights.Test/{Microsoft.ApplicationInsights.Authentication.Tests => Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication}/MockCredential.cs (89%) rename BASE/Test/Microsoft.ApplicationInsights.Test/{Microsoft.ApplicationInsights.Authentication.Tests => Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication}/ReflectionCredentialEnvelopeTests.cs (98%) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs similarity index 96% rename from BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs rename to BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs index 9cbcd3d9b1..a4a8e5f477 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Authentication.Tests +namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication { using System; using System.Threading.Tasks; diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/MockCredential.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs similarity index 89% rename from BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/MockCredential.cs rename to BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs index cc757ca853..1ee83b1c71 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/MockCredential.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Authentication.Tests +namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication { using System; using System.Threading; diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs similarity index 98% rename from BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs rename to BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs index f705aba489..32c2d515cf 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs @@ -1,4 +1,4 @@ -namespace Microsoft.ApplicationInsights.Authentication.Tests +namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication { using System; using System.Threading; diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj index 5e3625fe58..6edbe4beef 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj @@ -41,6 +41,10 @@ + + + + From 5d6011a1e30ea9e2d5dd05b7292727275a1cc42d Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 20 May 2021 17:45:45 -0700 Subject: [PATCH 51/93] update Endpoints for Ingestion --- .../Implementation/Endpoints/EndpointContainer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs index 8b55a1886a..36ca9c1b85 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs @@ -30,8 +30,13 @@ internal EndpointContainer(IEndpointProvider endpointProvider) /// Gets the fully formatted endpoint for the ingestion service. internal string FormattedIngestionEndpoint => new Uri(this.Ingestion, "v2/track").AbsoluteUri; + /// Gets the fully formatted endpoint for the ingestion service with support for AAD. + internal string FormattedIngestionAADEndpoint => new Uri(this.Ingestion, "v2.1/track").AbsoluteUri; + /// Gets the fully formatted endpoint for the application id profile service. /// This returns a string without using the Uri for validation because the consuming method needs to do a string replace. internal string FormattedApplicationIdEndpoint => this.Ingestion.AbsoluteUri + "api/profiles/{0}/appId"; + + internal string GetFormattedIngestionEndpoint(bool enableAAD) => enableAAD ? this.FormattedIngestionAADEndpoint : this.FormattedIngestionEndpoint; } } From d4b03786c2b041e11bf574fea7d015b20c1ef698 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 21 May 2021 13:29:01 -0700 Subject: [PATCH 52/93] moving tests to Base Test project --- .../Authentication/CredentialEnvelopeTests.cs | 41 +++++++++++++++---- .../Authentication/MockCredential.cs | 4 +- .../ReflectionCredentialEnvelopeTests.cs | 21 ++++++++-- ...Microsoft.ApplicationInsights.Tests.csproj | 2 +- .../ReflectionCredentialEnvelope.cs | 2 +- 5 files changed, 55 insertions(+), 15 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs index a4a8e5f477..f54f8b0472 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs @@ -8,32 +8,47 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] + [TestCategory("AAD")] public class CredentialEnvelopeTests { + /// + /// This tests verifies that each supported language can create and set a Credential. + /// [TestMethod] public void VerifyCanSetCredential() { +#if NET452 || NET46 + // *THIS IS COMPLICATED* + // In this case, the test runner is NET452 or NET46. + // The Azure.Core.TokenCredential is NOT SUPPORTED in these frameworks, so we cannot run this test. + // This does not affect the end user because we REQUIRE the end user to create their own instance of TokenCredential. + // This ensures that the end user is consuming the AI SDK in one of the newer frameworks. +#elif NET461 var mockCredential = new MockCredential(); var telemetryConfiguration = new TelemetryConfiguration(); telemetryConfiguration.SetCredential(mockCredential); + Assert.IsInstanceOfType(telemetryConfiguration.CredentialEnvelope, typeof(ReflectionCredentialEnvelope)); + Assert.AreEqual(mockCredential, telemetryConfiguration.CredentialEnvelope.Credential); +#elif NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 - var credentialEnvelope = telemetryConfiguration.CredentialEnvelope; -#if NET461 - Assert.IsInstanceOfType(credentialEnvelope, typeof(ReflectionCredentialEnvelope)); -#elif NET5_0 - Assert.IsInstanceOfType(credentialEnvelope, typeof(TokenCredentialEnvelope)); -#else - throw new System.Exception("this is a testing gap."); -#endif + var mockCredential = new MockCredential(); + + var telemetryConfiguration = new TelemetryConfiguration(); + telemetryConfiguration.SetCredential(mockCredential); + Assert.IsInstanceOfType(telemetryConfiguration.CredentialEnvelope, typeof(TokenCredentialEnvelope)); Assert.AreEqual(mockCredential, telemetryConfiguration.CredentialEnvelope.Credential); +#else + throw new NotImplementedException("this is a testing gap"); +#endif } #if NET461 /// /// For older frameworks, TelemetryConfiguration accepts an parameter. + /// This method will use reflection to verify the type at runtime. /// This test is to verify that we cannot set invalid types. /// [TestMethod] @@ -45,7 +60,11 @@ public void VerifyCannotSetInvalidObjectOnTelemetryConfiguration() } #endif -#if NET5_0 +#if NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 + /// + /// This test verifies that both and return identical tokens. + /// This test can only run in frameworks that support both types. + /// [TestMethod] public void VerifyCanGetTokenString() { @@ -62,6 +81,10 @@ public void VerifyCanGetTokenString() Assert.AreEqual(token, tokenFromReflection); } + /// + /// This test verifies that both and return identical tokens. + /// This test can only run in frameworks that support both types. + /// [TestMethod] public async Task VerifyCanGetTokenStringAsync() { diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs index 1ee83b1c71..73c0371cb6 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs @@ -1,4 +1,5 @@ -namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication +#if NET461 || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 +namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication { using System; using System.Threading; @@ -23,3 +24,4 @@ public override AccessToken GetToken(TokenRequestContext requestContext, Cancell } } } +#endif \ No newline at end of file diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs index 32c2d515cf..1339ea3289 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs @@ -1,4 +1,5 @@ -namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication +#if NET461 || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 +namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication { using System; using System.Threading; @@ -15,6 +16,7 @@ /// These tests are to confirm that we can correctly identity classes that implement TokenCredential and address it's methods. ///
[TestClass] + [TestCategory("AAD")] public class ReflectionCredentialEnvelopeTests { [TestMethod] @@ -71,6 +73,18 @@ public void VerifyCannotSetInvalidType() // Assert.AreEqual("TEST TOKEN test/scope", testResult); //} + [TestMethod] + public void VerifyCanMakeTokenRequestContext() + { + var testScope = new string[] { "test/scope" }; + + var requestContext = new TokenRequestContext(testScope); + + var tokenRequestContext = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(testScope); + Assert.IsInstanceOfType(tokenRequestContext, typeof(TokenRequestContext)); + } + + [TestMethod] public void VerifyGetToken_AsLambdaExpression_UsingCompileTimeTypes() { @@ -122,7 +136,7 @@ public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingDynamicTypes() Assert.AreEqual("TEST TOKEN test/scope", testResult); } - #region TestClasses +#region TestClasses private class TestClass1 : Azure.Core.TokenCredential { public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) @@ -159,6 +173,7 @@ public override ValueTask GetTokenAsync(TokenRequestContext request } private class NotTokenCredential2 : NotTokenCredential1 { } - #endregion +#endregion } } +#endif \ No newline at end of file diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj index 6d139c3d39..5c00a4f462 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj @@ -41,7 +41,7 @@ - + diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index ae65f8a527..73b770250c 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -95,7 +95,7 @@ internal static object MakeTokenRequestContext(string[] scopes) { return Activator.CreateInstance( type: Type.GetType("Azure.Core.TokenRequestContext, Azure.Core"), - args: new object[] { scopes, null, null }); + args: new object[] { scopes, null, }); } /// This creates a wrapper for the following method: From a82e3210cd81b9c983a254e80c37129c82278038 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 21 May 2021 13:32:54 -0700 Subject: [PATCH 53/93] remove Authentication.Test project --- BASE/Microsoft.ApplicationInsights.sln | 23 ------------------ ...cationInsights.Authentication.Tests.csproj | 24 ------------------- 2 files changed, 47 deletions(-) delete mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj diff --git a/BASE/Microsoft.ApplicationInsights.sln b/BASE/Microsoft.ApplicationInsights.sln index c301c92c39..624abee285 100644 --- a/BASE/Microsoft.ApplicationInsights.sln +++ b/BASE/Microsoft.ApplicationInsights.sln @@ -40,8 +40,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ApplicationInsigh EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelemetryChannel.Tests", "Test\ServerTelemetryChannel.Test\TelemetryChannel.Tests\TelemetryChannel.Tests.csproj", "{7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.ApplicationInsights.Authentication.Tests", "Test\Microsoft.ApplicationInsights.Test\Microsoft.ApplicationInsights.Authentication.Tests\Microsoft.ApplicationInsights.Authentication.Tests.csproj", "{AADBCDDC-3BD4-434E-B474-B832133AFC84}" -EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution Test\TestFramework\Shared\TestFramework.Shared.projitems*{f76c6cbd-29b0-4564-bdcb-c969f8fec136}*SharedItemsImports = 13 @@ -199,26 +197,6 @@ Global {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x64.Build.0 = Release|Any CPU {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x86.ActiveCfg = Release|Any CPU {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4}.Release|x86.Build.0 = Release|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|ARM.ActiveCfg = Debug|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|ARM.Build.0 = Debug|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|x64.ActiveCfg = Debug|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|x64.Build.0 = Debug|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|x86.ActiveCfg = Debug|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Debug|x86.Build.0 = Debug|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|Any CPU.Build.0 = Release|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|ARM.ActiveCfg = Release|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|ARM.Build.0 = Release|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|x64.ActiveCfg = Release|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|x64.Build.0 = Release|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|x86.ActiveCfg = Release|Any CPU - {AADBCDDC-3BD4-434E-B474-B832133AFC84}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -232,7 +210,6 @@ Global {3273D899-D9B3-44FE-B3AB-578E18B2EF90} = {E7B0521E-DA4D-40EA-B55D-ADCBDA69027C} {EF007559-EA01-4D4A-9BEB-8CC661797BE5} = {C2FEEDE5-8CAE-41A4-8932-42D284A86EA7} {7AB3D817-9CAC-45A7-BA4D-25FA4D690DA4} = {A61B048F-ECEA-4BED-A2ED-22834E7D4DFB} - {AADBCDDC-3BD4-434E-B474-B832133AFC84} = {C2FEEDE5-8CAE-41A4-8932-42D284A86EA7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F70D4C7C-02FB-4EE9-875A-A2F95EC90EAC} diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj deleted file mode 100644 index 6621a65021..0000000000 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Authentication.Tests/Microsoft.ApplicationInsights.Authentication.Tests.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - - net461;net5.0 - - false - - - - - - - - - - - - - - - - - From 393f0a23093a3c942336bd59423d848afcbacffb Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 21 May 2021 13:34:30 -0700 Subject: [PATCH 54/93] remove change to AssemblyInfo --- .../src/Microsoft.ApplicationInsights/Properties/AssemblyInfo.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Properties/AssemblyInfo.cs b/BASE/src/Microsoft.ApplicationInsights/Properties/AssemblyInfo.cs index 85db606155..34c30d94ba 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Properties/AssemblyInfo.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Properties/AssemblyInfo.cs @@ -5,7 +5,6 @@ [assembly: ComVisible(false)] [assembly: InternalsVisibleTo("Microsoft.ApplicationInsights.Tests, PublicKey=" + AssemblyInfo.PublicKey)] -[assembly: InternalsVisibleTo("Microsoft.ApplicationInsights.Authentication.Tests, PublicKey=" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("Microsoft.ApplicationInsights.TelemetryChannel.Tests, PublicKey=" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("Microsoft.ApplicationInsights.AspNetCore.Tests, PublicKey=" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("Microsoft.ApplicationInsights.WorkerService.Tests, PublicKey=" + AssemblyInfo.PublicKey)] From 0bf32bacdbe27193982c95391a9eaf3fbaca5819 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 21 May 2021 14:03:18 -0700 Subject: [PATCH 55/93] resolving merge conflict --- .../Microsoft.ApplicationInsights.AspNetCore.csproj | 2 +- .../test/IntegrationTests.Tests/IntegrationTests.Tests.csproj | 2 +- .../test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj b/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj index b129fffaca..c5cff312b8 100644 --- a/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj +++ b/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj @@ -57,7 +57,7 @@ - + diff --git a/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj b/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj index 6f1e0a3471..0f4ff428b8 100644 --- a/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj +++ b/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj @@ -41,7 +41,7 @@ - + diff --git a/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj b/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj index 2bd3a1f09c..0133fe47d0 100644 --- a/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj +++ b/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj @@ -9,7 +9,7 @@ - + From 6d8a7416fc3f4b25b540d64567edbd9fa0510574 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 21 May 2021 15:52:08 -0700 Subject: [PATCH 56/93] implementing the ingestion api switch. Needs tests --- .../Endpoints/EndpointContainer.cs | 6 ++++ .../Extensibility/TelemetryConfiguration.cs | 28 +++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs index 36ca9c1b85..966e3c31d7 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs @@ -37,6 +37,12 @@ internal EndpointContainer(IEndpointProvider endpointProvider) /// This returns a string without using the Uri for validation because the consuming method needs to do a string replace. internal string FormattedApplicationIdEndpoint => this.Ingestion.AbsoluteUri + "api/profiles/{0}/appId"; + /// + /// Get the Ingestion Endpoint, depending on if AAD is in use. + /// This can be removed after we fully transition no the newer Ingestion API. + /// + /// Boolean to indicate which ingestion service to use. + /// Fully formatted endpoint for the ingestion service. internal string GetFormattedIngestionEndpoint(bool enableAAD) => enableAAD ? this.FormattedIngestionAADEndpoint : this.FormattedIngestionEndpoint; } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index e64e7dbe1d..18639a58dc 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -94,7 +94,8 @@ public TelemetryConfiguration(string instrumentationKey, ITelemetryChannel chann { this.instrumentationKey = instrumentationKey ?? throw new ArgumentNullException(nameof(instrumentationKey)); - SetTelemetryChannelEndpoint(channel, this.EndpointContainer.FormattedIngestionEndpoint, force: true); + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope == null); + SetTelemetryChannelEndpoint(channel, ingestionEndpoint, force: true); var defaultSink = new TelemetrySink(this, channel); defaultSink.Name = "default"; this.telemetrySinks.Add(defaultSink); @@ -241,7 +242,8 @@ public ITelemetryChannel TelemetryChannel if (!this.isDisposed) { this.telemetrySinks.DefaultSink.TelemetryChannel = value; - SetTelemetryChannelEndpoint(this.telemetrySinks.DefaultSink.TelemetryChannel, this.EndpointContainer.FormattedIngestionEndpoint); + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope == null); + SetTelemetryChannelEndpoint(this.telemetrySinks.DefaultSink.TelemetryChannel, ingestionEndpoint); SetTelemetryChannelCredentialEnvelope(value, this.CredentialEnvelope); } } @@ -298,10 +300,8 @@ public string ConnectionString this.EndpointContainer = new EndpointContainer(endpointProvider); // UPDATE TELEMETRY CHANNEL - foreach (var tSink in this.TelemetrySinks) - { - SetTelemetryChannelEndpoint(tSink.TelemetryChannel, this.EndpointContainer.FormattedIngestionEndpoint, force: true); - } + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope == null); + this.SetTelemetryChannelEndpoint(ingestionEndpoint); // UPDATE APPLICATION ID PROVIDER SetApplicationIdEndpoint(this.ApplicationIdProvider, this.EndpointContainer.FormattedApplicationIdEndpoint, force: true); @@ -415,12 +415,20 @@ public void SetCredential(Azure.Core.TokenCredential tokenCredential) { this.CredentialEnvelope = new TokenCredentialEnvelope(tokenCredential); this.SetTelemetryChannelCredentialEnvelope(); + + // Update Ingestion Endpoint. + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: true); + this.SetTelemetryChannelEndpoint(ingestionEndpoint); } #else public void SetCredential(object tokenCredential) { this.CredentialEnvelope = new ReflectionCredentialEnvelope(tokenCredential); this.SetTelemetryChannelCredentialEnvelope(); + + // Update Ingestion Endpoint. + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: true); + this.SetTelemetryChannelEndpoint(ingestionEndpoint); } #endif @@ -516,6 +524,14 @@ private void SetTelemetryChannelCredentialEnvelope() } } + private void SetTelemetryChannelEndpoint(string ingestionEndpoint) + { + foreach (var tSink in this.TelemetrySinks) + { + SetTelemetryChannelEndpoint(tSink.TelemetryChannel, ingestionEndpoint, force: true); + } + } + /// /// Disposes of resources. /// From 5e3ef5dfefa9932f89fdaf67971f47e852752117 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Mon, 24 May 2021 10:15:03 -0700 Subject: [PATCH 57/93] Revert "resolving merge conflict" This reverts commit 0bf32bacdbe27193982c95391a9eaf3fbaca5819. --- .../Microsoft.ApplicationInsights.AspNetCore.csproj | 2 +- .../test/IntegrationTests.Tests/IntegrationTests.Tests.csproj | 2 +- .../test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj b/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj index c5cff312b8..b129fffaca 100644 --- a/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj +++ b/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj @@ -57,7 +57,7 @@ - + diff --git a/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj b/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj index 0f4ff428b8..6f1e0a3471 100644 --- a/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj +++ b/NETCORE/test/IntegrationTests.Tests/IntegrationTests.Tests.csproj @@ -41,7 +41,7 @@ - + diff --git a/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj b/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj index 0133fe47d0..2bd3a1f09c 100644 --- a/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj +++ b/NETCORE/test/IntegrationTests.WebApp/IntegrationTests.WebApp.csproj @@ -9,7 +9,7 @@ - + From 7d6ad679c86f398af8362d5f29d61c0cb1f9e372 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 11:00:24 -0700 Subject: [PATCH 58/93] remove Azure.Core dependency --- .../net452/PublicAPI.Unshipped.txt | 8 +------- .../net46/PublicAPI.Unshipped.txt | 8 +------- .../netstandard2.0/PublicAPI.Unshipped.txt | 10 ++-------- .../Authentication/CredentialEnvelopeTests.cs | 13 ++----------- .../Authentication/TokenCredentialEnvelope.cs | 6 ++++-- .../Microsoft.ApplicationInsights.Tests.csproj | 1 + .../Authentication/CredentialEnvelope.cs | 2 +- .../Extensibility/TelemetryConfiguration.cs | 6 +----- .../Microsoft.ApplicationInsights.csproj | 3 --- 9 files changed, 13 insertions(+), 44 deletions(-) rename BASE/{src/Microsoft.ApplicationInsights => Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests}/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs (86%) diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt index 265e3bc0b1..149b88404b 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt @@ -1,11 +1,5 @@ -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void -Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(object tokenCredential) -> void -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task -static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] + Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt index 265e3bc0b1..149b88404b 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt @@ -1,11 +1,5 @@ -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void -Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(object tokenCredential) -> void -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task -static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] + Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt index 2b6b639256..149b88404b 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,11 +1,5 @@ -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void -Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope -Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(Azure.Core.TokenCredential tokenCredential) -> void -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task -static Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetScopes() -> string[] +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetCredential(object tokenCredential) -> void + Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs index f54f8b0472..4d90cf1253 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs @@ -23,7 +23,7 @@ public void VerifyCanSetCredential() // The Azure.Core.TokenCredential is NOT SUPPORTED in these frameworks, so we cannot run this test. // This does not affect the end user because we REQUIRE the end user to create their own instance of TokenCredential. // This ensures that the end user is consuming the AI SDK in one of the newer frameworks. -#elif NET461 +#elif NET461 || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 var mockCredential = new MockCredential(); var telemetryConfiguration = new TelemetryConfiguration(); @@ -31,17 +31,8 @@ public void VerifyCanSetCredential() Assert.IsInstanceOfType(telemetryConfiguration.CredentialEnvelope, typeof(ReflectionCredentialEnvelope)); Assert.AreEqual(mockCredential, telemetryConfiguration.CredentialEnvelope.Credential); -#elif NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 - - var mockCredential = new MockCredential(); - - var telemetryConfiguration = new TelemetryConfiguration(); - telemetryConfiguration.SetCredential(mockCredential); - - Assert.IsInstanceOfType(telemetryConfiguration.CredentialEnvelope, typeof(TokenCredentialEnvelope)); - Assert.AreEqual(mockCredential, telemetryConfiguration.CredentialEnvelope.Credential); #else - throw new NotImplementedException("this is a testing gap"); +#error This framework is a testing gap. #endif } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs similarity index 86% rename from BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs rename to BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs index 706b40ff1a..2a3a06d84d 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs @@ -1,5 +1,5 @@ -#if NETSTANDARD2_0 -namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +#if !NET452 && !NET46 +namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication { using System; using System.Threading; @@ -7,6 +7,8 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authenticat using Azure.Core; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; + internal class TokenCredentialEnvelope : CredentialEnvelope { private readonly TokenCredential tokenCredential; diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj index 5c00a4f462..a333ed8d41 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Microsoft.ApplicationInsights.Tests.csproj @@ -43,6 +43,7 @@ + diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index 2406ce823f..ace7c6b401 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -7,7 +7,7 @@ /// /// An envelope for an instance of Azure.Core.TokenCredential. /// - public abstract class CredentialEnvelope + internal abstract class CredentialEnvelope { /// /// Source: diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index a66a1f5b1a..f7966f1a41 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -338,7 +338,7 @@ public string ConnectionString /// /// Gets an envelope for Azure.Core.TokenCredential which provides an AAD Authenticated token. /// - public CredentialEnvelope CredentialEnvelope { get; private set; } + internal CredentialEnvelope CredentialEnvelope { get; private set; } /// /// Gets or sets the chain of processors. @@ -409,11 +409,7 @@ public void Dispose() /// Set a TokenCredential for this configuration. /// /// An instance of Azure.Core.TokenCredential. -#if NETSTANDARD2_0 - public void SetCredential(Azure.Core.TokenCredential tokenCredential) => this.CredentialEnvelope = new TokenCredentialEnvelope(tokenCredential); -#else public void SetCredential(object tokenCredential) => this.CredentialEnvelope = new ReflectionCredentialEnvelope(tokenCredential); -#endif internal MetricManager GetMetricManager(bool createIfNotExists) { diff --git a/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj b/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj index 1ed8dd0863..c61484710f 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj +++ b/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj @@ -30,9 +30,6 @@ - - - From 2f3b668c854c2d1c5ec98a0f65144e24fec11039 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 11:03:04 -0700 Subject: [PATCH 59/93] cleanup csproj --- .../Microsoft.ApplicationInsights.csproj | 1 - .../Microsoft.ApplicationInsights.AspNetCore.csproj | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj b/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj index c61484710f..7974809bbd 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj +++ b/BASE/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj @@ -30,7 +30,6 @@ - diff --git a/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj b/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj index ce80104ae1..83bd6d100f 100644 --- a/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj +++ b/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/Microsoft.ApplicationInsights.AspNetCore.csproj @@ -57,7 +57,7 @@ - + From 4b9b76199ec6ef30336dbeaf789cc16526e461b9 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 11:05:39 -0700 Subject: [PATCH 60/93] cleanup EOF --- .../Implementation/Authentication/MockCredential.cs | 2 +- .../Authentication/ReflectionCredentialEnvelopeTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs index 73c0371cb6..fff204b43a 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/MockCredential.cs @@ -24,4 +24,4 @@ public override AccessToken GetToken(TokenRequestContext requestContext, Cancell } } } -#endif \ No newline at end of file +#endif diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs index 1339ea3289..024678f827 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs @@ -176,4 +176,4 @@ private class NotTokenCredential2 : NotTokenCredential1 { } #endregion } } -#endif \ No newline at end of file +#endif From 4cf03ca5054f019d9227a05ff7b5bacacfdf0f1a Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 11:22:46 -0700 Subject: [PATCH 61/93] cleanup test --- .../Authentication/CredentialEnvelopeTests.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs index 4d90cf1253..6f3af2d689 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs @@ -7,6 +7,13 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.VisualStudio.TestTools.UnitTesting; +#if !NET452 && !NET46 + /// + /// These tests do not run in NET452 OR NET46. + /// In these cases, the test runner is NET452 or NET46 and Azure.Core.TokenCredential is NOT SUPPORTED in these frameworks. + /// This does not affect the end user because we REQUIRE the end user to create their own instance of TokenCredential. + /// This ensures that the end user is consuming the AI SDK in one of the newer frameworks. + /// [TestClass] [TestCategory("AAD")] public class CredentialEnvelopeTests @@ -17,29 +24,21 @@ public class CredentialEnvelopeTests [TestMethod] public void VerifyCanSetCredential() { -#if NET452 || NET46 - // *THIS IS COMPLICATED* - // In this case, the test runner is NET452 or NET46. - // The Azure.Core.TokenCredential is NOT SUPPORTED in these frameworks, so we cannot run this test. - // This does not affect the end user because we REQUIRE the end user to create their own instance of TokenCredential. - // This ensures that the end user is consuming the AI SDK in one of the newer frameworks. -#elif NET461 || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 +#if NET461 || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 var mockCredential = new MockCredential(); var telemetryConfiguration = new TelemetryConfiguration(); telemetryConfiguration.SetCredential(mockCredential); Assert.IsInstanceOfType(telemetryConfiguration.CredentialEnvelope, typeof(ReflectionCredentialEnvelope)); - Assert.AreEqual(mockCredential, telemetryConfiguration.CredentialEnvelope.Credential); + Assert.AreEqual(mockCredential, telemetryConfiguration.CredentialEnvelope.Credential, "Credential should be the same instance that we pass in."); #else #error This framework is a testing gap. #endif } -#if NET461 /// - /// For older frameworks, TelemetryConfiguration accepts an parameter. - /// This method will use reflection to verify the type at runtime. + /// TelemetryConfiguration accepts an parameter, and uses reflection to verify the type at runtime /// This test is to verify that we cannot set invalid types. /// [TestMethod] @@ -49,7 +48,6 @@ public void VerifyCannotSetInvalidObjectOnTelemetryConfiguration() var telemetryConfiguration = new TelemetryConfiguration(); telemetryConfiguration.SetCredential(Guid.Empty); } -#endif #if NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 /// @@ -60,6 +58,7 @@ public void VerifyCannotSetInvalidObjectOnTelemetryConfiguration() public void VerifyCanGetTokenString() { var mockCredential = new MockCredential(); + //var token = mockCredential.GetToken(); var tokenCredentialEnvelope = new TokenCredentialEnvelope(mockCredential); var token = tokenCredentialEnvelope.GetToken(); @@ -93,4 +92,5 @@ public async Task VerifyCanGetTokenStringAsync() } #endif } +#endif } From 62bbe38169caade90b3cd5b3440ad9e306e60933 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 12:15:03 -0700 Subject: [PATCH 62/93] cleanup. removing abstract class CredentialEnvelope --- .../ReflectionCredentialEnvelopeTests.cs | 80 ++++++++++--------- ...ryConfigurationCredentialEnvelopeTests.cs} | 56 ++----------- .../Authentication/TokenCredentialEnvelope.cs | 41 ---------- .../Authentication/CredentialConstants.cs | 25 ++++++ .../Authentication/CredentialEnvelope.cs | 44 ---------- .../ReflectionCredentialEnvelope.cs | 29 ++++--- .../Extensibility/TelemetryConfiguration.cs | 2 +- 7 files changed, 95 insertions(+), 182 deletions(-) rename BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/{CredentialEnvelopeTests.cs => TelemetryConfigurationCredentialEnvelopeTests.cs} (50%) delete mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs create mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs delete mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs index 024678f827..f5f2e65dd9 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs @@ -1,4 +1,4 @@ -#if NET461 || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 +#if !NET452 && !NET46 namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication { using System; @@ -15,6 +15,12 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati /// We must use reflection to interact with this class. /// These tests are to confirm that we can correctly identity classes that implement TokenCredential and address it's methods. /// + /// + /// These tests do not run in NET452 OR NET46. + /// In these cases, the test runner is NET452 or NET46 and Azure.Core.TokenCredential is NOT SUPPORTED in these frameworks. + /// This does not affect the end user because we REQUIRE the end user to create their own instance of TokenCredential. + /// This ensures that the end user is consuming the AI SDK in one of the newer frameworks. + /// [TestClass] [TestCategory("AAD")] public class ReflectionCredentialEnvelopeTests @@ -41,50 +47,50 @@ public void VerifyCannotSetInvalidType() _ = new ReflectionCredentialEnvelope(Guid.Empty); } - //[TestMethod] - //public void VerifyGetTokenAsExpression_UsingCompileTimeTypes() - //{ - // var mockCredential = new MockCredential(); - // var requestContext = new TokenRequestContext(new string[] { "test/scope" }); - - // var expression = ReflectionCredentialEnvelope.GetTokenAsExpression(mockCredential, requestContext).Compile(); - - // var testResult = expression(mockCredential, requestContext, CancellationToken.None); - // Assert.AreEqual("TEST TOKEN test/scope", testResult); - //} + [TestMethod] + public void VerifyCanMakeTokenRequestContext() + { + var testScope = new string[] { "test/scope" }; - ///// - ///// This more closely represents how this would be used in a production environment. - ///// - //[TestMethod] - //public void VerifyGetTokenAsExpression_UsingDynamicTypes() - //{ - // // This currently throws ArgumentExceptions: - // // ParameterExpression of type 'Microsoft.ApplicationInsights.Authentication.Tests.MockCredential' cannot be used for delegate parameter of type 'System.Object' - // // ParameterExpression of type 'Azure.Core.TokenRequestContext' cannot be used for delegate parameter of type 'System.Object' + var requestContext = new TokenRequestContext(testScope); + var tokenRequestContextViaReflection = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(testScope); + Assert.IsInstanceOfType(tokenRequestContextViaReflection, typeof(TokenRequestContext)); + Assert.AreEqual(requestContext, tokenRequestContextViaReflection); + } - // var mockCredential = (object)new MockCredential(); - // var requestContext = ReflectionCredentialEnvelope.MakeTokenRequestContext(new[] { "test/scope" }); + /// + /// This test verifies that both and return identical tokens. + /// + [TestMethod] + public void VerifyCanGetToken() + { + var requestContext = new TokenRequestContext(scopes: CredentialConstants.GetScopes()); + var mockCredential = new MockCredential(); + var tokenUsingTypes = mockCredential.GetToken(requestContext, CancellationToken.None); - // var expression = ReflectionCredentialEnvelope.GetTokenAsExpression(mockCredential, requestContext).Compile(); + var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); + var tokenUsingReflection = reflectionCredentialEnvelope.GetToken(); - // var testResult = expression(mockCredential, requestContext, CancellationToken.None); - // Assert.AreEqual("TEST TOKEN test/scope", testResult); - //} + Assert.AreEqual(tokenUsingTypes.Token, tokenUsingReflection); + } + /// + /// This test verifies that both and return identical tokens. + /// [TestMethod] - public void VerifyCanMakeTokenRequestContext() + public async Task VerifyCanGetTokenAsync() { - var testScope = new string[] { "test/scope" }; + var requestContext = new TokenRequestContext(scopes: CredentialConstants.GetScopes()); + var mockCredential = new MockCredential(); + var tokenUsingTypes = await mockCredential.GetTokenAsync(requestContext, CancellationToken.None); - var requestContext = new TokenRequestContext(testScope); + var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); + var tokenUsingReflection = await reflectionCredentialEnvelope.GetTokenAsync(); - var tokenRequestContext = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(testScope); - Assert.IsInstanceOfType(tokenRequestContext, typeof(TokenRequestContext)); + Assert.AreEqual(tokenUsingTypes.Token, tokenUsingReflection); } - [TestMethod] public void VerifyGetToken_AsLambdaExpression_UsingCompileTimeTypes() { @@ -136,7 +142,7 @@ public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingDynamicTypes() Assert.AreEqual("TEST TOKEN test/scope", testResult); } -#region TestClasses + #region TestClasses private class TestClass1 : Azure.Core.TokenCredential { public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) @@ -152,10 +158,10 @@ public override ValueTask GetTokenAsync(TokenRequestContext request private class TestClass2 : TestClass1 { } - private abstract class NotTokenCredential + private abstract class NotTokenCredential { public abstract AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken); - + public abstract ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken); } @@ -173,7 +179,7 @@ public override ValueTask GetTokenAsync(TokenRequestContext request } private class NotTokenCredential2 : NotTokenCredential1 { } -#endregion + #endregion } } #endif diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TelemetryConfigurationCredentialEnvelopeTests.cs similarity index 50% rename from BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs rename to BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TelemetryConfigurationCredentialEnvelopeTests.cs index 6f3af2d689..e931c295e2 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/CredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TelemetryConfigurationCredentialEnvelopeTests.cs @@ -1,3 +1,4 @@ +#if !NET452 && !NET46 namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication { using System; @@ -7,7 +8,9 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.VisualStudio.TestTools.UnitTesting; -#if !NET452 && !NET46 + /// + /// These tests verify that can receive and store an instance of . + /// /// /// These tests do not run in NET452 OR NET46. /// In these cases, the test runner is NET452 or NET46 and Azure.Core.TokenCredential is NOT SUPPORTED in these frameworks. @@ -16,7 +19,7 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati /// [TestClass] [TestCategory("AAD")] - public class CredentialEnvelopeTests + public class TelemetryConfigurationCredentialEnvelopeTests { /// /// This tests verifies that each supported language can create and set a Credential. @@ -24,7 +27,6 @@ public class CredentialEnvelopeTests [TestMethod] public void VerifyCanSetCredential() { -#if NET461 || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 var mockCredential = new MockCredential(); var telemetryConfiguration = new TelemetryConfiguration(); @@ -32,9 +34,6 @@ public void VerifyCanSetCredential() Assert.IsInstanceOfType(telemetryConfiguration.CredentialEnvelope, typeof(ReflectionCredentialEnvelope)); Assert.AreEqual(mockCredential, telemetryConfiguration.CredentialEnvelope.Credential, "Credential should be the same instance that we pass in."); -#else -#error This framework is a testing gap. -#endif } /// @@ -48,49 +47,6 @@ public void VerifyCannotSetInvalidObjectOnTelemetryConfiguration() var telemetryConfiguration = new TelemetryConfiguration(); telemetryConfiguration.SetCredential(Guid.Empty); } - -#if NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 - /// - /// This test verifies that both and return identical tokens. - /// This test can only run in frameworks that support both types. - /// - [TestMethod] - public void VerifyCanGetTokenString() - { - var mockCredential = new MockCredential(); - //var token = mockCredential.GetToken(); - - var tokenCredentialEnvelope = new TokenCredentialEnvelope(mockCredential); - var token = tokenCredentialEnvelope.GetToken(); - Assert.IsNotNull(token); - - var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); - var tokenFromReflection = reflectionCredentialEnvelope.GetToken(); - Assert.IsNotNull(tokenFromReflection); - - Assert.AreEqual(token, tokenFromReflection); - } - - /// - /// This test verifies that both and return identical tokens. - /// This test can only run in frameworks that support both types. - /// - [TestMethod] - public async Task VerifyCanGetTokenStringAsync() - { - var mockCredential = new MockCredential(); - - var tokenCredentialEnvelope = new TokenCredentialEnvelope(mockCredential); - var token = await tokenCredentialEnvelope.GetTokenAsync(); - Assert.IsNotNull(token); - - var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); - var tokenFromReflection = await reflectionCredentialEnvelope.GetTokenAsync(); - Assert.IsNotNull(tokenFromReflection); - - Assert.AreEqual(token, tokenFromReflection); - } -#endif } -#endif } +#endif diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs deleted file mode 100644 index 2a3a06d84d..0000000000 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TokenCredentialEnvelope.cs +++ /dev/null @@ -1,41 +0,0 @@ -#if !NET452 && !NET46 -namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication -{ - using System; - using System.Threading; - using System.Threading.Tasks; - - using Azure.Core; - - using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; - - internal class TokenCredentialEnvelope : CredentialEnvelope - { - private readonly TokenCredential tokenCredential; - private readonly TokenRequestContext tokenRequestContext; - - public TokenCredentialEnvelope(TokenCredential tokenCredential) - { - this.tokenCredential = tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential)); - this.tokenRequestContext = new TokenRequestContext(scopes: GetScopes()); - } - - /// - public override object Credential => this.tokenCredential; - - /// - public override string GetToken(CancellationToken cancellationToken = default) - { - var accessToken = this.tokenCredential.GetToken(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken); - return accessToken.Token; - } - - /// - public override async Task GetTokenAsync(CancellationToken cancellationToken = default) - { - var accessToken = await this.tokenCredential.GetTokenAsync(requestContext: this.tokenRequestContext, cancellationToken: cancellationToken).ConfigureAwait(false); - return accessToken.Token; - } - } -} -#endif diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs new file mode 100644 index 0000000000..c7acfb5138 --- /dev/null +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs @@ -0,0 +1,25 @@ +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + internal static class CredentialConstants + { + /// + /// Source: + /// (https://docs.microsoft.com/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). + /// (https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope). + /// + public const string AzureMonitorScope = "https://monitor.azure.com//.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. + + + /// + /// Get scopes for Azure Monitor as an array. + /// + /// An array of scopes. + public static string[] GetScopes() => new string[] { AzureMonitorScope }; + } +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs deleted file mode 100644 index ace7c6b401..0000000000 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication -{ - using System; - using System.Threading; - using System.Threading.Tasks; - - /// - /// An envelope for an instance of Azure.Core.TokenCredential. - /// - internal abstract class CredentialEnvelope - { - /// - /// Source: - /// (https://docs.microsoft.com/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). - /// (https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope). - /// - private const string Scope = "https://monitor.azure.com//.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. - - /// - /// Gets the TokenCredential object held by this class. - /// - public abstract object Credential { get; } - - /// - /// Gets an Azure.Core.AccessToken. - /// - /// The System.Threading.CancellationToken to use. - /// A valid Azure.Core.AccessToken. - public abstract string GetToken(CancellationToken cancellationToken = default); - - /// - /// Gets an Azure.Core.AccessToken. - /// - /// The System.Threading.CancellationToken to use. - /// A valid Azure.Core.AccessToken. - public abstract Task GetTokenAsync(CancellationToken cancellationToken = default); - - /// - /// Get scopes for Azure Monitor as an array. - /// - /// An array of scopes. - protected static string[] GetScopes() => new string[] { Scope }; - } -} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 73b770250c..0b42b511a9 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -6,13 +6,14 @@ using System.Threading.Tasks; /// - /// This is an implementation of that uses reflection to interact with the Azure.Core library. + /// This is an envelope for an instance of Azure.Core.TokenCredential. + /// This class uses reflection to interact with the Azure.Core library. /// /// /// Our SDK currently targets net452, net46, and netstandard2.0. /// Azure.Core.TokenCredential is only available for netstandard2.0. /// - internal class ReflectionCredentialEnvelope : CredentialEnvelope + internal class ReflectionCredentialEnvelope { private readonly object tokenCredential; private readonly object tokenRequestContext; @@ -27,7 +28,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) if (tokenCredential.GetType().IsSubclassOf(Type.GetType("Azure.Core.TokenCredential, Azure.Core"))) { - this.tokenRequestContext = AzureCore.MakeTokenRequestContext(scopes: GetScopes()); + this.tokenRequestContext = AzureCore.MakeTokenRequestContext(scopes: CredentialConstants.GetScopes()); } else { @@ -35,17 +36,27 @@ public ReflectionCredentialEnvelope(object tokenCredential) } } - /// - public override object Credential => this.tokenCredential; + /// + /// Gets the TokenCredential object held by this class. + /// + public object Credential => this.tokenCredential; - /// - public override string GetToken(CancellationToken cancellationToken = default) + /// + /// Gets an Azure.Core.AccessToken. + /// + /// The System.Threading.CancellationToken to use. + /// A valid Azure.Core.AccessToken. + public string GetToken(CancellationToken cancellationToken = default) { return AzureCore.InvokeGetToken(this.tokenCredential, this.tokenRequestContext, cancellationToken); } - /// - public override Task GetTokenAsync(CancellationToken cancellationToken = default) + /// + /// Gets an Azure.Core.AccessToken. + /// + /// The System.Threading.CancellationToken to use. + /// A valid Azure.Core.AccessToken. + public Task GetTokenAsync(CancellationToken cancellationToken = default) { return AzureCore.InvokeGetTokenAsync(this.tokenCredential, this.tokenRequestContext, cancellationToken); } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index f7966f1a41..08379c2523 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -338,7 +338,7 @@ public string ConnectionString /// /// Gets an envelope for Azure.Core.TokenCredential which provides an AAD Authenticated token. /// - internal CredentialEnvelope CredentialEnvelope { get; private set; } + internal ReflectionCredentialEnvelope CredentialEnvelope { get; private set; } /// /// Gets or sets the chain of processors. From aac78edd659be65d4118813c53a44652d23184e9 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 13:03:57 -0700 Subject: [PATCH 63/93] fxcop --- .../Implementation/Authentication/CredentialConstants.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs index c7acfb5138..3d6f253606 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs @@ -15,7 +15,6 @@ internal static class CredentialConstants /// public const string AzureMonitorScope = "https://monitor.azure.com//.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. - /// /// Get scopes for Azure Monitor as an array. /// From 080220f931d04b926e9aee4183576e3a8446e8d6 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 13:44:08 -0700 Subject: [PATCH 64/93] merge conflict --- .../Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs | 3 +-- .../Channel/InMemoryTransmitter.cs | 2 +- .../Microsoft.ApplicationInsights/Channel/Transmission.cs | 3 +-- .../Authentication/ISupportCredentialEnvelope.cs | 4 ++-- .../Extensibility/TelemetryConfiguration.cs | 2 +- .../Implementation/TransmissionSender.cs | 2 +- .../src/ServerTelemetryChannel/Implementation/Transmitter.cs | 2 +- BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs | 5 ++--- 8 files changed, 10 insertions(+), 13 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs index ed9acb7f6c..bb5ff432e4 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs @@ -103,8 +103,7 @@ public TimeSpan SendingInterval /// sets /// which is used to set just before calling . /// - [EditorBrowsable(EditorBrowsableState.Never)] - public CredentialEnvelope CredentialEnvelope + ReflectionCredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope { get => this.transmitter.CredentialEnvelope; set => this.transmitter.CredentialEnvelope = value; diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs index 24e6af07bd..8dcedabf4a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs @@ -71,7 +71,7 @@ internal TimeSpan SendingInterval /// sets /// which is used to set just before calling . /// - internal CredentialEnvelope CredentialEnvelope { get; set; } + internal ReflectionCredentialEnvelope CredentialEnvelope { get; set; } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index 9f2ca8cf3a..b5460f92ad 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -146,8 +146,7 @@ public ICollection TelemetryItems /// Gets or sets the . /// This is used include an AAD token on HTTP Requests sent to ingestion. /// - [EditorBrowsable(EditorBrowsableState.Never)] - public CredentialEnvelope CredentialEnvelope { get; set; } + internal ReflectionCredentialEnvelope CredentialEnvelope { get; set; } /// /// Gets the flush async id for the transmission. diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs index 3a79b29bbb..6b5795bd4f 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs @@ -9,11 +9,11 @@ /// /// This interface defines a class that accepts the as a property. /// - public interface ISupportCredentialEnvelope + internal interface ISupportCredentialEnvelope { /// /// Gets or sets the . /// - CredentialEnvelope CredentialEnvelope { get; set; } + ReflectionCredentialEnvelope CredentialEnvelope { get; set; } } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 96e336c3e0..09dce6013a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -496,7 +496,7 @@ private static void SetTelemetryChannelEndpoint(ITelemetryChannel channel, strin } } - private static void SetTelemetryChannelCredentialEnvelope(ITelemetryChannel telemetryChannel, CredentialEnvelope credentialEnvelope) + private static void SetTelemetryChannelCredentialEnvelope(ITelemetryChannel telemetryChannel, ReflectionCredentialEnvelope credentialEnvelope) { if (telemetryChannel is ISupportCredentialEnvelope tc) { diff --git a/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs b/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs index d482c43d05..430b09b7e4 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs @@ -115,7 +115,7 @@ public virtual int ThrottleWindow /// sets and then sets /// which is used to set just before calling . /// - public CredentialEnvelope CredentialEnvelope { get; set; } + internal ReflectionCredentialEnvelope CredentialEnvelope { get; set; } public virtual bool Enqueue(Func transmissionGetter) { diff --git a/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs b/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs index f4ec7fcad6..78c36c7828 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs @@ -69,7 +69,7 @@ internal Transmitter( /// sets and then sets /// which is used to set just before calling . /// - public CredentialEnvelope CredentialEnvelope + internal ReflectionCredentialEnvelope CredentialEnvelope { get => this.Sender.CredentialEnvelope; set => this.Sender.CredentialEnvelope = value; diff --git a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs index f9ac16ab35..61016132d4 100644 --- a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs +++ b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs @@ -252,8 +252,7 @@ public int LocalThrottleWindow /// sets and then sets /// which is used to set just before calling . /// - [EditorBrowsable(EditorBrowsableState.Never)] - public CredentialEnvelope CredentialEnvelope + ReflectionCredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope { get => this.Transmitter.CredentialEnvelope; set => this.Transmitter.CredentialEnvelope = value; @@ -373,7 +372,7 @@ public void Initialize(TelemetryConfiguration configuration) throw new ArgumentNullException(nameof(configuration)); } - this.CredentialEnvelope = configuration.CredentialEnvelope; + ((ISupportCredentialEnvelope)this).CredentialEnvelope = configuration.CredentialEnvelope; this.Transmitter.Initialize(); From 06132dea8d612897bba7ecb24e1b1d6fc7c13979 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 13:49:30 -0700 Subject: [PATCH 65/93] resolve merge conflicts --- .../net452/PublicAPI.Unshipped.txt | 4 +-- .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +-- .../Channel/InMemoryChannel.cs | 4 +-- .../Channel/InMemoryTransmitter.cs | 2 +- .../Implementation/TransmissionSender.cs | 2 +- .../Implementation/Transmitter.cs | 26 +++++++++---------- .../ServerTelemetryChannel.cs | 4 +-- 7 files changed, 21 insertions(+), 25 deletions(-) diff --git a/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/net452/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/net452/PublicAPI.Unshipped.txt index 26df0ca25d..2baf8ba033 100644 --- a/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/net452/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/net452/PublicAPI.Unshipped.txt @@ -1,3 +1 @@ -Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task -Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope -Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.CredentialEnvelope.set -> void \ No newline at end of file +Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task \ No newline at end of file diff --git a/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/netstandard2.0/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/netstandard2.0/PublicAPI.Unshipped.txt index 26df0ca25d..2baf8ba033 100644 --- a/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/netstandard2.0/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.AI.ServerTelemetryChannel.dll/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,3 +1 @@ -Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task -Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope -Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.CredentialEnvelope.set -> void \ No newline at end of file +Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.ServerTelemetryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task \ No newline at end of file diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs index bb5ff432e4..ef8088ef06 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs @@ -96,11 +96,11 @@ public TimeSpan SendingInterval } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// FOR INTERNAL USE. Customers should use instead. /// /// - /// sets + /// sets /// which is used to set just before calling . /// ReflectionCredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs index 8dcedabf4a..1a84b07abf 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs @@ -68,7 +68,7 @@ internal TimeSpan SendingInterval /// Gets or sets the which is used for AAD. /// /// - /// sets + /// sets /// which is used to set just before calling . /// internal ReflectionCredentialEnvelope CredentialEnvelope { get; set; } diff --git a/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs b/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs index 430b09b7e4..87c4f37c70 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs @@ -112,7 +112,7 @@ public virtual int ThrottleWindow /// Gets or sets the which is used for AAD. /// /// - /// sets and then sets + /// sets and then sets /// which is used to set just before calling . /// internal ReflectionCredentialEnvelope CredentialEnvelope { get; set; } diff --git a/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs b/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs index 78c36c7828..e80a0d955a 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs @@ -62,19 +62,6 @@ internal Transmitter( public string StorageFolder { get; set; } - /// - /// Gets or sets the which is used for AAD. - /// - /// - /// sets and then sets - /// which is used to set just before calling . - /// - internal ReflectionCredentialEnvelope CredentialEnvelope - { - get => this.Sender.CredentialEnvelope; - set => this.Sender.CredentialEnvelope = value; - } - public int MaxBufferCapacity { get @@ -140,6 +127,19 @@ public BackoffLogicManager BackoffLogicManager get { return this.backoffLogicManager; } } + /// + /// Gets or sets the which is used for AAD. + /// + /// + /// sets and then sets + /// which is used to set just before calling . + /// + internal ReflectionCredentialEnvelope CredentialEnvelope + { + get => this.Sender.CredentialEnvelope; + set => this.Sender.CredentialEnvelope = value; + } + /// /// Releases resources used by this instance. /// diff --git a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs index 61016132d4..b688fa5971 100644 --- a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs +++ b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs @@ -245,11 +245,11 @@ public int LocalThrottleWindow } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// DO NOT SET DIRECTLY. Use instead. /// /// - /// sets and then sets + /// sets and then sets /// which is used to set just before calling . /// ReflectionCredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope From ad1f387001e0971a0c980cf613598da6cb2676db Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 13:51:40 -0700 Subject: [PATCH 66/93] revert changes to EndpointContainer --- .../Implementation/Endpoints/EndpointContainer.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs index 36ca9c1b85..8b55a1886a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs @@ -30,13 +30,8 @@ internal EndpointContainer(IEndpointProvider endpointProvider) /// Gets the fully formatted endpoint for the ingestion service. internal string FormattedIngestionEndpoint => new Uri(this.Ingestion, "v2/track").AbsoluteUri; - /// Gets the fully formatted endpoint for the ingestion service with support for AAD. - internal string FormattedIngestionAADEndpoint => new Uri(this.Ingestion, "v2.1/track").AbsoluteUri; - /// Gets the fully formatted endpoint for the application id profile service. /// This returns a string without using the Uri for validation because the consuming method needs to do a string replace. internal string FormattedApplicationIdEndpoint => this.Ingestion.AbsoluteUri + "api/profiles/{0}/appId"; - - internal string GetFormattedIngestionEndpoint(bool enableAAD) => enableAAD ? this.FormattedIngestionAADEndpoint : this.FormattedIngestionEndpoint; } } From 7bfe41e509b563bff6a9e3af1c0b865db92b3965 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 14:37:05 -0700 Subject: [PATCH 67/93] add interface ICredentialEnvelope --- .../Authentication/ICredentialEnvelope.cs | 27 +++++++++++++++++++ .../ReflectionCredentialEnvelope.cs | 4 +-- .../Extensibility/TelemetryConfiguration.cs | 2 +- 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs new file mode 100644 index 0000000000..7deca591c6 --- /dev/null +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs @@ -0,0 +1,27 @@ +namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication +{ + using System.Threading; + using System.Threading.Tasks; + + internal interface ICredentialEnvelope + { + /// + /// Gets the TokenCredential instance held by this class. + /// + object Credential { get; } + + /// + /// Gets an Azure.Core.AccessToken. + /// + /// The System.Threading.CancellationToken to use. + /// A valid Azure.Core.AccessToken. + string GetToken(CancellationToken cancellationToken = default); + + /// + /// Gets an Azure.Core.AccessToken. + /// + /// The System.Threading.CancellationToken to use. + /// A valid Azure.Core.AccessToken. + Task GetTokenAsync(CancellationToken cancellationToken = default); + } +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 0b42b511a9..b5b7687beb 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -13,7 +13,7 @@ /// Our SDK currently targets net452, net46, and netstandard2.0. /// Azure.Core.TokenCredential is only available for netstandard2.0. /// - internal class ReflectionCredentialEnvelope + internal class ReflectionCredentialEnvelope : ICredentialEnvelope { private readonly object tokenCredential; private readonly object tokenRequestContext; @@ -37,7 +37,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) } /// - /// Gets the TokenCredential object held by this class. + /// Gets the TokenCredential instance held by this class. /// public object Credential => this.tokenCredential; diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 08379c2523..8de0511370 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -338,7 +338,7 @@ public string ConnectionString /// /// Gets an envelope for Azure.Core.TokenCredential which provides an AAD Authenticated token. /// - internal ReflectionCredentialEnvelope CredentialEnvelope { get; private set; } + internal ICredentialEnvelope CredentialEnvelope { get; private set; } /// /// Gets or sets the chain of processors. From 6b00f3b8252359c72b7134aa8ac8e5e37778082e Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 15:19:43 -0700 Subject: [PATCH 68/93] exception handling --- .../ReflectionCredentialEnvelopeTests.cs | 97 ++++++++++++------- .../ReflectionCredentialEnvelope.cs | 34 ++++++- .../Implementation/Tracing/CoreEventSource.cs | 3 + 3 files changed, 95 insertions(+), 39 deletions(-) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs index f5f2e65dd9..3618956480 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs @@ -10,6 +10,8 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; + /// /// The cannot take a dependency on . /// We must use reflection to interact with this class. @@ -59,43 +61,36 @@ public void VerifyCanMakeTokenRequestContext() Assert.AreEqual(requestContext, tokenRequestContextViaReflection); } - /// - /// This test verifies that both and return identical tokens. - /// [TestMethod] - public void VerifyCanGetToken() + public void VerifyGetToken_UsingCompileTimeTypes() { - var requestContext = new TokenRequestContext(scopes: CredentialConstants.GetScopes()); var mockCredential = new MockCredential(); - var tokenUsingTypes = mockCredential.GetToken(requestContext, CancellationToken.None); + var requestContext = new TokenRequestContext(new string[] { "test/scope" }); - var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); - var tokenUsingReflection = reflectionCredentialEnvelope.GetToken(); + var testResult = ReflectionCredentialEnvelope.AzureCore.InvokeGetToken(mockCredential, requestContext, CancellationToken.None); - Assert.AreEqual(tokenUsingTypes.Token, tokenUsingReflection); + Assert.AreEqual("TEST TOKEN test/scope", testResult); } - /// - /// This test verifies that both and return identical tokens. - /// [TestMethod] - public async Task VerifyCanGetTokenAsync() + public async Task VerifyGetTokenAsync_UsingCompileTimeTypes() { - var requestContext = new TokenRequestContext(scopes: CredentialConstants.GetScopes()); var mockCredential = new MockCredential(); - var tokenUsingTypes = await mockCredential.GetTokenAsync(requestContext, CancellationToken.None); + var requestContext = new TokenRequestContext(new string[] { "test/scope" }); - var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); - var tokenUsingReflection = await reflectionCredentialEnvelope.GetTokenAsync(); + var testResult = await ReflectionCredentialEnvelope.AzureCore.InvokeGetTokenAsync(mockCredential, requestContext, CancellationToken.None); - Assert.AreEqual(tokenUsingTypes.Token, tokenUsingReflection); + Assert.AreEqual("TEST TOKEN test/scope", testResult); } + /// + /// This more closely represents how this would be used in a production environment. + /// [TestMethod] - public void VerifyGetToken_AsLambdaExpression_UsingCompileTimeTypes() + public void VerifyGetToken_UsingDynamicTypes() { - var mockCredential = new MockCredential(); - var requestContext = new TokenRequestContext(new string[] { "test/scope" }); + var mockCredential = (object)new MockCredential(); + var requestContext = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(new[] { "test/scope" }); var testResult = ReflectionCredentialEnvelope.AzureCore.InvokeGetToken(mockCredential, requestContext, CancellationToken.None); @@ -106,43 +101,73 @@ public void VerifyGetToken_AsLambdaExpression_UsingCompileTimeTypes() /// This more closely represents how this would be used in a production environment. /// [TestMethod] - public void VerifyGetToken_AsLambdaExpression_UsingDynamicTypes() + public async Task VerifyGetTokenAsync_UsingDynamicTypes() { var mockCredential = (object)new MockCredential(); var requestContext = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(new[] { "test/scope" }); - var testResult = ReflectionCredentialEnvelope.AzureCore.InvokeGetToken(mockCredential, requestContext, CancellationToken.None); + var testResult = await ReflectionCredentialEnvelope.AzureCore.InvokeGetTokenAsync(mockCredential, requestContext, CancellationToken.None); Assert.AreEqual("TEST TOKEN test/scope", testResult); } - + /// + /// This test verifies that both and return identical tokens. + /// [TestMethod] - public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingCompileTimeTypes() + public void VerifyGetToken_ReturnsValidToken() { + var requestContext = new TokenRequestContext(scopes: CredentialConstants.GetScopes()); var mockCredential = new MockCredential(); - var requestContext = new TokenRequestContext(new string[] { "test/scope" }); + var tokenUsingTypes = mockCredential.GetToken(requestContext, CancellationToken.None); - var testResult = await ReflectionCredentialEnvelope.AzureCore.InvokeGetTokenAsync(mockCredential, requestContext, CancellationToken.None); + var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); + var tokenUsingReflection = reflectionCredentialEnvelope.GetToken(); - Assert.AreEqual("TEST TOKEN test/scope", testResult); + Assert.AreEqual(tokenUsingTypes.Token, tokenUsingReflection); } /// - /// This more closely represents how this would be used in a production environment. + /// This test verifies that both and return identical tokens. /// [TestMethod] - public async Task VerifyGetTokenAsync_AsLambdaExpression_UsingDynamicTypes() + public async Task VerifyGetTokenAsync_ReturnsValidToken() { - var mockCredential = (object)new MockCredential(); - var requestContext = ReflectionCredentialEnvelope.AzureCore.MakeTokenRequestContext(new[] { "test/scope" }); + var requestContext = new TokenRequestContext(scopes: CredentialConstants.GetScopes()); + var mockCredential = new MockCredential(); + var tokenUsingTypes = await mockCredential.GetTokenAsync(requestContext, CancellationToken.None); - var testResult = await ReflectionCredentialEnvelope.AzureCore.InvokeGetTokenAsync(mockCredential, requestContext, CancellationToken.None); + var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); + var tokenUsingReflection = await reflectionCredentialEnvelope.GetTokenAsync(); - Assert.AreEqual("TEST TOKEN test/scope", testResult); + Assert.AreEqual(tokenUsingTypes.Token, tokenUsingReflection); + } + + [TestMethod] + public void VerifyGetToken_IfCredentialThrowsException_EnvelopeReturnsNull() + { + Mock mockTokenCredential = new Mock(); + mockTokenCredential.Setup(x => x.GetToken(It.IsAny(), It.IsAny())).Throws(new NotImplementedException()); + var mockCredential = mockTokenCredential.Object; + + var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); + var token = reflectionCredentialEnvelope.GetToken(); + Assert.IsNull(token); + } + + [TestMethod] + public async Task VerifyGetTokenAsync_IfCredentialThrowsException_EnvelopeReturnsNull() + { + Mock mockTokenCredential = new Mock(); + mockTokenCredential.Setup(x => x.GetTokenAsync(It.IsAny(), It.IsAny())).Throws(new NotImplementedException()); + var mockCredential = mockTokenCredential.Object; + + var reflectionCredentialEnvelope = new ReflectionCredentialEnvelope(mockCredential); + var token = await reflectionCredentialEnvelope.GetTokenAsync(); + Assert.IsNull(token); } - #region TestClasses +#region TestClasses private class TestClass1 : Azure.Core.TokenCredential { public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) @@ -179,7 +204,7 @@ public override ValueTask GetTokenAsync(TokenRequestContext request } private class NotTokenCredential2 : NotTokenCredential1 { } - #endregion +#endregion } } #endif diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index b5b7687beb..b35d74430a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -5,6 +5,8 @@ using System.Threading; using System.Threading.Tasks; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; + /// /// This is an envelope for an instance of Azure.Core.TokenCredential. /// This class uses reflection to interact with the Azure.Core library. @@ -48,7 +50,20 @@ public ReflectionCredentialEnvelope(object tokenCredential) /// A valid Azure.Core.AccessToken. public string GetToken(CancellationToken cancellationToken = default) { - return AzureCore.InvokeGetToken(this.tokenCredential, this.tokenRequestContext, cancellationToken); + SdkInternalOperationsMonitor.Enter(); + try + { + return AzureCore.InvokeGetToken(this.tokenCredential, this.tokenRequestContext, cancellationToken); + } + catch (Exception ex) + { + CoreEventSource.Log.FailedToGetToken(ex.ToInvariantString()); + return null; + } + finally + { + SdkInternalOperationsMonitor.Exit(); + } } /// @@ -56,9 +71,22 @@ public string GetToken(CancellationToken cancellationToken = default) /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - public Task GetTokenAsync(CancellationToken cancellationToken = default) + public async Task GetTokenAsync(CancellationToken cancellationToken = default) { - return AzureCore.InvokeGetTokenAsync(this.tokenCredential, this.tokenRequestContext, cancellationToken); + SdkInternalOperationsMonitor.Enter(); + try + { + return await AzureCore.InvokeGetTokenAsync(this.tokenCredential, this.tokenRequestContext, cancellationToken).ConfigureAwait(true); + } + catch (Exception ex) + { + CoreEventSource.Log.FailedToGetToken(ex.ToInvariantString()); + return null; + } + finally + { + SdkInternalOperationsMonitor.Exit(); + } } /// diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Tracing/CoreEventSource.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Tracing/CoreEventSource.cs index 6c71a54476..fcdec90df0 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Tracing/CoreEventSource.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Tracing/CoreEventSource.cs @@ -659,6 +659,9 @@ public void IngestionResponseTimeEventCounter(float responseDurationInMs) [Event(72, Keywords = Keywords.UserActionable, Message = "Failed to create file for self diagnostics at {0}. Error message: {1}.", Level = EventLevel.Error)] public void SelfDiagnosticsFileCreateException(string logDirectory, string exception, string appDomainName = "Incorrect") => this.WriteEvent(72, logDirectory, exception, this.nameProvider.Name); + [Event(73, Message = "Failed to get AAD Token. Error message: {0}.", Level = EventLevel.Error)] + public void FailedToGetToken(string exception, string appDomainName = "Incorrect") => this.WriteEvent(73, exception, this.nameProvider.Name); + [NonEvent] public void TransmissionStatusEventFailed(Exception ex) { From 957f33f49fe58e904bc92d3e99edd76caa79eb6f Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 15:24:04 -0700 Subject: [PATCH 69/93] set ConfigureAwait(true) --- .../Authentication/ReflectionCredentialEnvelope.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index b35d74430a..6546b69d9a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -76,7 +76,7 @@ public async Task GetTokenAsync(CancellationToken cancellationToken = de SdkInternalOperationsMonitor.Enter(); try { - return await AzureCore.InvokeGetTokenAsync(this.tokenCredential, this.tokenRequestContext, cancellationToken).ConfigureAwait(true); + return await AzureCore.InvokeGetTokenAsync(this.tokenCredential, this.tokenRequestContext, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { From f04ae0f81e1a1acd85bafc2fae9466c693285e5a Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 15:40:47 -0700 Subject: [PATCH 70/93] change to ICredentialEnvelope --- .../Channel/InMemoryChannel.cs | 6 +++--- .../Channel/InMemoryTransmitter.cs | 6 +++--- .../Channel/Transmission.cs | 4 ++-- .../Authentication/ISupportCredentialEnvelope.cs | 12 +++--------- .../Extensibility/TelemetryConfiguration.cs | 2 +- .../Implementation/TransmissionSender.cs | 6 +++--- .../Implementation/Transmitter.cs | 6 +++--- .../ServerTelemetryChannel/ServerTelemetryChannel.cs | 6 +++--- 8 files changed, 21 insertions(+), 27 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs index ef8088ef06..519ffbac7a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs @@ -96,14 +96,14 @@ public TimeSpan SendingInterval } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// FOR INTERNAL USE. Customers should use instead. /// /// - /// sets + /// on sets /// which is used to set just before calling . /// - ReflectionCredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope + ICredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope { get => this.transmitter.CredentialEnvelope; set => this.transmitter.CredentialEnvelope = value; diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs index 1a84b07abf..5dd4869248 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs @@ -65,13 +65,13 @@ internal TimeSpan SendingInterval } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// /// - /// sets + /// on sets /// which is used to set just before calling . /// - internal ReflectionCredentialEnvelope CredentialEnvelope { get; set; } + internal ICredentialEnvelope CredentialEnvelope { get; set; } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index b5460f92ad..f4e8fd5620 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -143,10 +143,10 @@ public ICollection TelemetryItems } /// - /// Gets or sets the . + /// Gets or sets the . /// This is used include an AAD token on HTTP Requests sent to ingestion. /// - internal ReflectionCredentialEnvelope CredentialEnvelope { get; set; } + internal ICredentialEnvelope CredentialEnvelope { get; set; } /// /// Gets the flush async id for the transmission. diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs index 6b5795bd4f..a387ed5ce2 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs @@ -1,19 +1,13 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; - /// - /// This interface defines a class that accepts the as a property. + /// This interface defines a class that accepts the as a property. /// internal interface ISupportCredentialEnvelope { /// - /// Gets or sets the . + /// Gets or sets the . /// - ReflectionCredentialEnvelope CredentialEnvelope { get; set; } + ICredentialEnvelope CredentialEnvelope { get; set; } } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index e63c4c40e5..594545972b 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -496,7 +496,7 @@ private static void SetTelemetryChannelEndpoint(ITelemetryChannel channel, strin } } - private static void SetTelemetryChannelCredentialEnvelope(ITelemetryChannel telemetryChannel, ReflectionCredentialEnvelope credentialEnvelope) + private static void SetTelemetryChannelCredentialEnvelope(ITelemetryChannel telemetryChannel, ICredentialEnvelope credentialEnvelope) { if (telemetryChannel is ISupportCredentialEnvelope tc) { diff --git a/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs b/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs index 87c4f37c70..08a3aa2c5c 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs @@ -109,13 +109,13 @@ public virtual int ThrottleWindow } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// /// - /// sets and then sets + /// on sets and then sets /// which is used to set just before calling . /// - internal ReflectionCredentialEnvelope CredentialEnvelope { get; set; } + internal ICredentialEnvelope CredentialEnvelope { get; set; } public virtual bool Enqueue(Func transmissionGetter) { diff --git a/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs b/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs index e80a0d955a..b17fcea9da 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs @@ -128,13 +128,13 @@ public BackoffLogicManager BackoffLogicManager } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// /// - /// sets and then sets + /// on sets and then sets /// which is used to set just before calling . /// - internal ReflectionCredentialEnvelope CredentialEnvelope + internal ICredentialEnvelope CredentialEnvelope { get => this.Sender.CredentialEnvelope; set => this.Sender.CredentialEnvelope = value; diff --git a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs index b688fa5971..7e16364e76 100644 --- a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs +++ b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs @@ -245,14 +245,14 @@ public int LocalThrottleWindow } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// DO NOT SET DIRECTLY. Use instead. /// /// - /// sets and then sets + /// on sets and then sets /// which is used to set just before calling . /// - ReflectionCredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope + ICredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope { get => this.Transmitter.CredentialEnvelope; set => this.Transmitter.CredentialEnvelope = value; From f04d2bd92199cdfad1766863ec4ee07c1cf6c9bd Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Wed, 26 May 2021 19:10:14 -0700 Subject: [PATCH 71/93] saving work in progress --- .../Microsoft.ApplicationInsights/Channel/Transmission.cs | 8 +++++++- .../Implementation/ResponseStatusCodes.cs | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index f4e8fd5620..ccec1f06c2 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -414,7 +414,13 @@ protected virtual HttpRequestMessage CreateRequestMessage(Uri address, Stream co if (this.CredentialEnvelope != null) { var aadToken = this.CredentialEnvelope.GetToken(); - request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + aadToken); + + if (aadToken == null) + { + // TODO: DO NOT SEND. RETURN FAILURE AND LET CHANNEL DECIDE WHEN TO RETRY. + } + + request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + aadToken). } return request; diff --git a/BASE/src/ServerTelemetryChannel/Implementation/ResponseStatusCodes.cs b/BASE/src/ServerTelemetryChannel/Implementation/ResponseStatusCodes.cs index 68db029d8b..36bb44b46a 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/ResponseStatusCodes.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/ResponseStatusCodes.cs @@ -12,5 +12,7 @@ internal class ResponseStatusCodes public const int BadGateway = 502; public const int ServiceUnavailable = 503; public const int GatewayTimeout = 504; + public const int Unauthorized = 401; // AAD + public const int Forbidden = 403; // AAD } } From 9c11def67f98b2dc2b5fa675a07de3541ea8a6f3 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 27 May 2021 12:27:03 -0700 Subject: [PATCH 72/93] saving work in progress --- BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index ccec1f06c2..bbeb832dcb 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -413,6 +413,7 @@ protected virtual HttpRequestMessage CreateRequestMessage(Uri address, Stream co if (this.CredentialEnvelope != null) { + // TODO: NEED TO USE CACHING var aadToken = this.CredentialEnvelope.GetToken(); if (aadToken == null) @@ -420,7 +421,7 @@ protected virtual HttpRequestMessage CreateRequestMessage(Uri address, Stream co // TODO: DO NOT SEND. RETURN FAILURE AND LET CHANNEL DECIDE WHEN TO RETRY. } - request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + aadToken). + request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + aadToken); } return request; From 0fc7613dba35bb35efa08475be3f47f410d1d4d9 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 27 May 2021 12:35:51 -0700 Subject: [PATCH 73/93] merge conflicts --- .../Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs | 2 +- BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs index 519ffbac7a..4fe5e58d14 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs @@ -97,7 +97,7 @@ public TimeSpan SendingInterval /// /// Gets or sets the which is used for AAD. - /// FOR INTERNAL USE. Customers should use instead. + /// FOR INTERNAL USE. Customers should use instead. /// /// /// on sets diff --git a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs index 7e16364e76..d3a44aced3 100644 --- a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs +++ b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs @@ -246,7 +246,7 @@ public int LocalThrottleWindow /// /// Gets or sets the which is used for AAD. - /// DO NOT SET DIRECTLY. Use instead. + /// DO NOT SET DIRECTLY. Use instead. /// /// /// on sets and then sets From 0c9c2a2aa7e6faedfaf2c1a6cd4d65cd90d57430 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 27 May 2021 13:38:31 -0700 Subject: [PATCH 74/93] merge conflicts --- .../Implementation/Authentication/ICredentialEnvelope.cs | 2 +- .../Extensibility/TelemetryConfiguration.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs index 7deca591c6..6d02edd427 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs @@ -3,7 +3,7 @@ using System.Threading; using System.Threading.Tasks; - internal interface ICredentialEnvelope + public interface ICredentialEnvelope { /// /// Gets the TokenCredential instance held by this class. diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index fae48c6181..23cd13cf0b 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -339,7 +339,7 @@ public string ConnectionString /// /// Gets an envelope for Azure.Core.TokenCredential which provides an AAD Authenticated token. /// - internal ICredentialEnvelope CredentialEnvelope { get; private set; } + public ICredentialEnvelope CredentialEnvelope { get; private set; } /// /// Gets or sets the chain of processors. From fc9756807b00ef96fdbe10fdce2d4fd34d9fc467 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 27 May 2021 13:41:35 -0700 Subject: [PATCH 75/93] merge conflict. --- .../net452/PublicAPI.Unshipped.txt | 6 +++++- .../net46/PublicAPI.Unshipped.txt | 6 +++++- .../netstandard2.0/PublicAPI.Unshipped.txt | 6 +++++- .../Implementation/Authentication/ICredentialEnvelope.cs | 3 +++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt index 44ef0ab106..491b63ff3a 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt @@ -1,5 +1,9 @@ +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.Credential.get -> object +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureTokenCredential(object tokenCredential) -> void - Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt index 44ef0ab106..491b63ff3a 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt @@ -1,5 +1,9 @@ +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.Credential.get -> object +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureTokenCredential(object tokenCredential) -> void - Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt index 44ef0ab106..491b63ff3a 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,5 +1,9 @@ +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.Credential.get -> object +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureTokenCredential(object tokenCredential) -> void - Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs index 6d02edd427..37b72fcf29 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs @@ -3,6 +3,9 @@ using System.Threading; using System.Threading.Tasks; + /// + /// This interface defines a class that can interact with Azure.Core.TokenCredential. + /// public interface ICredentialEnvelope { /// From 6acc5bb79af5e073ba7c1e5276b480cf14ae57cc Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Thu, 27 May 2021 15:15:37 -0700 Subject: [PATCH 76/93] fix tests --- .../Extensibility/TelemetryConfiguration.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 23cd13cf0b..6b62f4bbfe 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -94,7 +94,7 @@ public TelemetryConfiguration(string instrumentationKey, ITelemetryChannel chann { this.instrumentationKey = instrumentationKey ?? throw new ArgumentNullException(nameof(instrumentationKey)); - var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope == null); + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope != null); SetTelemetryChannelEndpoint(channel, ingestionEndpoint, force: true); var defaultSink = new TelemetrySink(this, channel); defaultSink.Name = "default"; @@ -242,7 +242,7 @@ public ITelemetryChannel TelemetryChannel if (!this.isDisposed) { this.telemetrySinks.DefaultSink.TelemetryChannel = value; - var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope == null); + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope != null); SetTelemetryChannelEndpoint(this.telemetrySinks.DefaultSink.TelemetryChannel, ingestionEndpoint); SetTelemetryChannelCredentialEnvelope(value, this.CredentialEnvelope); } @@ -300,7 +300,7 @@ public string ConnectionString this.EndpointContainer = new EndpointContainer(endpointProvider); // UPDATE TELEMETRY CHANNEL - var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope == null); + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope != null); this.SetTelemetryChannelEndpoint(ingestionEndpoint); // UPDATE APPLICATION ID PROVIDER From 3c1fcae5c460998c2876340a51e36999fc5bbf3a Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 10:30:12 -0700 Subject: [PATCH 77/93] refactor --- .../net452/PublicAPI.Unshipped.txt | 11 +++++---- .../net46/PublicAPI.Unshipped.txt | 11 +++++---- .../netstandard2.0/PublicAPI.Unshipped.txt | 11 +++++---- .../ReflectionCredentialEnvelopeTests.cs | 4 ++-- .../Channel/InMemoryChannel.cs | 4 ++-- .../Channel/InMemoryTransmitter.cs | 4 ++-- .../Channel/Transmission.cs | 4 ++-- .../Authentication/AuthConstants.cs | 13 ++++++++++ .../Authentication/CredentialConstants.cs | 24 ------------------- ...ntialEnvelope.cs => CredentialEnvelope.cs} | 8 +++---- .../ISupportCredentialEnvelope.cs | 6 ++--- .../ReflectionCredentialEnvelope.cs | 10 ++++---- .../Extensibility/TelemetryConfiguration.cs | 4 ++-- .../Implementation/TransmissionSender.cs | 4 ++-- .../Implementation/Transmitter.cs | 4 ++-- .../ServerTelemetryChannel.cs | 4 ++-- 16 files changed, 59 insertions(+), 67 deletions(-) delete mode 100644 BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs rename BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/{ICredentialEnvelope.cs => CredentialEnvelope.cs} (76%) diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt index 491b63ff3a..03ccefc0b5 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt @@ -1,8 +1,9 @@ -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.Credential.get -> object -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task -Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureTokenCredential(object tokenCredential) -> void Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt index 491b63ff3a..03ccefc0b5 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt @@ -1,8 +1,9 @@ -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.Credential.get -> object -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task -Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureTokenCredential(object tokenCredential) -> void Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt index 491b63ff3a..03ccefc0b5 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,8 +1,9 @@ -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.Credential.get -> object -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string -Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task -Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.ICredentialEnvelope +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureTokenCredential(object tokenCredential) -> void Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs index 75535b7289..c6cf0dcc70 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs @@ -118,7 +118,7 @@ public async Task VerifyGetTokenAsync_UsingDynamicTypes() [TestMethod] public void VerifyGetToken_ReturnsValidToken() { - var requestContext = new TokenRequestContext(scopes: CredentialConstants.GetScopes()); + var requestContext = new TokenRequestContext(scopes: AuthConstants.GetScopes()); var mockCredential = new MockCredential(); var tokenUsingTypes = mockCredential.GetToken(requestContext, CancellationToken.None); @@ -134,7 +134,7 @@ public void VerifyGetToken_ReturnsValidToken() [TestMethod] public async Task VerifyGetTokenAsync_ReturnsValidToken() { - var requestContext = new TokenRequestContext(scopes: CredentialConstants.GetScopes()); + var requestContext = new TokenRequestContext(scopes: AuthConstants.GetScopes()); var mockCredential = new MockCredential(); var tokenUsingTypes = await mockCredential.GetTokenAsync(requestContext, CancellationToken.None); diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs index 4fe5e58d14..279b9aca02 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs @@ -96,14 +96,14 @@ public TimeSpan SendingInterval } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// FOR INTERNAL USE. Customers should use instead. /// /// /// on sets /// which is used to set just before calling . /// - ICredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope + CredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope { get => this.transmitter.CredentialEnvelope; set => this.transmitter.CredentialEnvelope = value; diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs index 5dd4869248..33c6da0cab 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs @@ -65,13 +65,13 @@ internal TimeSpan SendingInterval } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// /// /// on sets /// which is used to set just before calling . /// - internal ICredentialEnvelope CredentialEnvelope { get; set; } + internal CredentialEnvelope CredentialEnvelope { get; set; } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index bbeb832dcb..3c6beb3767 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -143,10 +143,10 @@ public ICollection TelemetryItems } /// - /// Gets or sets the . + /// Gets or sets the which is used for AAD. /// This is used include an AAD token on HTTP Requests sent to ingestion. /// - internal ICredentialEnvelope CredentialEnvelope { get; set; } + internal CredentialEnvelope CredentialEnvelope { get; set; } /// /// Gets the flush async id for the transmission. diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs index 3c7968a117..9e0c4d3323 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs @@ -5,5 +5,18 @@ internal static class AuthConstants public const string AuthorizationHeaderName = "Authorization"; public const string AuthorizationTokenPrefix = "Bearer "; + + /// + /// Source: + /// (https://docs.microsoft.com/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). + /// (https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope). + /// + private const string AzureMonitorScope = "https://monitor.azure.com//.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. + + /// + /// Get scopes for Azure Monitor as an array. + /// + /// An array of scopes. + public static string[] GetScopes() => new string[] { AzureMonitorScope }; } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs deleted file mode 100644 index 3d6f253606..0000000000 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; - - internal static class CredentialConstants - { - /// - /// Source: - /// (https://docs.microsoft.com/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). - /// (https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope). - /// - public const string AzureMonitorScope = "https://monitor.azure.com//.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. - - /// - /// Get scopes for Azure Monitor as an array. - /// - /// An array of scopes. - public static string[] GetScopes() => new string[] { AzureMonitorScope }; - } -} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs similarity index 76% rename from BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs rename to BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index 37b72fcf29..7804257670 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -6,25 +6,25 @@ /// /// This interface defines a class that can interact with Azure.Core.TokenCredential. /// - public interface ICredentialEnvelope + public abstract class CredentialEnvelope { /// /// Gets the TokenCredential instance held by this class. /// - object Credential { get; } + public abstract object Credential { get; } /// /// Gets an Azure.Core.AccessToken. /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - string GetToken(CancellationToken cancellationToken = default); + public abstract string GetToken(CancellationToken cancellationToken = default); /// /// Gets an Azure.Core.AccessToken. /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - Task GetTokenAsync(CancellationToken cancellationToken = default); + public abstract Task GetTokenAsync(CancellationToken cancellationToken = default); } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs index a387ed5ce2..6130f89d1a 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ISupportCredentialEnvelope.cs @@ -1,13 +1,13 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { /// - /// This interface defines a class that accepts the as a property. + /// This interface defines a class that accepts the as a property. /// internal interface ISupportCredentialEnvelope { /// - /// Gets or sets the . + /// Gets or sets the . /// - ICredentialEnvelope CredentialEnvelope { get; set; } + CredentialEnvelope CredentialEnvelope { get; set; } } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 6546b69d9a..d356ea0e81 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -15,7 +15,7 @@ /// Our SDK currently targets net452, net46, and netstandard2.0. /// Azure.Core.TokenCredential is only available for netstandard2.0. /// - internal class ReflectionCredentialEnvelope : ICredentialEnvelope + internal class ReflectionCredentialEnvelope : CredentialEnvelope { private readonly object tokenCredential; private readonly object tokenRequestContext; @@ -30,7 +30,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) if (tokenCredential.GetType().IsSubclassOf(Type.GetType("Azure.Core.TokenCredential, Azure.Core"))) { - this.tokenRequestContext = AzureCore.MakeTokenRequestContext(scopes: CredentialConstants.GetScopes()); + this.tokenRequestContext = AzureCore.MakeTokenRequestContext(scopes: AuthConstants.GetScopes()); } else { @@ -41,14 +41,14 @@ public ReflectionCredentialEnvelope(object tokenCredential) /// /// Gets the TokenCredential instance held by this class. /// - public object Credential => this.tokenCredential; + public override object Credential => this.tokenCredential; /// /// Gets an Azure.Core.AccessToken. /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - public string GetToken(CancellationToken cancellationToken = default) + public override string GetToken(CancellationToken cancellationToken = default) { SdkInternalOperationsMonitor.Enter(); try @@ -71,7 +71,7 @@ public string GetToken(CancellationToken cancellationToken = default) /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - public async Task GetTokenAsync(CancellationToken cancellationToken = default) + public override async Task GetTokenAsync(CancellationToken cancellationToken = default) { SdkInternalOperationsMonitor.Enter(); try diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 6b62f4bbfe..8685ea61d6 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -339,7 +339,7 @@ public string ConnectionString /// /// Gets an envelope for Azure.Core.TokenCredential which provides an AAD Authenticated token. /// - public ICredentialEnvelope CredentialEnvelope { get; private set; } + public CredentialEnvelope CredentialEnvelope { get; private set; } /// /// Gets or sets the chain of processors. @@ -501,7 +501,7 @@ private static void SetTelemetryChannelEndpoint(ITelemetryChannel channel, strin } } - private static void SetTelemetryChannelCredentialEnvelope(ITelemetryChannel telemetryChannel, ICredentialEnvelope credentialEnvelope) + private static void SetTelemetryChannelCredentialEnvelope(ITelemetryChannel telemetryChannel, CredentialEnvelope credentialEnvelope) { if (telemetryChannel is ISupportCredentialEnvelope tc) { diff --git a/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs b/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs index 08a3aa2c5c..74201249a7 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/TransmissionSender.cs @@ -109,13 +109,13 @@ public virtual int ThrottleWindow } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// /// /// on sets and then sets /// which is used to set just before calling . /// - internal ICredentialEnvelope CredentialEnvelope { get; set; } + internal CredentialEnvelope CredentialEnvelope { get; set; } public virtual bool Enqueue(Func transmissionGetter) { diff --git a/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs b/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs index b17fcea9da..3c8fb576aa 100644 --- a/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs +++ b/BASE/src/ServerTelemetryChannel/Implementation/Transmitter.cs @@ -128,13 +128,13 @@ public BackoffLogicManager BackoffLogicManager } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// /// /// on sets and then sets /// which is used to set just before calling . /// - internal ICredentialEnvelope CredentialEnvelope + internal CredentialEnvelope CredentialEnvelope { get => this.Sender.CredentialEnvelope; set => this.Sender.CredentialEnvelope = value; diff --git a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs index d3a44aced3..de10defa0e 100644 --- a/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs +++ b/BASE/src/ServerTelemetryChannel/ServerTelemetryChannel.cs @@ -245,14 +245,14 @@ public int LocalThrottleWindow } /// - /// Gets or sets the which is used for AAD. + /// Gets or sets the which is used for AAD. /// DO NOT SET DIRECTLY. Use instead. /// /// /// on sets and then sets /// which is used to set just before calling . /// - ICredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope + CredentialEnvelope ISupportCredentialEnvelope.CredentialEnvelope { get => this.Transmitter.CredentialEnvelope; set => this.Transmitter.CredentialEnvelope = value; From 205337165fb3cd548d9c0a3ae6994a56aa00d972 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 10:37:12 -0700 Subject: [PATCH 78/93] AAD: refactor --- .../net452/PublicAPI.Unshipped.txt | 7 ++++++- .../net46/PublicAPI.Unshipped.txt | 7 ++++++- .../netstandard2.0/PublicAPI.Unshipped.txt | 7 ++++++- .../ReflectionCredentialEnvelopeTests.cs | 4 ++-- .../{CredentialConstants.cs => AuthConstants.cs} | 10 ++-------- ...ICredentialEnvelope.cs => CredentialEnvelope.cs} | 13 ++++++++----- .../Authentication/ReflectionCredentialEnvelope.cs | 10 +++++----- .../Extensibility/TelemetryConfiguration.cs | 2 +- 8 files changed, 36 insertions(+), 24 deletions(-) rename BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/{CredentialConstants.cs => AuthConstants.cs} (63%) rename BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/{ICredentialEnvelope.cs => CredentialEnvelope.cs} (65%) diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt index 44ef0ab106..03ccefc0b5 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt @@ -1,5 +1,10 @@ +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureTokenCredential(object tokenCredential) -> void - Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt index 44ef0ab106..03ccefc0b5 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt @@ -1,5 +1,10 @@ +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureTokenCredential(object tokenCredential) -> void - Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt index 44ef0ab106..03ccefc0b5 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,5 +1,10 @@ +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string +abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope +Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.CredentialEnvelope() -> void +Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CredentialEnvelope.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.SetAzureTokenCredential(object tokenCredential) -> void - Microsoft.ApplicationInsights.Channel.IAsyncFlushable Microsoft.ApplicationInsights.Channel.IAsyncFlushable.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Channel.InMemoryChannel.FlushAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs index 75535b7289..c6cf0dcc70 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelopeTests.cs @@ -118,7 +118,7 @@ public async Task VerifyGetTokenAsync_UsingDynamicTypes() [TestMethod] public void VerifyGetToken_ReturnsValidToken() { - var requestContext = new TokenRequestContext(scopes: CredentialConstants.GetScopes()); + var requestContext = new TokenRequestContext(scopes: AuthConstants.GetScopes()); var mockCredential = new MockCredential(); var tokenUsingTypes = mockCredential.GetToken(requestContext, CancellationToken.None); @@ -134,7 +134,7 @@ public void VerifyGetToken_ReturnsValidToken() [TestMethod] public async Task VerifyGetTokenAsync_ReturnsValidToken() { - var requestContext = new TokenRequestContext(scopes: CredentialConstants.GetScopes()); + var requestContext = new TokenRequestContext(scopes: AuthConstants.GetScopes()); var mockCredential = new MockCredential(); var tokenUsingTypes = await mockCredential.GetTokenAsync(requestContext, CancellationToken.None); diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs similarity index 63% rename from BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs rename to BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs index 3d6f253606..8a6da3ed86 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialConstants.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs @@ -1,19 +1,13 @@ namespace Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; - - internal static class CredentialConstants + internal static class AuthConstants { /// /// Source: /// (https://docs.microsoft.com/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). /// (https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#the-default-scope). /// - public const string AzureMonitorScope = "https://monitor.azure.com//.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. + private const string AzureMonitorScope = "https://monitor.azure.com//.default"; // TODO: THIS SCOPE IS UNVERIFIED. WAITING FOR SERVICES TEAM TO PROVIDE AN INT ENVIRONMENT FOR E2E TESTING. /// /// Get scopes for Azure Monitor as an array. diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs similarity index 65% rename from BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs rename to BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index 7deca591c6..c4afb0b4d8 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ICredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -3,25 +3,28 @@ using System.Threading; using System.Threading.Tasks; - internal interface ICredentialEnvelope + /// + /// This interface defines a class that can interact with Azure.Core.TokenCredential. + /// + public abstract class CredentialEnvelope { /// /// Gets the TokenCredential instance held by this class. /// - object Credential { get; } + public abstract object Credential { get; } /// /// Gets an Azure.Core.AccessToken. /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - string GetToken(CancellationToken cancellationToken = default); + public abstract string GetToken(CancellationToken cancellationToken = default); /// /// Gets an Azure.Core.AccessToken. /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - Task GetTokenAsync(CancellationToken cancellationToken = default); + public abstract Task GetTokenAsync(CancellationToken cancellationToken = default); } -} +} \ No newline at end of file diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 6546b69d9a..d356ea0e81 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -15,7 +15,7 @@ /// Our SDK currently targets net452, net46, and netstandard2.0. /// Azure.Core.TokenCredential is only available for netstandard2.0. /// - internal class ReflectionCredentialEnvelope : ICredentialEnvelope + internal class ReflectionCredentialEnvelope : CredentialEnvelope { private readonly object tokenCredential; private readonly object tokenRequestContext; @@ -30,7 +30,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) if (tokenCredential.GetType().IsSubclassOf(Type.GetType("Azure.Core.TokenCredential, Azure.Core"))) { - this.tokenRequestContext = AzureCore.MakeTokenRequestContext(scopes: CredentialConstants.GetScopes()); + this.tokenRequestContext = AzureCore.MakeTokenRequestContext(scopes: AuthConstants.GetScopes()); } else { @@ -41,14 +41,14 @@ public ReflectionCredentialEnvelope(object tokenCredential) /// /// Gets the TokenCredential instance held by this class. /// - public object Credential => this.tokenCredential; + public override object Credential => this.tokenCredential; /// /// Gets an Azure.Core.AccessToken. /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - public string GetToken(CancellationToken cancellationToken = default) + public override string GetToken(CancellationToken cancellationToken = default) { SdkInternalOperationsMonitor.Enter(); try @@ -71,7 +71,7 @@ public string GetToken(CancellationToken cancellationToken = default) /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. - public async Task GetTokenAsync(CancellationToken cancellationToken = default) + public override async Task GetTokenAsync(CancellationToken cancellationToken = default) { SdkInternalOperationsMonitor.Enter(); try diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 2db25dba0a..f8b0297828 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -338,7 +338,7 @@ public string ConnectionString /// /// Gets an envelope for Azure.Core.TokenCredential which provides an AAD Authenticated token. /// - internal ICredentialEnvelope CredentialEnvelope { get; private set; } + public CredentialEnvelope CredentialEnvelope { get; private set; } /// /// Gets or sets the chain of processors. From 4ecdfc40753dbc2c8e845fcd88b4ad26bc4e8a35 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 11:45:01 -0700 Subject: [PATCH 79/93] change property to internal --- .../net452/PublicAPI.Unshipped.txt | 1 - .../net46/PublicAPI.Unshipped.txt | 1 - .../netstandard2.0/PublicAPI.Unshipped.txt | 1 - .../Implementation/Authentication/CredentialEnvelope.cs | 2 +- .../Authentication/ReflectionCredentialEnvelope.cs | 2 +- 5 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt index 03ccefc0b5..39e0d1c109 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net452/PublicAPI.Unshipped.txt @@ -1,4 +1,3 @@ -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt index 03ccefc0b5..39e0d1c109 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt @@ -1,4 +1,3 @@ -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt index 03ccefc0b5..39e0d1c109 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,4 +1,3 @@ -abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.Credential.get -> object abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetToken(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> string abstract Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope.GetTokenAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication.CredentialEnvelope diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index c4afb0b4d8..ecc6931bf9 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -11,7 +11,7 @@ public abstract class CredentialEnvelope /// /// Gets the TokenCredential instance held by this class. /// - public abstract object Credential { get; } + internal abstract object Credential { get; } /// /// Gets an Azure.Core.AccessToken. diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index d356ea0e81..b441f952eb 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -41,7 +41,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) /// /// Gets the TokenCredential instance held by this class. /// - public override object Credential => this.tokenCredential; + internal override object Credential => this.tokenCredential; /// /// Gets an Azure.Core.AccessToken. From 8cdfde4547b9f3cb02b38e393e0681223c9da9f6 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 12:27:03 -0700 Subject: [PATCH 80/93] merge conflict --- .../Authentication/ReflectionCredentialEnvelope.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 65ddc36833..b441f952eb 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -41,7 +41,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) /// /// Gets the TokenCredential instance held by this class. /// - public object Credential => this.tokenCredential; + internal override object Credential => this.tokenCredential; /// /// Gets an Azure.Core.AccessToken. From 2006cad75d280ae808c805b90f1bbcd21133684b Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 13:40:32 -0700 Subject: [PATCH 81/93] rename param --- .../Channel/Transmission.cs | 6 +++--- .../QuickPulse/QuickPulseServiceClient.cs | 18 +++++++++--------- .../QuickPulse/QuickPulseServiceClient.cs | 18 +++++++++--------- .../Mocks/QuickPulseServiceClientMock.cs | 2 +- .../QuickPulse/IQuickPulseServiceClient.cs | 8 ++++---- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index 3c6beb3767..02f32e6ec5 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -414,14 +414,14 @@ protected virtual HttpRequestMessage CreateRequestMessage(Uri address, Stream co if (this.CredentialEnvelope != null) { // TODO: NEED TO USE CACHING - var aadToken = this.CredentialEnvelope.GetToken(); + var authToken = this.CredentialEnvelope.GetToken(); - if (aadToken == null) + if (authToken == null) { // TODO: DO NOT SEND. RETURN FAILURE AND LET CHANNEL DECIDE WHEN TO RETRY. } - request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + aadToken); + request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + authToken); } return request; diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs index 7e4a47a438..42a20b3739 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetFull/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -86,7 +86,7 @@ public Uri CurrentServiceUri DateTimeOffset timestamp, string configurationETag, string authApiKey, - string aadToken, + string authToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint) { @@ -101,7 +101,7 @@ public Uri CurrentServiceUri true, configurationETag, authApiKey, - aadToken, + authToken, out configurationInfo, out servicePollingIntervalHint, requestStream => this.WritePingData(timestamp, requestStream)); @@ -112,7 +112,7 @@ public Uri CurrentServiceUri string instrumentationKey, string configurationETag, string authApiKey, - string aadToken, + string authToken, out CollectionConfigurationInfo configurationInfo, CollectionConfigurationError[] collectionConfigurationErrors) { @@ -127,7 +127,7 @@ public Uri CurrentServiceUri false, configurationETag, authApiKey, - aadToken, + authToken, out configurationInfo, out _, requestStream => this.WriteSamples(samples, instrumentationKey, requestStream, collectionConfigurationErrors)); @@ -142,7 +142,7 @@ public void Dispose() bool includeIdentityHeaders, string configurationETag, string authApiKey, - string aadToken, + string authToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint, Action onWriteRequestBody) @@ -153,7 +153,7 @@ public void Dispose() request.Method = "POST"; request.Timeout = (int)this.timeout.TotalMilliseconds; - this.AddHeaders(request, includeIdentityHeaders, configurationETag, authApiKey, aadToken); + this.AddHeaders(request, includeIdentityHeaders, configurationETag, authApiKey, authToken); using (Stream requestStream = request.GetRequestStream()) { @@ -365,7 +365,7 @@ private static IEnumerable CreateDefaultMetrics(QuickPulseDataSampl }; } - private void AddHeaders(HttpWebRequest request, bool includeIdentityHeaders, string configurationETag, string authApiKey, string aadToken) + private void AddHeaders(HttpWebRequest request, bool includeIdentityHeaders, string configurationETag, string authApiKey, string authToken) { request.Headers.Add(QuickPulseConstants.XMsQpsTransmissionTimeHeaderName, this.timeProvider.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture)); @@ -388,9 +388,9 @@ private void AddHeaders(HttpWebRequest request, bool includeIdentityHeaders, str } // The AAD token is an optional feature. Only include if it is provided. - if (!string.IsNullOrEmpty(aadToken)) + if (!string.IsNullOrEmpty(authToken)) { - request.Headers.Add(QuickPulseConstants.AuthorizationHeaderName, QuickPulseConstants.AuthorizationTokenPrefix + aadToken); + request.Headers.Add(QuickPulseConstants.AuthorizationHeaderName, QuickPulseConstants.AuthorizationTokenPrefix + authToken); } } } diff --git a/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs index d37dd61d55..567cb72620 100644 --- a/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/Perf.Shared.NetStandard/Implementation/QuickPulse/QuickPulseServiceClient.cs @@ -92,7 +92,7 @@ public Uri CurrentServiceUri DateTimeOffset timestamp, string configurationETag, string authApiKey, - string aadToken, + string authToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint) { @@ -107,7 +107,7 @@ public Uri CurrentServiceUri true, configurationETag, authApiKey, - aadToken, + authToken, out configurationInfo, out servicePollingIntervalHint, requestStream => this.WritePingData(timestamp, requestStream)); @@ -118,7 +118,7 @@ public Uri CurrentServiceUri string instrumentationKey, string configurationETag, string authApiKey, - string aadToken, + string authToken, out CollectionConfigurationInfo configurationInfo, CollectionConfigurationError[] collectionConfigurationErrors) { @@ -133,7 +133,7 @@ public Uri CurrentServiceUri false, configurationETag, authApiKey, - aadToken, + authToken, out configurationInfo, out _, requestStream => this.WriteSamples(samples, instrumentationKey, requestStream, collectionConfigurationErrors)); @@ -150,7 +150,7 @@ public void Dispose() bool includeIdentityHeaders, string configurationETag, string authApiKey, - string aadToken, + string authToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint, Action onWriteRequestBody) @@ -159,7 +159,7 @@ public void Dispose() { using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri)) { - this.AddHeaders(request, includeIdentityHeaders, configurationETag, authApiKey, aadToken); + this.AddHeaders(request, includeIdentityHeaders, configurationETag, authApiKey, authToken); using (MemoryStream stream = new MemoryStream()) { @@ -394,7 +394,7 @@ private static IEnumerable CreateDefaultMetrics(QuickPulseDataSampl }; } - private void AddHeaders(HttpRequestMessage request, bool includeIdentityHeaders, string configurationETag, string authApiKey, string aadToken) + private void AddHeaders(HttpRequestMessage request, bool includeIdentityHeaders, string configurationETag, string authApiKey, string authToken) { request.Headers.TryAddWithoutValidation(QuickPulseConstants.XMsQpsTransmissionTimeHeaderName, this.timeProvider.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture)); @@ -417,9 +417,9 @@ private void AddHeaders(HttpRequestMessage request, bool includeIdentityHeaders, } // The AAD token is an optional feature. Only include if it is provided. - if (!string.IsNullOrEmpty(aadToken)) + if (!string.IsNullOrEmpty(authToken)) { - request.Headers.TryAddWithoutValidation(QuickPulseConstants.AuthorizationHeaderName, QuickPulseConstants.AuthorizationTokenPrefix + aadToken); + request.Headers.TryAddWithoutValidation(QuickPulseConstants.AuthorizationHeaderName, QuickPulseConstants.AuthorizationTokenPrefix + authToken); } } diff --git a/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/Mocks/QuickPulseServiceClientMock.cs b/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/Mocks/QuickPulseServiceClientMock.cs index 4f408a1bc7..f163b763fc 100644 --- a/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/Mocks/QuickPulseServiceClientMock.cs +++ b/WEB/Src/PerformanceCollector/Perf.Tests/QuickPulse/Mocks/QuickPulseServiceClientMock.cs @@ -74,7 +74,7 @@ public void Reset() DateTimeOffset timestamp, string configurationETag, string authApiKey, - string aadToken, + string authToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint) { diff --git a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs index 7e3f9ca012..2bcbbbf443 100644 --- a/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs +++ b/WEB/Src/PerformanceCollector/PerformanceCollector/Implementation/QuickPulse/IQuickPulseServiceClient.cs @@ -20,7 +20,7 @@ internal interface IQuickPulseServiceClient : IDisposable /// Timestamp to pass to the server. /// Current configuration ETag that the client has. /// Authentication API key. - /// AAD token to be included on Http messages. + /// Authorization token to be included on Http messages. /// When available, the deserialized response data received from the server. /// When available, a hint regarding what the period should be when pinging the server going forward. /// true if data is expected, otherwise false. @@ -29,7 +29,7 @@ internal interface IQuickPulseServiceClient : IDisposable DateTimeOffset timestamp, string configurationETag, string authApiKey, - string aadToken, + string authToken, out CollectionConfigurationInfo configurationInfo, out TimeSpan? servicePollingIntervalHint); @@ -40,7 +40,7 @@ internal interface IQuickPulseServiceClient : IDisposable /// InstrumentationKey for which to submit data samples. /// Current configuration ETag that the client has. /// Authentication API key. - /// AAD token to be included on Http messages. + /// Authorization token to be included on Http messages. /// When available, the deserialized response data received from the server. /// Errors to be reported back to the server. /// true if the client is expected to keep sending data samples, false otherwise. @@ -49,7 +49,7 @@ internal interface IQuickPulseServiceClient : IDisposable string instrumentationKey, string configurationETag, string authApiKey, - string aadToken, + string authToken, out CollectionConfigurationInfo configurationInfo, CollectionConfigurationError[] collectionConfigurationErrors); } From abf9b3c1b78c5225eacf1a6abbe5b8a3cc41bd88 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 13:56:33 -0700 Subject: [PATCH 82/93] aad with InMemoryChannel --- .../Channel/InMemoryChannel.cs | 20 ++++++- .../Channel/InMemoryTransmitter.cs | 23 ++++++-- .../Channel/Transmission.cs | 23 +++++++- .../Authentication/AuthConstants.cs | 4 ++ .../Endpoints/EndpointContainer.cs | 13 ++++- .../Extensibility/TelemetryConfiguration.cs | 58 +++++++++++++++---- 6 files changed, 120 insertions(+), 21 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs index c01ccde94d..2c50a75932 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs @@ -1,10 +1,14 @@ namespace Microsoft.ApplicationInsights.Channel { using System; + using System.ComponentModel; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; + using Microsoft.ApplicationInsights.Common; + using Microsoft.ApplicationInsights.Extensibility; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; /// @@ -122,6 +126,20 @@ public int BacklogSize set { this.buffer.BacklogSize = value; } } + /// + /// Gets or sets the which is used for AAD. + /// FOR INTERNAL USE. Customers should use instead. + /// + /// + /// sets + /// which is used to set just before calling . + /// + internal CredentialEnvelope CredentialEnvelope + { + get => this.transmitter.CredentialEnvelope; + set => this.transmitter.CredentialEnvelope = value; + } + internal bool IsDisposed => this.isDisposed; /// @@ -231,4 +249,4 @@ protected virtual void Dispose(bool disposing) } } } -} +} \ No newline at end of file diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs index 9c80f20676..c122689c32 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs @@ -11,9 +11,11 @@ namespace Microsoft.ApplicationInsights.Channel using System.Net.Http; using System.Threading; using System.Threading.Tasks; + using Microsoft.ApplicationInsights.Common.Extensions; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility.Implementation; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; /// @@ -32,13 +34,13 @@ internal class InMemoryTransmitter : IDisposable [SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", Justification = "Object is disposed within the using statement of the " + nameof(Runner) + " method.")] private AutoResetEvent startRunnerEvent; private bool enabled = true; - + /// /// The number of times this object was disposed. /// private int disposeCount = 0; private TimeSpan sendingInterval = TimeSpan.FromSeconds(30); - + internal InMemoryTransmitter(TelemetryBuffer buffer) { this.buffer = buffer; @@ -47,11 +49,11 @@ internal InMemoryTransmitter(TelemetryBuffer buffer) // Starting the Runner Task.Factory.StartNew(this.Runner, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default) .ContinueWith( - task => + task => { string msg = string.Format(CultureInfo.InvariantCulture, "InMemoryTransmitter: Unhandled exception in Runner: {0}", task.Exception); CoreEventSource.Log.LogVerbose(msg); - }, + }, TaskContinuationOptions.OnlyOnFaulted); } @@ -63,6 +65,15 @@ internal TimeSpan SendingInterval set { this.sendingInterval = value; } } + /// + /// Gets or sets the which is used for AAD. + /// + /// + /// sets + /// which is used to set just before calling . + /// + internal CredentialEnvelope CredentialEnvelope { get; set; } + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// @@ -163,7 +174,7 @@ private Task Send(IEnumerable telemetryItems, TimeSpan timeout) } var transmission = new Transmission(this.EndpointAddress, data, JsonSerializer.ContentType, JsonSerializer.CompressionType, timeout); - + transmission.CredentialEnvelope = this.CredentialEnvelope; return transmission.SendAsync(); } @@ -192,4 +203,4 @@ private void Dispose(bool disposing) } } } -} +} \ No newline at end of file diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index 2a955baded..097b954e35 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -10,7 +10,9 @@ using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; + using Microsoft.ApplicationInsights.Extensibility.Implementation; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; /// @@ -141,6 +143,12 @@ public ICollection TelemetryItems get; private set; } + /// + /// Gets or sets the which is used for AAD. + /// This is used include an AAD token on HTTP Requests sent to ingestion. + /// + internal CredentialEnvelope CredentialEnvelope { get; set; } + /// /// Gets the flush async id for the transmission. /// @@ -404,6 +412,19 @@ protected virtual HttpRequestMessage CreateRequestMessage(Uri address, Stream co request.Content.Headers.Add(ContentEncodingHeader, this.ContentEncoding); } + if (this.CredentialEnvelope != null) + { + // TODO: NEED TO USE CACHING + var authToken = this.CredentialEnvelope.GetToken(); + + if (authToken == null) + { + // TODO: DO NOT SEND. RETURN FAILURE AND LET CHANNEL DECIDE WHEN TO RETRY. + } + + request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + authToken); + } + return request; } @@ -432,4 +453,4 @@ protected virtual WebRequest CreateRequest(Uri address) return request; } } -} +} \ No newline at end of file diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs index 8a6da3ed86..9e0c4d3323 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/AuthConstants.cs @@ -2,6 +2,10 @@ { internal static class AuthConstants { + public const string AuthorizationHeaderName = "Authorization"; + + public const string AuthorizationTokenPrefix = "Bearer "; + /// /// Source: /// (https://docs.microsoft.com/azure/active-directory/develop/msal-acquire-cache-tokens#scopes-when-acquiring-tokens). diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs index 8b55a1886a..5308ae8388 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs @@ -30,8 +30,19 @@ internal EndpointContainer(IEndpointProvider endpointProvider) /// Gets the fully formatted endpoint for the ingestion service. internal string FormattedIngestionEndpoint => new Uri(this.Ingestion, "v2/track").AbsoluteUri; + /// Gets the fully formatted endpoint for the ingestion service with support for AAD. + internal string FormattedIngestionAADEndpoint => new Uri(this.Ingestion, "v2.1/track").AbsoluteUri; + /// Gets the fully formatted endpoint for the application id profile service. /// This returns a string without using the Uri for validation because the consuming method needs to do a string replace. internal string FormattedApplicationIdEndpoint => this.Ingestion.AbsoluteUri + "api/profiles/{0}/appId"; + + /// + /// Get the Ingestion Endpoint, depending on if AAD is in use. + /// This can be removed after we fully transition no the newer Ingestion API. + /// + /// Boolean to indicate which ingestion service to use. + /// Fully formatted endpoint for the ingestion service. + internal string GetFormattedIngestionEndpoint(bool enableAAD) => enableAAD ? this.FormattedIngestionAADEndpoint : this.FormattedIngestionEndpoint; } -} +} \ No newline at end of file diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index f8b0297828..acc4edfd00 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Threading; using System.Threading.Tasks; + using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.DataContracts; using Microsoft.ApplicationInsights.Extensibility.Implementation; @@ -31,11 +32,11 @@ public sealed class TelemetryConfiguration : IDisposable internal readonly SamplingRateStore LastKnownSampleRateStore = new SamplingRateStore(); private static object syncRoot = new object(); - private static TelemetryConfiguration active; + private static TelemetryConfiguration active; private readonly SnapshottingList telemetryInitializers = new SnapshottingList(); private readonly TelemetrySinkCollection telemetrySinks = new TelemetrySinkCollection(); - + private TelemetryProcessorChain telemetryProcessorChain; private string instrumentationKey = string.Empty; private string connectionString; @@ -43,7 +44,7 @@ public sealed class TelemetryConfiguration : IDisposable private TelemetryProcessorChainBuilder builder; private MetricManager metricManager = null; private IApplicationIdProvider applicationIdProvider; - + /// /// Indicates if this instance has been disposed of. /// @@ -64,7 +65,7 @@ static TelemetryConfiguration() { Activity.DefaultIdFormat = ActivityIdFormat.W3C; Activity.ForceDefaultIdFormat = true; - } + } }); SelfDiagnosticsInitializer.EnsureInitialized(); } @@ -94,7 +95,8 @@ public TelemetryConfiguration(string instrumentationKey, ITelemetryChannel chann { this.instrumentationKey = instrumentationKey ?? throw new ArgumentNullException(nameof(instrumentationKey)); - SetTelemetryChannelEndpoint(channel, this.EndpointContainer.FormattedIngestionEndpoint, force: true); + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope != null); + SetTelemetryChannelEndpoint(channel, ingestionEndpoint, force: true); var defaultSink = new TelemetrySink(this, channel); defaultSink.Name = "default"; this.telemetrySinks.Add(defaultSink); @@ -241,7 +243,9 @@ public ITelemetryChannel TelemetryChannel if (!this.isDisposed) { this.telemetrySinks.DefaultSink.TelemetryChannel = value; - SetTelemetryChannelEndpoint(this.telemetrySinks.DefaultSink.TelemetryChannel, this.EndpointContainer.FormattedIngestionEndpoint); + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope != null); + SetTelemetryChannelEndpoint(this.telemetrySinks.DefaultSink.TelemetryChannel, ingestionEndpoint); + SetTelemetryChannelCredentialEnvelope(value, this.CredentialEnvelope); } } } @@ -297,10 +301,8 @@ public string ConnectionString this.EndpointContainer = new EndpointContainer(endpointProvider); // UPDATE TELEMETRY CHANNEL - foreach (var tSink in this.TelemetrySinks) - { - SetTelemetryChannelEndpoint(tSink.TelemetryChannel, this.EndpointContainer.FormattedIngestionEndpoint, force: true); - } + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: this.CredentialEnvelope != null); + this.SetTelemetryChannelEndpoint(ingestionEndpoint); // UPDATE APPLICATION ID PROVIDER SetApplicationIdEndpoint(this.ApplicationIdProvider, this.EndpointContainer.FormattedApplicationIdEndpoint, force: true); @@ -414,7 +416,15 @@ public void Dispose() /// /// An instance of Azure.Core.TokenCredential. /// An ArgumentException is thrown if the provided object does not inherit Azure.Core.TokenCredential. - public void SetAzureTokenCredential(object tokenCredential) => this.CredentialEnvelope = new ReflectionCredentialEnvelope(tokenCredential); + public void SetAzureTokenCredential(object tokenCredential) + { + this.CredentialEnvelope = new ReflectionCredentialEnvelope(tokenCredential); + this.SetTelemetryChannelCredentialEnvelope(); + + // Update Ingestion Endpoint. + var ingestionEndpoint = this.EndpointContainer.GetFormattedIngestionEndpoint(enableAAD: true); + this.SetTelemetryChannelEndpoint(ingestionEndpoint); + } internal MetricManager GetMetricManager(bool createIfNotExists) { @@ -492,6 +502,30 @@ private static void SetTelemetryChannelEndpoint(ITelemetryChannel channel, strin } } + private static void SetTelemetryChannelCredentialEnvelope(ITelemetryChannel telemetryChannel, CredentialEnvelope credentialEnvelope) + { + if (telemetryChannel is InMemoryChannel inMemoryChannel) + { + inMemoryChannel.CredentialEnvelope = credentialEnvelope; + } + } + + private void SetTelemetryChannelCredentialEnvelope() + { + foreach (var tSink in this.TelemetrySinks) + { + SetTelemetryChannelCredentialEnvelope(tSink.TelemetryChannel, this.CredentialEnvelope); + } + } + + private void SetTelemetryChannelEndpoint(string ingestionEndpoint) + { + foreach (var tSink in this.TelemetrySinks) + { + SetTelemetryChannelEndpoint(tSink.TelemetryChannel, ingestionEndpoint, force: true); + } + } + /// /// Disposes of resources. /// @@ -525,4 +559,4 @@ private void Dispose(bool disposing) } } } -} +} \ No newline at end of file From 605b597e4d1683210fc0bcaaecf8b45a7527f7e0 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 14:01:04 -0700 Subject: [PATCH 83/93] fix end of line --- .../Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs | 2 +- .../Channel/InMemoryTransmitter.cs | 2 +- BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs | 2 +- .../Extensibility/Implementation/Endpoints/EndpointContainer.cs | 2 +- .../Extensibility/TelemetryConfiguration.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs index 2c50a75932..85ca810ffa 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs @@ -249,4 +249,4 @@ protected virtual void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs index c122689c32..58461333d9 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryTransmitter.cs @@ -203,4 +203,4 @@ private void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index 097b954e35..ef6053aaec 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -453,4 +453,4 @@ protected virtual WebRequest CreateRequest(Uri address) return request; } } -} \ No newline at end of file +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs index 5308ae8388..966e3c31d7 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Endpoints/EndpointContainer.cs @@ -45,4 +45,4 @@ internal EndpointContainer(IEndpointProvider endpointProvider) /// Fully formatted endpoint for the ingestion service. internal string GetFormattedIngestionEndpoint(bool enableAAD) => enableAAD ? this.FormattedIngestionAADEndpoint : this.FormattedIngestionEndpoint; } -} \ No newline at end of file +} diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index acc4edfd00..9cd56036b4 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -559,4 +559,4 @@ private void Dispose(bool disposing) } } } -} \ No newline at end of file +} From cb2163d6e7ba1710be4bf104f0e73e625117bc07 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 14:44:19 -0700 Subject: [PATCH 84/93] configuration tests --- ...tryConfigurationCredentialEnvelopeTests.cs | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TelemetryConfigurationCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TelemetryConfigurationCredentialEnvelopeTests.cs index b3394e32bc..a14c396fce 100644 --- a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TelemetryConfigurationCredentialEnvelopeTests.cs +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TelemetryConfigurationCredentialEnvelopeTests.cs @@ -4,6 +4,7 @@ namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementati using System; using System.Threading.Tasks; + using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -47,6 +48,50 @@ public void VerifyCannotSetInvalidObjectOnTelemetryConfiguration() var telemetryConfiguration = new TelemetryConfiguration(); telemetryConfiguration.SetAzureTokenCredential(Guid.Empty); } + + [TestMethod] + public void VerifySetCredential_CorrectlySetsTelemetryChannel_CredentialFirst() + { + // SETUP + var tc = TelemetryConfiguration.CreateDefault(); + Assert.IsInstanceOfType(tc.TelemetryChannel, typeof(InMemoryChannel)); + Assert.IsTrue(tc.TelemetryChannel.EndpointAddress.Contains("v2")); // defaults to old api + + // ACT + // set credential first + tc.SetAzureTokenCredential(new MockCredential()); + Assert.IsTrue(tc.TelemetryChannel.EndpointAddress.Contains("v2.1")); // api switch + + // test new channel + var channel = new InMemoryChannel(); + Assert.IsNull(channel.EndpointAddress); // new channel defaults null + + // change config channel + tc.TelemetryChannel = channel; + Assert.IsTrue(channel.EndpointAddress.Contains("v2.1")); // configuration sets new api + } + + [TestMethod] + public void VerifySetCredential_CorrectlySetsTelemetryChannel_TelemetryChannelFirst() + { + // SETUP + var tc = TelemetryConfiguration.CreateDefault(); + Assert.IsInstanceOfType(tc.TelemetryChannel, typeof(InMemoryChannel)); + Assert.IsTrue(tc.TelemetryChannel.EndpointAddress.Contains("v2")); // defaults to old api + + // ACT + // set new channel first + var channel = new InMemoryChannel(); + Assert.IsNull(channel.EndpointAddress); // new channel defaults null + + // change config channel + tc.TelemetryChannel = channel; + Assert.IsTrue(channel.EndpointAddress.Contains("v2")); // configuration sets new api + + // set credential second + tc.SetAzureTokenCredential(new MockCredential()); + Assert.IsTrue(tc.TelemetryChannel.EndpointAddress.Contains("v2.1")); // api switch + } } } #endif From 6d049fb85ace45ec3ea46ae61d81efb5bad3f875 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 15:21:23 -0700 Subject: [PATCH 85/93] Transmission tests --- .../TransmissionCredentialEnvelopeTests.cs | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TransmissionCredentialEnvelopeTests.cs diff --git a/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TransmissionCredentialEnvelopeTests.cs b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TransmissionCredentialEnvelopeTests.cs new file mode 100644 index 0000000000..61e8145424 --- /dev/null +++ b/BASE/Test/Microsoft.ApplicationInsights.Test/Microsoft.ApplicationInsights.Tests/Extensibility/Implementation/Authentication/TransmissionCredentialEnvelopeTests.cs @@ -0,0 +1,94 @@ +#if !NET452 && !NET46 +namespace Microsoft.ApplicationInsights.TestFramework.Extensibility.Implementation.Authentication +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Net.Http; + using System.Text; + using System.Threading.Tasks; + + using Microsoft.ApplicationInsights.Channel; + using Microsoft.ApplicationInsights.DataContracts; + using Microsoft.ApplicationInsights.Extensibility.Implementation.Authentication; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + /// + /// These tests verify that can receive and store an instance of . + /// + /// + /// These tests do not run in NET452 OR NET46. + /// In these cases, the test runner is NET452 or NET46 and Azure.Core.TokenCredential is NOT SUPPORTED in these frameworks. + /// This does not affect the end user because we REQUIRE the end user to create their own instance of TokenCredential. + /// This ensures that the end user is consuming the AI SDK in one of the newer frameworks. + /// + [TestClass] + [TestCategory("AAD")] + public class TransmissionCredentialEnvelopeTests + { + private readonly Uri testUri = new Uri("https://127.0.0.1/"); + + [TestMethod] + public async Task VerifyTransmissionSendAsync_Default() + { + var handler = new HandlerForFakeHttpClient + { + InnerHandler = new HttpClientHandler(), + OnSendAsync = (req, cancellationToken) => + { + // VALIDATE + Assert.IsNull(req.Headers.Authorization); + + return Task.FromResult(new HttpResponseMessage()); + } + }; + + using (var fakeHttpClient = new HttpClient(handler)) + { + var expectedContentType = "content/type"; + var expectedContentEncoding = "contentEncoding"; + var items = new List { new EventTelemetry() }; + + // Instantiate Transmission with the mock HttpClient + var transmission = new Transmission(testUri, new byte[] { 1, 2, 3, 4, 5 }, fakeHttpClient, expectedContentType, expectedContentEncoding); + + var result = await transmission.SendAsync(); + } + } + + [TestMethod] + public async Task VerifyTransmissionSendAsync_WithCredential_SetsAuthHeader() + { + var credendialEnvelope = new ReflectionCredentialEnvelope(new MockCredential()); + var token = credendialEnvelope.GetToken(); + + + var handler = new HandlerForFakeHttpClient + { + InnerHandler = new HttpClientHandler(), + OnSendAsync = (req, cancellationToken) => + { + // VALIDATE + Assert.AreEqual(AuthConstants.AuthorizationTokenPrefix.Trim(), req.Headers.Authorization.Scheme); + Assert.AreEqual(token, req.Headers.Authorization.Parameter); + + return Task.FromResult(new HttpResponseMessage()); + } + }; + + using (var fakeHttpClient = new HttpClient(handler)) + { + var expectedContentType = "content/type"; + var expectedContentEncoding = "contentEncoding"; + var items = new List { new EventTelemetry() }; + + // Instantiate Transmission with the mock HttpClient + var transmission = new Transmission(testUri, new byte[] { 1, 2, 3, 4, 5 }, fakeHttpClient, expectedContentType, expectedContentEncoding); + transmission.CredentialEnvelope = credendialEnvelope; + + var result = await transmission.SendAsync(); + } + } + } +} +#endif From 6e25d92e2ed80762603dc5d7727d5a6d5cd2accb Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 16:16:26 -0700 Subject: [PATCH 86/93] comments --- .../Channel/Transmission.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs index ef6053aaec..9eb8e7806e 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs @@ -414,15 +414,18 @@ protected virtual HttpRequestMessage CreateRequestMessage(Uri address, Stream co if (this.CredentialEnvelope != null) { - // TODO: NEED TO USE CACHING + // TODO: NEED TO USE CACHING HERE var authToken = this.CredentialEnvelope.GetToken(); if (authToken == null) { // TODO: DO NOT SEND. RETURN FAILURE AND LET CHANNEL DECIDE WHEN TO RETRY. + // This could be either a configuration error or the AAD service is unavailable. + } + else + { + request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + authToken); } - - request.Headers.TryAddWithoutValidation(AuthConstants.AuthorizationHeaderName, AuthConstants.AuthorizationTokenPrefix + authToken); } return request; From b07755415d50178b40529bc5bf1e6d87bad301dc Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 16:16:39 -0700 Subject: [PATCH 87/93] testing fix for InternalOperations --- .../Authentication/ReflectionCredentialEnvelope.cs | 4 ++-- .../AzureSdk/AzureSdkDiagnosticsEventHandler.cs | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index b441f952eb..7a14b65ffc 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -50,7 +50,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) /// A valid Azure.Core.AccessToken. public override string GetToken(CancellationToken cancellationToken = default) { - SdkInternalOperationsMonitor.Enter(); + //SdkInternalOperationsMonitor.Enter(); try { return AzureCore.InvokeGetToken(this.tokenCredential, this.tokenRequestContext, cancellationToken); @@ -62,7 +62,7 @@ public override string GetToken(CancellationToken cancellationToken = default) } finally { - SdkInternalOperationsMonitor.Exit(); + //SdkInternalOperationsMonitor.Exit(); } } diff --git a/WEB/Src/DependencyCollector/DependencyCollector/Implementation/AzureSdk/AzureSdkDiagnosticsEventHandler.cs b/WEB/Src/DependencyCollector/DependencyCollector/Implementation/AzureSdk/AzureSdkDiagnosticsEventHandler.cs index 4a25454a48..49a886fbb9 100644 --- a/WEB/Src/DependencyCollector/DependencyCollector/Implementation/AzureSdk/AzureSdkDiagnosticsEventHandler.cs +++ b/WEB/Src/DependencyCollector/DependencyCollector/Implementation/AzureSdk/AzureSdkDiagnosticsEventHandler.cs @@ -38,6 +38,13 @@ public override void OnEvent(KeyValuePair evnt, DiagnosticListen { try { + if (SdkInternalOperationsMonitor.IsEntered()) + { + // Now that Application Insights supports AAD, we need to check if an internal operation is being caught here. + // type = "InProc | Microsoft.AAD" + return; + } + var currentActivity = Activity.Current; if (evnt.Key.EndsWith(".Start", StringComparison.Ordinal)) { From 7f0f92999fe36da2764cae7e43b873abec01dd4d Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 16:24:05 -0700 Subject: [PATCH 88/93] fxcop --- .../Authentication/ReflectionCredentialEnvelope.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index 7a14b65ffc..d351e192fa 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -50,7 +50,7 @@ public ReflectionCredentialEnvelope(object tokenCredential) /// A valid Azure.Core.AccessToken. public override string GetToken(CancellationToken cancellationToken = default) { - //SdkInternalOperationsMonitor.Enter(); + // SdkInternalOperationsMonitor.Enter(); try { return AzureCore.InvokeGetToken(this.tokenCredential, this.tokenRequestContext, cancellationToken); @@ -62,7 +62,7 @@ public override string GetToken(CancellationToken cancellationToken = default) } finally { - //SdkInternalOperationsMonitor.Exit(); + // SdkInternalOperationsMonitor.Exit(); } } From eebc0a3a91b28ac5c03343ccd90f30c6aed41719 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 16:54:56 -0700 Subject: [PATCH 89/93] comment about InternalOperations --- .../Authentication/CredentialEnvelope.cs | 6 ++++++ .../ReflectionCredentialEnvelope.cs | 16 ++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs index ecc6931bf9..1f25ac8ccf 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/CredentialEnvelope.cs @@ -16,6 +16,9 @@ public abstract class CredentialEnvelope /// /// Gets an Azure.Core.AccessToken. /// + /// + /// Whomever uses this MUST verify that it's called within otherwise dependency calls will be tracked. + /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. public abstract string GetToken(CancellationToken cancellationToken = default); @@ -23,6 +26,9 @@ public abstract class CredentialEnvelope /// /// Gets an Azure.Core.AccessToken. /// + /// + /// Whomever uses this MUST verify that it's called within otherwise dependency calls will be tracked. + /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. public abstract Task GetTokenAsync(CancellationToken cancellationToken = default); diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs index d351e192fa..b186c42cd2 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Authentication/ReflectionCredentialEnvelope.cs @@ -46,11 +46,13 @@ public ReflectionCredentialEnvelope(object tokenCredential) /// /// Gets an Azure.Core.AccessToken. /// + /// + /// Whomever uses this MUST verify that it's called within otherwise dependency calls will be tracked. + /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. public override string GetToken(CancellationToken cancellationToken = default) { - // SdkInternalOperationsMonitor.Enter(); try { return AzureCore.InvokeGetToken(this.tokenCredential, this.tokenRequestContext, cancellationToken); @@ -60,20 +62,18 @@ public override string GetToken(CancellationToken cancellationToken = default) CoreEventSource.Log.FailedToGetToken(ex.ToInvariantString()); return null; } - finally - { - // SdkInternalOperationsMonitor.Exit(); - } } /// /// Gets an Azure.Core.AccessToken. /// + /// + /// Whomever uses this MUST verify that it's called within otherwise dependency calls will be tracked. + /// /// The System.Threading.CancellationToken to use. /// A valid Azure.Core.AccessToken. public override async Task GetTokenAsync(CancellationToken cancellationToken = default) { - SdkInternalOperationsMonitor.Enter(); try { return await AzureCore.InvokeGetTokenAsync(this.tokenCredential, this.tokenRequestContext, cancellationToken).ConfigureAwait(false); @@ -83,10 +83,6 @@ public override async Task GetTokenAsync(CancellationToken cancellationT CoreEventSource.Log.FailedToGetToken(ex.ToInvariantString()); return null; } - finally - { - SdkInternalOperationsMonitor.Exit(); - } } /// From 8063dcf561e3c7e7da27abdb164c0ebfda8f0e77 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 16:55:05 -0700 Subject: [PATCH 90/93] cleanup --- .../Implementation/AzureSdk/AzureSdkDiagnosticsEventHandler.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/WEB/Src/DependencyCollector/DependencyCollector/Implementation/AzureSdk/AzureSdkDiagnosticsEventHandler.cs b/WEB/Src/DependencyCollector/DependencyCollector/Implementation/AzureSdk/AzureSdkDiagnosticsEventHandler.cs index 49a886fbb9..7f351630e4 100644 --- a/WEB/Src/DependencyCollector/DependencyCollector/Implementation/AzureSdk/AzureSdkDiagnosticsEventHandler.cs +++ b/WEB/Src/DependencyCollector/DependencyCollector/Implementation/AzureSdk/AzureSdkDiagnosticsEventHandler.cs @@ -40,8 +40,7 @@ public override void OnEvent(KeyValuePair evnt, DiagnosticListen { if (SdkInternalOperationsMonitor.IsEntered()) { - // Now that Application Insights supports AAD, we need to check if an internal operation is being caught here. - // type = "InProc | Microsoft.AAD" + // Because we support AAD, we must to check if an internal operation is being caught here (type = "InProc | Microsoft.AAD"). return; } From a99b09c30d2f3653b5df33098b9242b5e0bfb3cb Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 17:19:37 -0700 Subject: [PATCH 91/93] merge conflict --- .../Extensibility/TelemetryConfiguration.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 9cd56036b4..8815c79088 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -504,9 +504,9 @@ private static void SetTelemetryChannelEndpoint(ITelemetryChannel channel, strin private static void SetTelemetryChannelCredentialEnvelope(ITelemetryChannel telemetryChannel, CredentialEnvelope credentialEnvelope) { - if (telemetryChannel is InMemoryChannel inMemoryChannel) + if (telemetryChannel is ISupportCredentialEnvelope tc) { - inMemoryChannel.CredentialEnvelope = credentialEnvelope; + tc.CredentialEnvelope = credentialEnvelope; } } From 11c6a6ba761585cb3ba5d32dd521000c89d6438d Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 18:16:05 -0700 Subject: [PATCH 92/93] merge conflicts --- .../Channel/InMemoryChannel.cs | 14 -------------- .../Extensibility/TelemetryConfiguration.cs | 2 ++ 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs index 23df108765..befd7e94cb 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs @@ -140,20 +140,6 @@ public int BacklogSize set { this.buffer.BacklogSize = value; } } - /// - /// Gets or sets the which is used for AAD. - /// FOR INTERNAL USE. Customers should use instead. - /// - /// - /// sets - /// which is used to set just before calling . - /// - internal CredentialEnvelope CredentialEnvelope - { - get => this.transmitter.CredentialEnvelope; - set => this.transmitter.CredentialEnvelope = value; - } - internal bool IsDisposed => this.isDisposed; /// diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index 8815c79088..bfa55d4b27 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -339,7 +339,9 @@ public string ConnectionString /// /// Gets an envelope for Azure.Core.TokenCredential which provides an AAD Authenticated token. + /// FOR INTERNAL USE ONLY. To set the Credential use . /// + [EditorBrowsable(EditorBrowsableState.Never)] public CredentialEnvelope CredentialEnvelope { get; private set; } /// From 461c9e7d46a561377b93c1e0760af6d642cdcd22 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Lee Date: Fri, 28 May 2021 18:19:56 -0700 Subject: [PATCH 93/93] cleanup --- .../src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs index befd7e94cb..b26138f914 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Channel/InMemoryChannel.cs @@ -1,7 +1,6 @@ namespace Microsoft.ApplicationInsights.Channel { using System; - using System.ComponentModel; using System.Diagnostics; using System.Threading; using System.Threading.Tasks;