From bc33fc3238117197d7b81f5704f6d4d3e695d7dc Mon Sep 17 00:00:00 2001
From: Anoop Babu <anoobabu@cisco.com>
Date: Mon, 22 Jan 2024 18:52:29 -0500
Subject: [PATCH 1/5] Saving changes to switch to another branch

---
 Handler.cs                             |  40 +++++++
 Http                                   |   0
 ServerCertificateValidationProvider.cs | 153 +++++++++++++++++++++++++
 opentelemetry-dotnet-contrib.sln       |   7 ++
 4 files changed, 200 insertions(+)
 create mode 100644 Handler.cs
 create mode 100644 Http
 create mode 100644 ServerCertificateValidationProvider.cs

diff --git a/Handler.cs b/Handler.cs
new file mode 100644
index 0000000000..65b396df75
--- /dev/null
+++ b/Handler.cs
@@ -0,0 +1,40 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#if !NETFRAMEWORK
+
+using System;
+using System.Net.Http;
+
+namespace OpenTelemetry.ResourceDetector;
+
+internal class Handler
+{
+    public static HttpClientHandler? Create(string certificateFile)
+    {
+        try
+        {
+            ServerCertificateValidationProvider? serverCertificateValidationProvider =
+                ServerCertificateValidationProvider.FromCertificateFile(certificateFile);
+
+            if (serverCertificateValidationProvider == null)
+            {
+                AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection");
+                return null;
+            }
+
+            var clientHandler = new HttpClientHandler();
+            clientHandler.ServerCertificateCustomValidationCallback =
+                (sender, x509Certificate2, x509Chain, sslPolicyErrors) =>
+                    serverCertificateValidationProvider.ValidationCallback(sender, x509Certificate2, x509Chain, sslPolicyErrors);
+            return clientHandler;
+        }
+        catch (Exception ex)
+        {
+            AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(Handler)} : Failed to create HttpClientHandler", ex);
+        }
+
+        return null;
+    }
+}
+#endif
diff --git a/Http b/Http
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ServerCertificateValidationProvider.cs b/ServerCertificateValidationProvider.cs
new file mode 100644
index 0000000000..137c811610
--- /dev/null
+++ b/ServerCertificateValidationProvider.cs
@@ -0,0 +1,153 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#if !NETFRAMEWORK
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+
+namespace OpenTelemetry.ResourceDetector;
+
+internal class ServerCertificateValidationProvider
+{
+    private readonly X509Certificate2Collection trustedCertificates;
+
+    private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates)
+    {
+        this.trustedCertificates = trustedCertificates;
+        this.ValidationCallback = (_, cert, chain, errors) =>
+            this.ValidateCertificate(cert != null ? new X509Certificate2(cert) : null, chain, errors);
+    }
+
+    public RemoteCertificateValidationCallback ValidationCallback { get; }
+
+    public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile)
+    {
+        if (!File.Exists(certificateFile))
+        {
+            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist");
+            return null;
+        }
+
+        var trustedCertificates = new X509Certificate2Collection();
+        if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile))
+        {
+            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection");
+            return null;
+        }
+
+        return new ServerCertificateValidationProvider(trustedCertificates);
+    }
+
+    private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName)
+    {
+        try
+        {
+            collection.Import(certFileName);
+            return true;
+        }
+        catch (Exception)
+        {
+            return false;
+        }
+    }
+
+    private static bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection? collection)
+    {
+        if (collection == null)
+        {
+            return false;
+        }
+
+        foreach (var chainElement in chain.ChainElements)
+        {
+            foreach (var certificate in collection)
+            {
+                if (chainElement.Certificate.GetPublicKey().SequenceEqual(certificate.GetPublicKey()))
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPolicyErrors errors)
+    {
+        var isSslPolicyPassed = errors == SslPolicyErrors.None ||
+                                errors == SslPolicyErrors.RemoteCertificateChainErrors;
+        if (!isSslPolicyPassed)
+        {
+            if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors)
+            {
+                AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable");
+            }
+
+            if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors)
+            {
+                AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch");
+            }
+        }
+
+        if (chain == null)
+        {
+            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate chain is null.");
+            return false;
+        }
+
+        if (cert == null)
+        {
+            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate is null.");
+            return false;
+        }
+
+        chain.ChainPolicy.ExtraStore.AddRange(this.trustedCertificates);
+        chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
+
+        // building the chain to process basic validations e.g. signature, use, expiration, revocation
+        var isValidChain = chain.Build(cert);
+
+        if (!isValidChain)
+        {
+            var chainErrors = string.Empty;
+            foreach (var element in chain.ChainElements)
+            {
+                foreach (var status in element.ChainElementStatus)
+                {
+                    chainErrors +=
+                        $"\nCertificate [{element.Certificate.Subject}] Status [{status.Status}]: {status.StatusInformation}";
+                }
+            }
+
+            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}");
+        }
+
+        // check if at least one certificate in the chain is in our trust list
+        var isTrusted = HasCommonCertificate(chain, this.trustedCertificates);
+        if (!isTrusted)
+        {
+            var serverCertificates = string.Empty;
+            foreach (var element in chain.ChainElements)
+            {
+                serverCertificates += " " + element.Certificate.Subject;
+            }
+
+            var trustCertificates = string.Empty;
+            foreach (var trustCertificate in this.trustedCertificates)
+            {
+                trustCertificates += " " + trustCertificate.Subject;
+            }
+
+            AWSResourcesEventSource.Log.FailedToValidateCertificate(
+                nameof(ServerCertificateValidationProvider),
+                $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}");
+        }
+
+        return isSslPolicyPassed && isValidChain && isTrusted;
+    }
+}
+#endif
diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln
index 09fac45779..3f8115e97b 100644
--- a/opentelemetry-dotnet-contrib.sln
+++ b/opentelemetry-dotnet-contrib.sln
@@ -341,6 +341,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Host.Tests", "test\OpenTelemetry.ResourceDetectors.Host.Tests\OpenTelemetry.ResourceDetectors.Host.Tests.csproj", "{36271347-2055-438E-9659-B71542A17A73}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Http", "Http", "{C6D9B83F-4080-4CF9-A09E-2480B4420D20}"
+	ProjectSection(SolutionItems) = preProject
+		Handler.cs = Handler.cs
+		ServerCertificateValidationProvider.cs = ServerCertificateValidationProvider.cs
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -785,6 +791,7 @@ Global
 		{A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
 		{033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}
 		{36271347-2055-438E-9659-B71542A17A73} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
+		{C6D9B83F-4080-4CF9-A09E-2480B4420D20} = {1FCC8EEC-9E75-4FEA-AFCF-363DD33FF0B9}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66}

From 5a5e782c3586842a3157bcff21150dd3b4ba43fb Mon Sep 17 00:00:00 2001
From: Anoop Babu <anoobabu@cisco.com>
Date: Thu, 25 Jan 2024 21:56:09 -0500
Subject: [PATCH 2/5] Fully adjusted move to shared

---
 Handler.cs                                    |  40 -----
 Http                                          |   0
 ServerCertificateValidationProvider.cs        | 153 ------------------
 opentelemetry-dotnet-contrib.sln              |  10 +-
 .../AWSEKSResourceDetector.cs                 |   3 +-
 .../AWSResourcesEventSource.cs                |   6 -
 .../Http/Handler.cs                           |  40 -----
 .../ServerCertificateValidationProvider.cs    | 153 ------------------
 ...OpenTelemetry.ResourceDetectors.AWS.csproj |   3 +
 .../ServerCertificateValidationEventSource.cs |  28 ++++
 .../ServerCertificateValidationHandler.cs     |  42 +++++
 .../ServerCertificateValidationProvider.cs    | 153 ++++++++++++++++++
 .../Http/HandlerTests.cs                      |   5 +-
 ...erverCertificateValidationProviderTests.cs |   1 -
 14 files changed, 232 insertions(+), 405 deletions(-)
 delete mode 100644 Handler.cs
 delete mode 100644 Http
 delete mode 100644 ServerCertificateValidationProvider.cs
 delete mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs
 delete mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs
 create mode 100644 src/Shared/ServerCertificateValidationEventSource.cs
 create mode 100644 src/Shared/ServerCertificateValidationHandler.cs
 create mode 100644 src/Shared/ServerCertificateValidationProvider.cs

diff --git a/Handler.cs b/Handler.cs
deleted file mode 100644
index 65b396df75..0000000000
--- a/Handler.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-#if !NETFRAMEWORK
-
-using System;
-using System.Net.Http;
-
-namespace OpenTelemetry.ResourceDetector;
-
-internal class Handler
-{
-    public static HttpClientHandler? Create(string certificateFile)
-    {
-        try
-        {
-            ServerCertificateValidationProvider? serverCertificateValidationProvider =
-                ServerCertificateValidationProvider.FromCertificateFile(certificateFile);
-
-            if (serverCertificateValidationProvider == null)
-            {
-                AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection");
-                return null;
-            }
-
-            var clientHandler = new HttpClientHandler();
-            clientHandler.ServerCertificateCustomValidationCallback =
-                (sender, x509Certificate2, x509Chain, sslPolicyErrors) =>
-                    serverCertificateValidationProvider.ValidationCallback(sender, x509Certificate2, x509Chain, sslPolicyErrors);
-            return clientHandler;
-        }
-        catch (Exception ex)
-        {
-            AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(Handler)} : Failed to create HttpClientHandler", ex);
-        }
-
-        return null;
-    }
-}
-#endif
diff --git a/Http b/Http
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/ServerCertificateValidationProvider.cs b/ServerCertificateValidationProvider.cs
deleted file mode 100644
index 137c811610..0000000000
--- a/ServerCertificateValidationProvider.cs
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-#if !NETFRAMEWORK
-
-using System;
-using System.IO;
-using System.Linq;
-using System.Net.Security;
-using System.Security.Cryptography.X509Certificates;
-
-namespace OpenTelemetry.ResourceDetector;
-
-internal class ServerCertificateValidationProvider
-{
-    private readonly X509Certificate2Collection trustedCertificates;
-
-    private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates)
-    {
-        this.trustedCertificates = trustedCertificates;
-        this.ValidationCallback = (_, cert, chain, errors) =>
-            this.ValidateCertificate(cert != null ? new X509Certificate2(cert) : null, chain, errors);
-    }
-
-    public RemoteCertificateValidationCallback ValidationCallback { get; }
-
-    public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile)
-    {
-        if (!File.Exists(certificateFile))
-        {
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist");
-            return null;
-        }
-
-        var trustedCertificates = new X509Certificate2Collection();
-        if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile))
-        {
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection");
-            return null;
-        }
-
-        return new ServerCertificateValidationProvider(trustedCertificates);
-    }
-
-    private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName)
-    {
-        try
-        {
-            collection.Import(certFileName);
-            return true;
-        }
-        catch (Exception)
-        {
-            return false;
-        }
-    }
-
-    private static bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection? collection)
-    {
-        if (collection == null)
-        {
-            return false;
-        }
-
-        foreach (var chainElement in chain.ChainElements)
-        {
-            foreach (var certificate in collection)
-            {
-                if (chainElement.Certificate.GetPublicKey().SequenceEqual(certificate.GetPublicKey()))
-                {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPolicyErrors errors)
-    {
-        var isSslPolicyPassed = errors == SslPolicyErrors.None ||
-                                errors == SslPolicyErrors.RemoteCertificateChainErrors;
-        if (!isSslPolicyPassed)
-        {
-            if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors)
-            {
-                AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable");
-            }
-
-            if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors)
-            {
-                AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch");
-            }
-        }
-
-        if (chain == null)
-        {
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate chain is null.");
-            return false;
-        }
-
-        if (cert == null)
-        {
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate is null.");
-            return false;
-        }
-
-        chain.ChainPolicy.ExtraStore.AddRange(this.trustedCertificates);
-        chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
-
-        // building the chain to process basic validations e.g. signature, use, expiration, revocation
-        var isValidChain = chain.Build(cert);
-
-        if (!isValidChain)
-        {
-            var chainErrors = string.Empty;
-            foreach (var element in chain.ChainElements)
-            {
-                foreach (var status in element.ChainElementStatus)
-                {
-                    chainErrors +=
-                        $"\nCertificate [{element.Certificate.Subject}] Status [{status.Status}]: {status.StatusInformation}";
-                }
-            }
-
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}");
-        }
-
-        // check if at least one certificate in the chain is in our trust list
-        var isTrusted = HasCommonCertificate(chain, this.trustedCertificates);
-        if (!isTrusted)
-        {
-            var serverCertificates = string.Empty;
-            foreach (var element in chain.ChainElements)
-            {
-                serverCertificates += " " + element.Certificate.Subject;
-            }
-
-            var trustCertificates = string.Empty;
-            foreach (var trustCertificate in this.trustedCertificates)
-            {
-                trustCertificates += " " + trustCertificate.Subject;
-            }
-
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(
-                nameof(ServerCertificateValidationProvider),
-                $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}");
-        }
-
-        return isSslPolicyPassed && isValidChain && isTrusted;
-    }
-}
-#endif
diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln
index 3f8115e97b..a15696ddda 100644
--- a/opentelemetry-dotnet-contrib.sln
+++ b/opentelemetry-dotnet-contrib.sln
@@ -283,6 +283,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E
 		src\Shared\PropertyFetcher.cs = src\Shared\PropertyFetcher.cs
 		src\Shared\ResourceSemanticConventions.cs = src\Shared\ResourceSemanticConventions.cs
 		src\Shared\SemanticConventions.cs = src\Shared\SemanticConventions.cs
+		src\Shared\ServerCertificateValidationEventSource.cs = src\Shared\ServerCertificateValidationEventSource.cs
+		src\Shared\ServerCertificateValidationHandler.cs = src\Shared\ServerCertificateValidationHandler.cs
+		src\Shared\ServerCertificateValidationProvider.cs = src\Shared\ServerCertificateValidationProvider.cs
 		src\Shared\ServiceProviderExtensions.cs = src\Shared\ServiceProviderExtensions.cs
 		src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs
 		src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs
@@ -341,12 +344,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Host.Tests", "test\OpenTelemetry.ResourceDetectors.Host.Tests\OpenTelemetry.ResourceDetectors.Host.Tests.csproj", "{36271347-2055-438E-9659-B71542A17A73}"
 EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Http", "Http", "{C6D9B83F-4080-4CF9-A09E-2480B4420D20}"
-	ProjectSection(SolutionItems) = preProject
-		Handler.cs = Handler.cs
-		ServerCertificateValidationProvider.cs = ServerCertificateValidationProvider.cs
-	EndProjectSection
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -791,7 +788,6 @@ Global
 		{A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
 		{033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}
 		{36271347-2055-438E-9659-B71542A17A73} = {2097345F-4DD3-477D-BC54-A922F9B2B402}
-		{C6D9B83F-4080-4CF9-A09E-2480B4420D20} = {1FCC8EEC-9E75-4FEA-AFCF-363DD33FF0B9}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66}
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs
index 82e4ea0170..b1a8611c5b 100644
--- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs
+++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs
@@ -7,7 +7,6 @@
 using System.Collections.Generic;
 using System.Net.Http;
 using System.Text;
-using OpenTelemetry.ResourceDetectors.AWS.Http;
 using OpenTelemetry.ResourceDetectors.AWS.Models;
 using OpenTelemetry.Resources;
 
@@ -31,7 +30,7 @@ public sealed class AWSEKSResourceDetector : IResourceDetector
     public Resource Detect()
     {
         var credentials = GetEKSCredentials(AWSEKSCredentialPath);
-        using var httpClientHandler = Handler.Create(AWSEKSCertificatePath);
+        using var httpClientHandler = ServerCertificateValidationHandler.Create(AWSEKSCertificatePath);
 
         if (credentials == null || !IsEKSProcess(credentials, httpClientHandler))
         {
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs
index 4238241190..1b7eaad006 100644
--- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs
+++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs
@@ -26,10 +26,4 @@ public void FailedToExtractResourceAttributes(string format, string exception)
     {
         this.WriteEvent(3, format, exception);
     }
-
-    [Event(2, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)]
-    public void FailedToValidateCertificate(string format, string error)
-    {
-        this.WriteEvent(4, format, error);
-    }
 }
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs
deleted file mode 100644
index 5e709733b1..0000000000
--- a/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-#if !NETFRAMEWORK
-
-using System;
-using System.Net.Http;
-
-namespace OpenTelemetry.ResourceDetectors.AWS.Http;
-
-internal class Handler
-{
-    public static HttpClientHandler? Create(string certificateFile)
-    {
-        try
-        {
-            ServerCertificateValidationProvider? serverCertificateValidationProvider =
-                ServerCertificateValidationProvider.FromCertificateFile(certificateFile);
-
-            if (serverCertificateValidationProvider == null)
-            {
-                AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection");
-                return null;
-            }
-
-            var clientHandler = new HttpClientHandler();
-            clientHandler.ServerCertificateCustomValidationCallback =
-                (sender, x509Certificate2, x509Chain, sslPolicyErrors) =>
-                    serverCertificateValidationProvider.ValidationCallback(sender, x509Certificate2, x509Chain, sslPolicyErrors);
-            return clientHandler;
-        }
-        catch (Exception ex)
-        {
-            AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(Handler)} : Failed to create HttpClientHandler", ex);
-        }
-
-        return null;
-    }
-}
-#endif
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs
deleted file mode 100644
index 1538215391..0000000000
--- a/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-#if !NETFRAMEWORK
-
-using System;
-using System.IO;
-using System.Linq;
-using System.Net.Security;
-using System.Security.Cryptography.X509Certificates;
-
-namespace OpenTelemetry.ResourceDetectors.AWS.Http;
-
-internal class ServerCertificateValidationProvider
-{
-    private readonly X509Certificate2Collection trustedCertificates;
-
-    private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates)
-    {
-        this.trustedCertificates = trustedCertificates;
-        this.ValidationCallback = (_, cert, chain, errors) =>
-            this.ValidateCertificate(cert != null ? new X509Certificate2(cert) : null, chain, errors);
-    }
-
-    public RemoteCertificateValidationCallback ValidationCallback { get; }
-
-    public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile)
-    {
-        if (!File.Exists(certificateFile))
-        {
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist");
-            return null;
-        }
-
-        var trustedCertificates = new X509Certificate2Collection();
-        if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile))
-        {
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection");
-            return null;
-        }
-
-        return new ServerCertificateValidationProvider(trustedCertificates);
-    }
-
-    private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName)
-    {
-        try
-        {
-            collection.Import(certFileName);
-            return true;
-        }
-        catch (Exception)
-        {
-            return false;
-        }
-    }
-
-    private static bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection? collection)
-    {
-        if (collection == null)
-        {
-            return false;
-        }
-
-        foreach (var chainElement in chain.ChainElements)
-        {
-            foreach (var certificate in collection)
-            {
-                if (chainElement.Certificate.GetPublicKey().SequenceEqual(certificate.GetPublicKey()))
-                {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPolicyErrors errors)
-    {
-        var isSslPolicyPassed = errors == SslPolicyErrors.None ||
-                                errors == SslPolicyErrors.RemoteCertificateChainErrors;
-        if (!isSslPolicyPassed)
-        {
-            if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors)
-            {
-                AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable");
-            }
-
-            if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors)
-            {
-                AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch");
-            }
-        }
-
-        if (chain == null)
-        {
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate chain is null.");
-            return false;
-        }
-
-        if (cert == null)
-        {
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate is null.");
-            return false;
-        }
-
-        chain.ChainPolicy.ExtraStore.AddRange(this.trustedCertificates);
-        chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
-
-        // building the chain to process basic validations e.g. signature, use, expiration, revocation
-        var isValidChain = chain.Build(cert);
-
-        if (!isValidChain)
-        {
-            var chainErrors = string.Empty;
-            foreach (var element in chain.ChainElements)
-            {
-                foreach (var status in element.ChainElementStatus)
-                {
-                    chainErrors +=
-                        $"\nCertificate [{element.Certificate.Subject}] Status [{status.Status}]: {status.StatusInformation}";
-                }
-            }
-
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}");
-        }
-
-        // check if at least one certificate in the chain is in our trust list
-        var isTrusted = HasCommonCertificate(chain, this.trustedCertificates);
-        if (!isTrusted)
-        {
-            var serverCertificates = string.Empty;
-            foreach (var element in chain.ChainElements)
-            {
-                serverCertificates += " " + element.Certificate.Subject;
-            }
-
-            var trustCertificates = string.Empty;
-            foreach (var trustCertificate in this.trustedCertificates)
-            {
-                trustCertificates += " " + trustCertificate.Subject;
-            }
-
-            AWSResourcesEventSource.Log.FailedToValidateCertificate(
-                nameof(ServerCertificateValidationProvider),
-                $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}");
-        }
-
-        return isSslPolicyPassed && isValidChain && isTrusted;
-    }
-}
-#endif
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj
index b5ad0ad470..7800cccf4b 100644
--- a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj
+++ b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj
@@ -23,6 +23,9 @@
 
   <ItemGroup>
     <Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
+    <Compile Include="$(RepoRoot)\src\Shared\ServerCertificateValidationHandler.cs" Link="Includes\ServerCertificateValidationHandler.cs" />
+    <Compile Include="$(RepoRoot)\src\Shared\ServerCertificateValidationProvider.cs" Link="Includes\ServerCertificateValidationProvider.cs" />
+    <Compile Include="$(RepoRoot)\src\Shared\ServerCertificateValidationEventSource.cs" Link="Includes\ServerCertificateValidationEventSource.cs" />
   </ItemGroup>
 
 </Project>
diff --git a/src/Shared/ServerCertificateValidationEventSource.cs b/src/Shared/ServerCertificateValidationEventSource.cs
new file mode 100644
index 0000000000..854e813a5c
--- /dev/null
+++ b/src/Shared/ServerCertificateValidationEventSource.cs
@@ -0,0 +1,28 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#if !NETFRAMEWORK
+
+using System.Diagnostics.Tracing;
+
+namespace OpenTelemetry.ResourceDetectors;
+
+[EventSource(Name = "OpenTelemetry-ResourceDetectors-Http")]
+internal class ServerCertificateValidationEventSource : EventSource
+{
+    public static ServerCertificateValidationEventSource Log = new();
+
+    [Event(1, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)]
+    public void FailedToExtractResourceAttributes(string format, string exception)
+    {
+        this.WriteEvent(3, format, exception);
+    }
+
+    [Event(2, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)]
+    public void FailedToValidateCertificate(string format, string error)
+    {
+        this.WriteEvent(4, format, error);
+    }
+}
+
+#endif
diff --git a/src/Shared/ServerCertificateValidationHandler.cs b/src/Shared/ServerCertificateValidationHandler.cs
new file mode 100644
index 0000000000..551b7b1645
--- /dev/null
+++ b/src/Shared/ServerCertificateValidationHandler.cs
@@ -0,0 +1,42 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#if !NETFRAMEWORK
+
+using System;
+using System.Net.Http;
+using OpenTelemetry.Internal;
+
+namespace OpenTelemetry.ResourceDetectors;
+
+internal class ServerCertificateValidationHandler
+{
+    public static HttpClientHandler? Create(string certificateFile)
+    {
+        try
+        {
+            ServerCertificateValidationProvider? serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateFile);
+
+            if (serverCertificateValidationProvider == null)
+            {
+                ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationHandler), "Failed to Load the certificate file into trusted collection");
+                return null;
+            }
+
+            var clientHandler = new HttpClientHandler
+            {
+                ServerCertificateCustomValidationCallback =
+                (sender, x509Certificate2, x509Chain, sslPolicyErrors) =>
+                    serverCertificateValidationProvider.ValidationCallback(sender, x509Certificate2, x509Chain, sslPolicyErrors),
+            };
+            return clientHandler;
+        }
+        catch (Exception ex)
+        {
+            ServerCertificateValidationEventSource.Log.FailedToExtractResourceAttributes($"{nameof(ServerCertificateValidationHandler)} : Failed to create HttpClientHandler", ex.ToInvariantString());
+        }
+
+        return null;
+    }
+}
+#endif
diff --git a/src/Shared/ServerCertificateValidationProvider.cs b/src/Shared/ServerCertificateValidationProvider.cs
new file mode 100644
index 0000000000..d036c9d5b9
--- /dev/null
+++ b/src/Shared/ServerCertificateValidationProvider.cs
@@ -0,0 +1,153 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#if !NETFRAMEWORK
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+
+namespace OpenTelemetry.ResourceDetectors;
+
+internal class ServerCertificateValidationProvider
+{
+  private readonly X509Certificate2Collection trustedCertificates;
+
+  private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates)
+  {
+    this.trustedCertificates = trustedCertificates;
+    this.ValidationCallback = (_, cert, chain, errors) =>
+        this.ValidateCertificate(cert != null ? new X509Certificate2(cert) : null, chain, errors);
+  }
+
+  public RemoteCertificateValidationCallback ValidationCallback { get; }
+
+  public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile)
+  {
+    if (!File.Exists(certificateFile))
+    {
+      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist");
+      return null;
+    }
+
+    var trustedCertificates = new X509Certificate2Collection();
+    if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile))
+    {
+      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection");
+      return null;
+    }
+
+    return new ServerCertificateValidationProvider(trustedCertificates);
+  }
+
+  private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName)
+  {
+    try
+    {
+      collection.Import(certFileName);
+      return true;
+    }
+    catch (Exception)
+    {
+      return false;
+    }
+  }
+
+  private static bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection? collection)
+  {
+    if (collection == null)
+    {
+      return false;
+    }
+
+    foreach (var chainElement in chain.ChainElements)
+    {
+      foreach (var certificate in collection)
+      {
+        if (chainElement.Certificate.GetPublicKey().SequenceEqual(certificate.GetPublicKey()))
+        {
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+
+  private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPolicyErrors errors)
+  {
+    var isSslPolicyPassed = errors == SslPolicyErrors.None ||
+                            errors == SslPolicyErrors.RemoteCertificateChainErrors;
+    if (!isSslPolicyPassed)
+    {
+      if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors)
+      {
+        ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable");
+      }
+
+      if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors)
+      {
+        ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch");
+      }
+    }
+
+    if (chain == null)
+    {
+      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate chain is null.");
+      return false;
+    }
+
+    if (cert == null)
+    {
+      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate is null.");
+      return false;
+    }
+
+    chain.ChainPolicy.ExtraStore.AddRange(this.trustedCertificates);
+    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
+
+    // building the chain to process basic validations e.g. signature, use, expiration, revocation
+    var isValidChain = chain.Build(cert);
+
+    if (!isValidChain)
+    {
+      var chainErrors = string.Empty;
+      foreach (var element in chain.ChainElements)
+      {
+        foreach (var status in element.ChainElementStatus)
+        {
+          chainErrors +=
+              $"\nCertificate [{element.Certificate.Subject}] Status [{status.Status}]: {status.StatusInformation}";
+        }
+      }
+
+      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}");
+    }
+
+    // check if at least one certificate in the chain is in our trust list
+    var isTrusted = HasCommonCertificate(chain, this.trustedCertificates);
+    if (!isTrusted)
+    {
+      var serverCertificates = string.Empty;
+      foreach (var element in chain.ChainElements)
+      {
+        serverCertificates += " " + element.Certificate.Subject;
+      }
+
+      var trustCertificates = string.Empty;
+      foreach (var trustCertificate in this.trustedCertificates)
+      {
+        trustCertificates += " " + trustCertificate.Subject;
+      }
+
+      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(
+          nameof(ServerCertificateValidationProvider),
+          $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}");
+    }
+
+    return isSslPolicyPassed && isValidChain && isTrusted;
+  }
+}
+#endif
diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs
index b7c16d64ca..a209ff07c3 100644
--- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs
+++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs
@@ -3,7 +3,6 @@
 
 #if !NETFRAMEWORK
 
-using OpenTelemetry.ResourceDetectors.AWS.Http;
 using Xunit;
 
 namespace OpenTelemetry.ResourceDetectors.AWS.Tests.Http;
@@ -20,7 +19,7 @@ public void TestValidHandler()
             certificateUploader.Create();
 
             // Validates if the handler created.
-            Assert.NotNull(Handler.Create(certificateUploader.FilePath));
+            Assert.NotNull(ServerCertificateValidationHandler.Create(certificateUploader.FilePath));
         }
     }
 
@@ -28,7 +27,7 @@ public void TestValidHandler()
     public void TestInValidHandler()
     {
         // Validates if the handler created if no certificate is loaded into the trusted collection
-        Assert.Null(Handler.Create(INVALIDCRTNAME));
+        Assert.Null(ServerCertificateValidationHandler.Create(INVALIDCRTNAME));
     }
 }
 
diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs
index 008107b52e..81edbd8791 100644
--- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs
+++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs
@@ -4,7 +4,6 @@
 #if !NETFRAMEWORK
 
 using System.Security.Cryptography.X509Certificates;
-using OpenTelemetry.ResourceDetectors.AWS.Http;
 using Xunit;
 
 namespace OpenTelemetry.ResourceDetectors.AWS.Tests.Http;

From 81ace52fc3e92bcf4664fa305eadb9958d040540 Mon Sep 17 00:00:00 2001
From: Anoop Babu <anoobabu@cisco.com>
Date: Mon, 29 Jan 2024 18:51:15 -0500
Subject: [PATCH 3/5] Removing shared event source entirely, and using invoked
 actions for logging instead

---
 opentelemetry-dotnet-contrib.sln              |   1 -
 .../AWSEKSResourceDetector.cs                 |   3 +-
 .../AWSResourcesEventSource.cs                |   6 +
 ...OpenTelemetry.ResourceDetectors.AWS.csproj |   1 -
 .../ServerCertificateValidationHandler.cs     |   8 +-
 .../ServerCertificateValidationProvider.cs    | 215 +++++++++---------
 6 files changed, 121 insertions(+), 113 deletions(-)

diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln
index a15696ddda..9f02511871 100644
--- a/opentelemetry-dotnet-contrib.sln
+++ b/opentelemetry-dotnet-contrib.sln
@@ -283,7 +283,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E
 		src\Shared\PropertyFetcher.cs = src\Shared\PropertyFetcher.cs
 		src\Shared\ResourceSemanticConventions.cs = src\Shared\ResourceSemanticConventions.cs
 		src\Shared\SemanticConventions.cs = src\Shared\SemanticConventions.cs
-		src\Shared\ServerCertificateValidationEventSource.cs = src\Shared\ServerCertificateValidationEventSource.cs
 		src\Shared\ServerCertificateValidationHandler.cs = src\Shared\ServerCertificateValidationHandler.cs
 		src\Shared\ServerCertificateValidationProvider.cs = src\Shared\ServerCertificateValidationProvider.cs
 		src\Shared\ServiceProviderExtensions.cs = src\Shared\ServiceProviderExtensions.cs
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs
index b1a8611c5b..0c72ffebcf 100644
--- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs
+++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs
@@ -30,7 +30,8 @@ public sealed class AWSEKSResourceDetector : IResourceDetector
     public Resource Detect()
     {
         var credentials = GetEKSCredentials(AWSEKSCredentialPath);
-        using var httpClientHandler = ServerCertificateValidationHandler.Create(AWSEKSCertificatePath);
+        using var httpClientHandler = ServerCertificateValidationHandler.Create(
+            AWSEKSCertificatePath, AWSResourcesEventSource.Log.FailedToValidateCertificate, AWSResourcesEventSource.Log.FailedToExtractResourceAttributes);
 
         if (credentials == null || !IsEKSProcess(credentials, httpClientHandler))
         {
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs
index 1b7eaad006..4238241190 100644
--- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs
+++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs
@@ -26,4 +26,10 @@ public void FailedToExtractResourceAttributes(string format, string exception)
     {
         this.WriteEvent(3, format, exception);
     }
+
+    [Event(2, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)]
+    public void FailedToValidateCertificate(string format, string error)
+    {
+        this.WriteEvent(4, format, error);
+    }
 }
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj
index 7800cccf4b..8b87636a88 100644
--- a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj
+++ b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj
@@ -25,7 +25,6 @@
     <Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
     <Compile Include="$(RepoRoot)\src\Shared\ServerCertificateValidationHandler.cs" Link="Includes\ServerCertificateValidationHandler.cs" />
     <Compile Include="$(RepoRoot)\src\Shared\ServerCertificateValidationProvider.cs" Link="Includes\ServerCertificateValidationProvider.cs" />
-    <Compile Include="$(RepoRoot)\src\Shared\ServerCertificateValidationEventSource.cs" Link="Includes\ServerCertificateValidationEventSource.cs" />
   </ItemGroup>
 
 </Project>
diff --git a/src/Shared/ServerCertificateValidationHandler.cs b/src/Shared/ServerCertificateValidationHandler.cs
index 551b7b1645..aca8d4d29c 100644
--- a/src/Shared/ServerCertificateValidationHandler.cs
+++ b/src/Shared/ServerCertificateValidationHandler.cs
@@ -11,15 +11,15 @@ namespace OpenTelemetry.ResourceDetectors;
 
 internal class ServerCertificateValidationHandler
 {
-    public static HttpClientHandler? Create(string certificateFile)
+    public static HttpClientHandler? Create(string certificateFile, Action<string, string>? logFailedToValidateCertificate = null, Action<string, string>? logFailedToExtractResourceAttributes = null)
     {
         try
         {
-            ServerCertificateValidationProvider? serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateFile);
+            ServerCertificateValidationProvider? serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateFile, logFailedToValidateCertificate);
 
             if (serverCertificateValidationProvider == null)
             {
-                ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationHandler), "Failed to Load the certificate file into trusted collection");
+                logFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationHandler), "Failed to Load the certificate file into trusted collection");
                 return null;
             }
 
@@ -33,7 +33,7 @@ internal class ServerCertificateValidationHandler
         }
         catch (Exception ex)
         {
-            ServerCertificateValidationEventSource.Log.FailedToExtractResourceAttributes($"{nameof(ServerCertificateValidationHandler)} : Failed to create HttpClientHandler", ex.ToInvariantString());
+            logFailedToExtractResourceAttributes?.Invoke($"{nameof(ServerCertificateValidationHandler)} : Failed to create HttpClientHandler", ex.ToInvariantString());
         }
 
         return null;
diff --git a/src/Shared/ServerCertificateValidationProvider.cs b/src/Shared/ServerCertificateValidationProvider.cs
index d036c9d5b9..d58a42ae99 100644
--- a/src/Shared/ServerCertificateValidationProvider.cs
+++ b/src/Shared/ServerCertificateValidationProvider.cs
@@ -13,141 +13,144 @@ namespace OpenTelemetry.ResourceDetectors;
 
 internal class ServerCertificateValidationProvider
 {
-  private readonly X509Certificate2Collection trustedCertificates;
+    public static Action<string, string>? LogFailedToValidateCertificate;
 
-  private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates)
-  {
-    this.trustedCertificates = trustedCertificates;
-    this.ValidationCallback = (_, cert, chain, errors) =>
-        this.ValidateCertificate(cert != null ? new X509Certificate2(cert) : null, chain, errors);
-  }
+    private readonly X509Certificate2Collection trustedCertificates;
 
-  public RemoteCertificateValidationCallback ValidationCallback { get; }
-
-  public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile)
-  {
-    if (!File.Exists(certificateFile))
+    private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates, Action<string, string>? logFailedToValidateCertificate = null)
     {
-      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist");
-      return null;
+        this.trustedCertificates = trustedCertificates;
+        this.ValidationCallback = (_, cert, chain, errors) =>
+            this.ValidateCertificate(cert != null ? new X509Certificate2(cert) : null, chain, errors);
+        LogFailedToValidateCertificate = logFailedToValidateCertificate;
     }
 
-    var trustedCertificates = new X509Certificate2Collection();
-    if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile))
+    public RemoteCertificateValidationCallback ValidationCallback { get; }
+
+    public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile, Action<string, string>? failedToValidateCertificate = null)
     {
-      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection");
-      return null;
-    }
+        if (!File.Exists(certificateFile))
+        {
+            failedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "Certificate File does not exist");
+            return null;
+        }
 
-    return new ServerCertificateValidationProvider(trustedCertificates);
-  }
+        var trustedCertificates = new X509Certificate2Collection();
+        if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile))
+        {
+            failedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection");
+            return null;
+        }
 
-  private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName)
-  {
-    try
-    {
-      collection.Import(certFileName);
-      return true;
+        return new ServerCertificateValidationProvider(trustedCertificates, failedToValidateCertificate);
     }
-    catch (Exception)
-    {
-      return false;
-    }
-  }
 
-  private static bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection? collection)
-  {
-    if (collection == null)
+    private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName)
     {
-      return false;
+        try
+        {
+            collection.Import(certFileName);
+            return true;
+        }
+        catch (Exception)
+        {
+            return false;
+        }
     }
 
-    foreach (var chainElement in chain.ChainElements)
+    private static bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection? collection)
     {
-      foreach (var certificate in collection)
-      {
-        if (chainElement.Certificate.GetPublicKey().SequenceEqual(certificate.GetPublicKey()))
+        if (collection == null)
         {
-          return true;
+            return false;
         }
-      }
-    }
 
-    return false;
-  }
+        foreach (var chainElement in chain.ChainElements)
+        {
+            foreach (var certificate in collection)
+            {
+                if (chainElement.Certificate.GetPublicKey().SequenceEqual(certificate.GetPublicKey()))
+                {
+                    return true;
+                }
+            }
+        }
 
-  private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPolicyErrors errors)
-  {
-    var isSslPolicyPassed = errors == SslPolicyErrors.None ||
-                            errors == SslPolicyErrors.RemoteCertificateChainErrors;
-    if (!isSslPolicyPassed)
-    {
-      if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors)
-      {
-        ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable");
-      }
-
-      if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors)
-      {
-        ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch");
-      }
+        return false;
     }
 
-    if (chain == null)
+    private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPolicyErrors errors)
     {
-      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate chain is null.");
-      return false;
-    }
+        var isSslPolicyPassed = errors == SslPolicyErrors.None ||
+                                errors == SslPolicyErrors.RemoteCertificateChainErrors;
+        if (!isSslPolicyPassed)
+        {
+            if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors)
+            {
+                LogFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable");
+            }
+
+            if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors)
+            {
+                LogFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch");
+            }
+        }
 
-    if (cert == null)
-    {
-      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate is null.");
-      return false;
-    }
+        if (chain == null)
+        {
+            LogFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate chain is null.");
+            return false;
+        }
 
-    chain.ChainPolicy.ExtraStore.AddRange(this.trustedCertificates);
-    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
+        if (cert == null)
+        {
+            LogFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate is null.");
+            return false;
+        }
 
-    // building the chain to process basic validations e.g. signature, use, expiration, revocation
-    var isValidChain = chain.Build(cert);
+        chain.ChainPolicy.ExtraStore.AddRange(this.trustedCertificates);
+        chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
 
-    if (!isValidChain)
-    {
-      var chainErrors = string.Empty;
-      foreach (var element in chain.ChainElements)
-      {
-        foreach (var status in element.ChainElementStatus)
+        // building the chain to process basic validations e.g. signature, use, expiration, revocation
+        var isValidChain = chain.Build(cert);
+
+        if (!isValidChain)
         {
-          chainErrors +=
-              $"\nCertificate [{element.Certificate.Subject}] Status [{status.Status}]: {status.StatusInformation}";
+            var chainErrors = string.Empty;
+            foreach (var element in chain.ChainElements)
+            {
+                foreach (var status in element.ChainElementStatus)
+                {
+                    chainErrors +=
+                        $"\nCertificate [{element.Certificate.Subject}] Status [{status.Status}]: {status.StatusInformation}";
+                }
+            }
+
+            LogFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}");
         }
-      }
 
-      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}");
-    }
+        // check if at least one certificate in the chain is in our trust list
+        var isTrusted = HasCommonCertificate(chain, this.trustedCertificates);
+        if (!isTrusted)
+        {
+            var serverCertificates = string.Empty;
+            foreach (var element in chain.ChainElements)
+            {
+                serverCertificates += " " + element.Certificate.Subject;
+            }
+
+            var trustCertificates = string.Empty;
+            foreach (var trustCertificate in this.trustedCertificates)
+            {
+                trustCertificates += " " + trustCertificate.Subject;
+            }
+
+            LogFailedToValidateCertificate?.Invoke(
+                nameof(ServerCertificateValidationProvider),
+                $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}");
+        }
 
-    // check if at least one certificate in the chain is in our trust list
-    var isTrusted = HasCommonCertificate(chain, this.trustedCertificates);
-    if (!isTrusted)
-    {
-      var serverCertificates = string.Empty;
-      foreach (var element in chain.ChainElements)
-      {
-        serverCertificates += " " + element.Certificate.Subject;
-      }
-
-      var trustCertificates = string.Empty;
-      foreach (var trustCertificate in this.trustedCertificates)
-      {
-        trustCertificates += " " + trustCertificate.Subject;
-      }
-
-      ServerCertificateValidationEventSource.Log.FailedToValidateCertificate(
-          nameof(ServerCertificateValidationProvider),
-          $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}");
+        return isSslPolicyPassed && isValidChain && isTrusted;
     }
-
-    return isSslPolicyPassed && isValidChain && isTrusted;
-  }
 }
 #endif

From 5158730a1a67e419405c073ec5f3a8c9eb61558a Mon Sep 17 00:00:00 2001
From: Anoop Babu <anoobabu@cisco.com>
Date: Mon, 29 Jan 2024 19:21:07 -0500
Subject: [PATCH 4/5] Remove unncessary file

---
 .../ServerCertificateValidationEventSource.cs | 28 -------------------
 1 file changed, 28 deletions(-)
 delete mode 100644 src/Shared/ServerCertificateValidationEventSource.cs

diff --git a/src/Shared/ServerCertificateValidationEventSource.cs b/src/Shared/ServerCertificateValidationEventSource.cs
deleted file mode 100644
index 854e813a5c..0000000000
--- a/src/Shared/ServerCertificateValidationEventSource.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright The OpenTelemetry Authors
-// SPDX-License-Identifier: Apache-2.0
-
-#if !NETFRAMEWORK
-
-using System.Diagnostics.Tracing;
-
-namespace OpenTelemetry.ResourceDetectors;
-
-[EventSource(Name = "OpenTelemetry-ResourceDetectors-Http")]
-internal class ServerCertificateValidationEventSource : EventSource
-{
-    public static ServerCertificateValidationEventSource Log = new();
-
-    [Event(1, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)]
-    public void FailedToExtractResourceAttributes(string format, string exception)
-    {
-        this.WriteEvent(3, format, exception);
-    }
-
-    [Event(2, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)]
-    public void FailedToValidateCertificate(string format, string error)
-    {
-        this.WriteEvent(4, format, error);
-    }
-}
-
-#endif

From ef63c273b4ea4b66ad2cb9a59581b2e28064663b Mon Sep 17 00:00:00 2001
From: Anoop Babu <anoobabu@cisco.com>
Date: Wed, 7 Feb 2024 17:08:49 -0500
Subject: [PATCH 5/5] Updated change to fix the AWS Event Source and changed
 delegate logger to an interface on the event source

---
 opentelemetry-dotnet-contrib.sln              |  3 +--
 .../AWSEKSResourceDetector.cs                 |  3 +--
 .../AWSResourcesEventSource.cs                |  2 +-
 ...OpenTelemetry.ResourceDetectors.AWS.csproj |  1 +
 ...IServerCertificateValidationEventSource.cs | 11 ++++++++
 .../ServerCertificateValidationHandler.cs     |  8 +++---
 .../ServerCertificateValidationProvider.cs    | 26 +++++++++----------
 7 files changed, 32 insertions(+), 22 deletions(-)
 create mode 100644 src/Shared/IServerCertificateValidationEventSource.cs

diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln
index 9f02511871..f9393852cf 100644
--- a/opentelemetry-dotnet-contrib.sln
+++ b/opentelemetry-dotnet-contrib.sln
@@ -276,6 +276,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E
 		src\Shared\ExceptionExtensions.cs = src\Shared\ExceptionExtensions.cs
 		src\Shared\Guard.cs = src\Shared\Guard.cs
 		src\Shared\InstrumentationEventSource.cs = src\Shared\InstrumentationEventSource.cs
+		src\Shared\IServerCertificateValidationEventSource.cs = src\Shared\IServerCertificateValidationEventSource.cs
 		src\Shared\IsExternalInit.cs = src\Shared\IsExternalInit.cs
 		src\Shared\ListenerHandler.cs = src\Shared\ListenerHandler.cs
 		src\Shared\MultiTypePropertyFetcher.cs = src\Shared\MultiTypePropertyFetcher.cs
@@ -283,8 +284,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E
 		src\Shared\PropertyFetcher.cs = src\Shared\PropertyFetcher.cs
 		src\Shared\ResourceSemanticConventions.cs = src\Shared\ResourceSemanticConventions.cs
 		src\Shared\SemanticConventions.cs = src\Shared\SemanticConventions.cs
-		src\Shared\ServerCertificateValidationHandler.cs = src\Shared\ServerCertificateValidationHandler.cs
-		src\Shared\ServerCertificateValidationProvider.cs = src\Shared\ServerCertificateValidationProvider.cs
 		src\Shared\ServiceProviderExtensions.cs = src\Shared\ServiceProviderExtensions.cs
 		src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs
 		src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs
index abf2f2de17..c8a616f2b7 100644
--- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs
+++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs
@@ -30,8 +30,7 @@ public sealed class AWSEKSResourceDetector : IResourceDetector
     public Resource Detect()
     {
         var credentials = GetEKSCredentials(AWSEKSCredentialPath);
-        using var httpClientHandler = ServerCertificateValidationHandler.Create(
-            AWSEKSCertificatePath, AWSResourcesEventSource.Log.FailedToValidateCertificate, AWSResourcesEventSource.Log.FailedToExtractResourceAttributes);
+        using var httpClientHandler = ServerCertificateValidationHandler.Create(AWSEKSCertificatePath, AWSResourcesEventSource.Log);
 
         if (credentials == null || !IsEKSProcess(credentials, httpClientHandler))
         {
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs
index e34bb70909..b6e009089a 100644
--- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs
+++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs
@@ -8,7 +8,7 @@
 namespace OpenTelemetry.ResourceDetectors.AWS;
 
 [EventSource(Name = "OpenTelemetry-ResourceDetectors-AWS")]
-internal sealed class AWSResourcesEventSource : EventSource
+internal sealed class AWSResourcesEventSource : EventSource, IServerCertificateValidationEventSource
 {
     public static AWSResourcesEventSource Log = new();
 
diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj
index 8b87636a88..2038cb34b7 100644
--- a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj
+++ b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj
@@ -23,6 +23,7 @@
 
   <ItemGroup>
     <Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
+    <Compile Include="$(RepoRoot)\src\Shared\IServerCertificateValidationEventSource.cs" Link="Includes\IServerCertificateValidationEventSource.cs" />
     <Compile Include="$(RepoRoot)\src\Shared\ServerCertificateValidationHandler.cs" Link="Includes\ServerCertificateValidationHandler.cs" />
     <Compile Include="$(RepoRoot)\src\Shared\ServerCertificateValidationProvider.cs" Link="Includes\ServerCertificateValidationProvider.cs" />
   </ItemGroup>
diff --git a/src/Shared/IServerCertificateValidationEventSource.cs b/src/Shared/IServerCertificateValidationEventSource.cs
new file mode 100644
index 0000000000..c29acbb45c
--- /dev/null
+++ b/src/Shared/IServerCertificateValidationEventSource.cs
@@ -0,0 +1,11 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+namespace OpenTelemetry.ResourceDetectors;
+
+internal interface IServerCertificateValidationEventSource
+{
+    public void FailedToExtractResourceAttributes(string format, string exception);
+
+    public void FailedToValidateCertificate(string format, string error);
+}
diff --git a/src/Shared/ServerCertificateValidationHandler.cs b/src/Shared/ServerCertificateValidationHandler.cs
index aca8d4d29c..b24cc93d1d 100644
--- a/src/Shared/ServerCertificateValidationHandler.cs
+++ b/src/Shared/ServerCertificateValidationHandler.cs
@@ -11,15 +11,15 @@ namespace OpenTelemetry.ResourceDetectors;
 
 internal class ServerCertificateValidationHandler
 {
-    public static HttpClientHandler? Create(string certificateFile, Action<string, string>? logFailedToValidateCertificate = null, Action<string, string>? logFailedToExtractResourceAttributes = null)
+    public static HttpClientHandler? Create(string certificateFile, IServerCertificateValidationEventSource? log = null)
     {
         try
         {
-            ServerCertificateValidationProvider? serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateFile, logFailedToValidateCertificate);
+            ServerCertificateValidationProvider? serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateFile, log);
 
             if (serverCertificateValidationProvider == null)
             {
-                logFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationHandler), "Failed to Load the certificate file into trusted collection");
+                log?.FailedToValidateCertificate(nameof(ServerCertificateValidationHandler), "Failed to Load the certificate file into trusted collection");
                 return null;
             }
 
@@ -33,7 +33,7 @@ internal class ServerCertificateValidationHandler
         }
         catch (Exception ex)
         {
-            logFailedToExtractResourceAttributes?.Invoke($"{nameof(ServerCertificateValidationHandler)} : Failed to create HttpClientHandler", ex.ToInvariantString());
+            log?.FailedToExtractResourceAttributes($"{nameof(ServerCertificateValidationHandler)} : Failed to create HttpClientHandler", ex.ToInvariantString());
         }
 
         return null;
diff --git a/src/Shared/ServerCertificateValidationProvider.cs b/src/Shared/ServerCertificateValidationProvider.cs
index 75b546c2a2..d270274376 100644
--- a/src/Shared/ServerCertificateValidationProvider.cs
+++ b/src/Shared/ServerCertificateValidationProvider.cs
@@ -13,36 +13,36 @@ namespace OpenTelemetry.ResourceDetectors;
 
 internal class ServerCertificateValidationProvider
 {
-    public static Action<string, string>? LogFailedToValidateCertificate;
+    public static IServerCertificateValidationEventSource? Log;
 
     private readonly X509Certificate2Collection trustedCertificates;
 
-    private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates, Action<string, string>? logFailedToValidateCertificate = null)
+    private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates, IServerCertificateValidationEventSource? log = null)
     {
         this.trustedCertificates = trustedCertificates;
         this.ValidationCallback = (_, cert, chain, errors) =>
             this.ValidateCertificate(cert != null ? new X509Certificate2(cert) : null, chain, errors);
-        LogFailedToValidateCertificate = logFailedToValidateCertificate;
+        Log = log;
     }
 
     public RemoteCertificateValidationCallback ValidationCallback { get; }
 
-    public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile, Action<string, string>? failedToValidateCertificate = null)
+    public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile, IServerCertificateValidationEventSource? log = null)
     {
         if (!File.Exists(certificateFile))
         {
-            failedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "Certificate File does not exist");
+            log?.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist");
             return null;
         }
 
         var trustedCertificates = new X509Certificate2Collection();
         if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile))
         {
-            failedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection");
+            log?.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection");
             return null;
         }
 
-        return new ServerCertificateValidationProvider(trustedCertificates, failedToValidateCertificate);
+        return new ServerCertificateValidationProvider(trustedCertificates, log);
     }
 
     private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName)
@@ -87,24 +87,24 @@ private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPo
         {
             if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors)
             {
-                LogFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "SslPolicyError RemoteCertificateNotAvailable occurred");
+                Log?.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "SslPolicyError RemoteCertificateNotAvailable occurred");
             }
 
             if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors)
             {
-                LogFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "SslPolicyError RemoteCertificateNameMismatch occurred");
+                Log?.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "SslPolicyError RemoteCertificateNameMismatch occurred");
             }
         }
 
         if (chain == null)
         {
-            LogFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "Certificate chain is null.");
+            Log?.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate chain is null.");
             return false;
         }
 
         if (cert == null)
         {
-            LogFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), "Certificate is null.");
+            Log?.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate is null.");
             return false;
         }
 
@@ -126,7 +126,7 @@ private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPo
                 }
             }
 
-            LogFailedToValidateCertificate?.Invoke(nameof(ServerCertificateValidationProvider), chainErrors);
+            Log?.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), chainErrors);
         }
 
         // check if at least one certificate in the chain is in our trust list
@@ -145,7 +145,7 @@ private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPo
                 trustCertificates += " " + trustCertificate.Subject;
             }
 
-            LogFailedToValidateCertificate?.Invoke(
+            Log?.FailedToValidateCertificate(
                 nameof(ServerCertificateValidationProvider),
                 $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}");
         }