From 34e411ac6e9ec639e6293bc999aa1173bfa163db Mon Sep 17 00:00:00 2001 From: srprash <50466688+srprash@users.noreply.github.com> Date: Wed, 10 Jun 2020 00:08:17 +0530 Subject: [PATCH 01/37] Create stale.yml (#136) --- .github/stale.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000..4c8e4081 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,24 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 30 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Limit to only `issues` or `pulls` +only: issues +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - bug + - enhancement + - feature-request + - help wanted + - work-in-progress + - pending release +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs in next 7 days. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false From 63bb73c4b3a1d0de4629d557e01d0dda9458668a Mon Sep 17 00:00:00 2001 From: srprash <50466688+srprash@users.noreply.github.com> Date: Wed, 10 Jun 2020 22:37:35 +0530 Subject: [PATCH 02/37] Release commit for v2.9.0 (#137) --- CHANGELOG.md | 33 +++++++++++++++++++ sdk/AWSXRayRecorder.nuspec | 24 +++++++------- sdk/src/Core/AWSXRayRecorder.Core.csproj | 6 ++-- .../AWSXRayRecorder.Handlers.AspNet.csproj | 6 ++-- ...AWSXRayRecorder.Handlers.AspNetCore.csproj | 6 ++-- .../AWSXRayRecorder.Handlers.AwsSdk.csproj | 6 ++-- ...ayRecorder.Handlers.EntityFramework.csproj | 6 ++-- .../AWSXRayRecorder.Handlers.SqlServer.csproj | 6 ++-- ...AWSXRayRecorder.Handlers.System.Net.csproj | 6 ++-- 9 files changed, 66 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 400d2603..8d07331f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,39 @@ # Change Log All notable changes to this project will be documented in this file. +## 2.9.0 (2020-06-09) +### AWSXRayRecorder.Core (2.9.0) +#### Fixed +- Added .gitattributes file and normalized line endings [PR#132](https://github.com/aws/aws-xray-sdk-dotnet/pull/132) + +#### Improved +- Added IMDSv2 support [PR#134](https://github.com/aws/aws-xray-sdk-dotnet/pull/134) + +### AWSXRayRecorder.Handlers.AwsSdk (2.8.1) +#### Fixed +- Added .gitattributes file and normalized line endings [PR#132](https://github.com/aws/aws-xray-sdk-dotnet/pull/132) + +### AWSXRayRecorder.Handlers.EntityFramework (1.0.1) +#### Fixed +- Added .gitattributes file and normalized line endings [PR#132](https://github.com/aws/aws-xray-sdk-dotnet/pull/132) + +### AWSXRayRecorder.Handlers.AspNet (2.7.1) +#### Fixed +- Added .gitattributes file and normalized line endings [PR#132](https://github.com/aws/aws-xray-sdk-dotnet/pull/132) + +### AWSXRayRecorder.Handlers.AspNetCore (2.7.1) +#### Fixed +- Fixed typo in AWSXRayMiddlewareExtensions.cs. From Applicaion to Application [PR#131](https://github.com/aws/aws-xray-sdk-dotnet/pull/131) +- Added .gitattributes file and normalized line endings [PR#132](https://github.com/aws/aws-xray-sdk-dotnet/pull/132) + +### AWSXRayRecorder.Handlers.SqlServer (2.7.1) +#### Fixed +- Added .gitattributes file and normalized line endings [PR#132](https://github.com/aws/aws-xray-sdk-dotnet/pull/132) + +### AWSXRayRecorder.Handlers.System.Net (2.7.1) +#### Fixed +- Added .gitattributes file and normalized line endings [PR#132](https://github.com/aws/aws-xray-sdk-dotnet/pull/132) + ## 2.8.0 (2020-04-17) ### AWSXRayRecorder.Core (2.8.0) #### Fixed diff --git a/sdk/AWSXRayRecorder.nuspec b/sdk/AWSXRayRecorder.nuspec index a0314fcc..dfa5307d 100644 --- a/sdk/AWSXRayRecorder.nuspec +++ b/sdk/AWSXRayRecorder.nuspec @@ -2,7 +2,7 @@ AWSXRayRecorder - 2.8.0 + 2.9.0 AWS X-Ray Recorder AWS Web Service http://aws.amazon.com/apache2.0/ @@ -15,19 +15,19 @@ AWS Amazon cloud AWSXRay XRay - - - - - + + + + + - - - - - - + + + + + + diff --git a/sdk/src/Core/AWSXRayRecorder.Core.csproj b/sdk/src/Core/AWSXRayRecorder.Core.csproj index 6b243959..14ad64dc 100644 --- a/sdk/src/Core/AWSXRayRecorder.Core.csproj +++ b/sdk/src/Core/AWSXRayRecorder.Core.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.8.0.0 - 2.8.0.0 - 2.8.0 + 2.9.0.0 + 2.9.0.0 + 2.9.0 Amazon.XRay.Recorder.Core true ../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj b/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj index 7528e61d..0c7b2367 100644 --- a/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj +++ b/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.0.0 - 2.7.0.0 - 2.7.0 + 2.7.1.0 + 2.7.1.0 + 2.7.1 Amazon.XRay.Recorder.Handlers.AspNet true ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj b/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj index 69026f8e..0c3cae83 100644 --- a/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj +++ b/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj @@ -4,9 +4,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.0.0 - 2.7.0.0 - 2.7.0 + 2.7.1.0 + 2.7.1.0 + 2.7.1 true Amazon.XRay.Recorder.Handlers.AspNetCore ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj b/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj index 0c5a5fe0..15f283fe 100644 --- a/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj +++ b/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.8.0.0 - 2.8.0.0 - 2.8.0 + 2.8.1.0 + 2.8.1.0 + 2.8.1 Amazon.XRay.Recorder.Handlers.AwsSdk true ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj b/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj index 3cadc010..baaa9804 100644 --- a/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj +++ b/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 1.0.0.0 - 1.0.0.0 - 1.0.0 + 1.0.1.0 + 1.0.1.0 + 1.0.1 AWSXRayRecorder.Handlers.EntityFramework Amazon.XRay.Recorder.Handlers.EntityFramework Amazon Web Services diff --git a/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj b/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj index 37934ece..425fc0c3 100644 --- a/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj +++ b/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.0.0 - 2.7.0.0 - 2.7.0 + 2.7.1.0 + 2.7.1.0 + 2.7.1 Amazon.XRay.Recorder.Handlers.SqlServer true ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj b/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj index 9fd164ff..04a29183 100644 --- a/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj +++ b/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.0.0 - 2.7.0.0 - 2.7.0 + 2.7.1.0 + 2.7.1.0 + 2.7.1 Amazon.XRay.Recorder.Handlers.System.Net true ../../../../buildtools/local-development.snk From ac6fe04fc4d07ea8a4787cddd2ab15d018d8de73 Mon Sep 17 00:00:00 2001 From: srprash <50466688+srprash@users.noreply.github.com> Date: Mon, 22 Jun 2020 19:59:04 -0700 Subject: [PATCH 03/37] Added 2 seconds timeout for EC2 metadata requests (#138) --- sdk/src/Core/Plugins/EC2Plugin.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/src/Core/Plugins/EC2Plugin.cs b/sdk/src/Core/Plugins/EC2Plugin.cs index dd96fd42..19718a2b 100644 --- a/sdk/src/Core/Plugins/EC2Plugin.cs +++ b/sdk/src/Core/Plugins/EC2Plugin.cs @@ -131,6 +131,7 @@ protected virtual async Task DoRequest(string url, HttpMethod method, Di } } + _client.Timeout = TimeSpan.FromSeconds(2); // 2 seconds timeout HttpResponseMessage response = await _client.SendAsync(request); if (response.IsSuccessStatusCode) { From 1e05a2b34d09b4128ec577d3f9c789d8bef23929 Mon Sep 17 00:00:00 2001 From: Anuraag Agrawal Date: Thu, 16 Jul 2020 12:39:42 +0900 Subject: [PATCH 04/37] Update NOTICE so it only has third party licenses and no proprietary notice (#139) --- NOTICE.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index bb306549..344095f6 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1,6 +1,3 @@ -AWS X-Ray Recorder SDK for .NET -Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. - ********************** THIRD PARTY COMPONENTS ********************** @@ -52,4 +49,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [This is the BSD license, see - http://opensource.org/licenses/BSD-3-Clause] \ No newline at end of file + http://opensource.org/licenses/BSD-3-Clause] From 0c1b817d46ced10d5cb472bb3ce3177b85068621 Mon Sep 17 00:00:00 2001 From: srprash <50466688+srprash@users.noreply.github.com> Date: Fri, 14 Aug 2020 12:42:18 -0700 Subject: [PATCH 05/37] Fixing link to EFCore usage section (#143) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 305817df..d999941b 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Following API reference documentation provides guidance for using the SDK and mo 4. [Trace AWS SDK request](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-aws-sdk-request-net-and-net-core--nuget) 5. [Trace out-going HTTP requests](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-out-going-http-requests-net-and-net-core--nuget) 6. [Trace Query to SQL Server](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-query-to-sql-server-net-and-net-core--nuget) -7. [Trace SQL Query through Entity Framework Core 3.0 and above](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-sql-query-through-entity-framework-core-30-and-above-net-core) +7. [Trace SQL Query through Entity Framework Core 3.0 and above](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-sql-query-through-entity-framework-core-30-and-above-net-core--nuget) 8. [Multithreaded Execution](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#multithreaded-execution-net-and-net-core--nuget) 9. [Trace custom methods ](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-custom-methods-net-and-net-core) 10. [Creating custom Segment/Subsegment](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#creating-custom-segmentsubsegment-net-and-net-core) From 3ae4cdb1960d2dd5bd33b604eae1d561ca529c4b Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Tue, 25 Aug 2020 12:17:35 -0700 Subject: [PATCH 06/37] Added EF Core installation instruction step (#145) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d999941b..d29ff8a6 100644 --- a/README.md +++ b/README.md @@ -392,6 +392,7 @@ For how to start with Entity Framework Core in an ASP.NET Core web app, please t *NOTE:* +* You need to install `AWSXRayRecorder.Handlers.EntityFramework` nuget package. This package adds extension methods to the `DbContextOptionsBuilder` to make it easy to register AWS X-Ray interceptor. * Not all database provider support Entity Framework Core 3.0 and above, please make sure that you are using the [Nuget package](https://docs.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli) with a compatible version (EF Core >= 3.0). #### Setup From 8461c354d783da96a052015ff111f31a91b131d0 Mon Sep 17 00:00:00 2001 From: srprash <50466688+srprash@users.noreply.github.com> Date: Mon, 12 Oct 2020 20:44:56 -0700 Subject: [PATCH 07/37] Fixing race condition for initializing and running timer in RulePoller (#154) --- sdk/src/Core/Sampling/RulePoller.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sdk/src/Core/Sampling/RulePoller.cs b/sdk/src/Core/Sampling/RulePoller.cs index 53ef5b0d..3da42261 100644 --- a/sdk/src/Core/Sampling/RulePoller.cs +++ b/sdk/src/Core/Sampling/RulePoller.cs @@ -46,12 +46,8 @@ public RulePoller(RuleCache ruleCache) internal void Poll(IConnector connector) { _connector = connector; - _timer = InitializeTimer(); - } - - private Timer InitializeTimer() - { - return new Timer(Start, null, 0, 0); + _timer = new Timer(Start); + _timer.Change(0, 0); } internal async void Start(Object state) @@ -93,7 +89,10 @@ private async Task RefreshCache() internal void WakeUp() { _timer.Dispose(); - _timer = InitializeTimer(); // Perform out of band polling + + // Perform out of band polling + _timer = new Timer(Start); + _timer.Change(0, 0); } private int GetDelay() From 4a7ed00486ccd1f4ac0e8434e61d42e732f13937 Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Wed, 14 Oct 2020 16:20:58 -0700 Subject: [PATCH 08/37] Bump AWSSDK.Core dependency version (#155) * Bump AWSSDK.Core dependency version * Bumped AWSSDK.Core version as range. * Removed redundant dependency --- sdk/src/Core/AWSXRayRecorder.Core.csproj | 4 ++-- .../AWSXRayRecorder.Handlers.AspNet.csproj | 4 ---- .../AWSXRayRecorder.Handlers.AwsSdk.csproj | 4 ---- .../AWSXRayRecorder.Handlers.SqlServer.csproj | 4 ---- ...AWSXRayRecorder.Handlers.System.Net.csproj | 4 ---- .../AWSXRayRecorder.IntegrationTests.csproj | 10 ++++---- .../AWSXRayRecorder.UnitTests.csproj | 10 ++++---- sdk/test/UnitTests/Tools/MockHttpRequest.cs | 23 +++++++++++++++++++ 8 files changed, 35 insertions(+), 28 deletions(-) diff --git a/sdk/src/Core/AWSXRayRecorder.Core.csproj b/sdk/src/Core/AWSXRayRecorder.Core.csproj index 14ad64dc..760a603d 100644 --- a/sdk/src/Core/AWSXRayRecorder.Core.csproj +++ b/sdk/src/Core/AWSXRayRecorder.Core.csproj @@ -38,8 +38,8 @@ - - + + diff --git a/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj b/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj index 0c7b2367..60622d02 100644 --- a/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj +++ b/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj @@ -29,10 +29,6 @@ 1701;1702;1705;1591;1587;1572;1573 - - - - diff --git a/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj b/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj index 15f283fe..fa1b21c2 100644 --- a/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj +++ b/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj @@ -40,10 +40,6 @@ - - - - diff --git a/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj b/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj index 425fc0c3..86e2bcd7 100644 --- a/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj +++ b/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj @@ -29,10 +29,6 @@ 1701;1702;1705;1591;1587;1572;1573 - - - - diff --git a/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj b/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj index 04a29183..2a1d7a0b 100644 --- a/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj +++ b/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj @@ -29,10 +29,6 @@ 1701;1702;1705;1591;1587;1572;1573 - - - - diff --git a/sdk/test/IntegrationTests/AWSXRayRecorder.IntegrationTests.csproj b/sdk/test/IntegrationTests/AWSXRayRecorder.IntegrationTests.csproj index 0353c746..58460316 100644 --- a/sdk/test/IntegrationTests/AWSXRayRecorder.IntegrationTests.csproj +++ b/sdk/test/IntegrationTests/AWSXRayRecorder.IntegrationTests.csproj @@ -13,11 +13,11 @@ - - - - - + + + + + diff --git a/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj b/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj index 6d3720cf..70129ece 100644 --- a/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj +++ b/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj @@ -36,11 +36,11 @@ - - - - - + + + + + diff --git a/sdk/test/UnitTests/Tools/MockHttpRequest.cs b/sdk/test/UnitTests/Tools/MockHttpRequest.cs index fa45af7a..ac53a1a5 100644 --- a/sdk/test/UnitTests/Tools/MockHttpRequest.cs +++ b/sdk/test/UnitTests/Tools/MockHttpRequest.cs @@ -20,6 +20,7 @@ using System.IO; using System.Linq; using System.Net; +using System.Threading; using System.Threading.Tasks; using Amazon.Runtime; using Amazon.Runtime.Internal; @@ -146,5 +147,27 @@ private HttpWebResponse CreateResponse(MockHttpRequest request) } } + + public Task GetRequestContentAsync(CancellationToken cancellationToken) + { + return Task.FromResult(new MemoryStream()); + } + + public Task WriteToRequestBodyAsync(Stream requestContent, Stream contentStream, IDictionary contentHeaders, IRequestContext requestContext) + { + Assert.IsNotNull(requestContent); + Assert.IsNotNull(contentStream); + Assert.IsNotNull(contentHeaders); + Assert.IsNotNull(requestContext); + return Task.FromResult(0); + } + + public Task WriteToRequestBodyAsync(Stream requestContent, byte[] requestData, IDictionary headers, CancellationToken cancellationToken) + { + Assert.IsNotNull(requestContent); + Assert.IsNotNull(requestData); + Assert.IsNotNull(headers); + return Task.FromResult(0); + } } } From a085520b19e9e3fe9d10ac1eacc5a60a8d481374 Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Fri, 6 Nov 2020 11:09:34 -0800 Subject: [PATCH 09/37] Applied HttpClient to get sampling info (#159) * Applied HttpWebRequest to get sampling info and removed dependency on AWSSDK.XRay * Fixed lock issue and switched to HttpClient * Added and modified documentations. * Added documentations. * Set ExpectContinue header as false by default --- sdk/src/Core/AWSXRayRecorder.Core.csproj | 1 - .../Core/Sampling/DefaultSamplingStrategy.cs | 6 +- .../Core/Sampling/GetSamplingRulesResponse.cs | 2 +- .../Sampling/GetSamplingTargetsResponse.cs | 2 +- .../Core/Sampling/Model/SamplingRuleModel.cs | 53 ++++ .../Model/SamplingRuleRecordsModel.cs | 31 ++ .../Model/SamplingRuleResponseModel.cs | 31 ++ .../Model/SamplingStatisticsDocumentModel.cs | 37 +++ .../Sampling/Model/SamplingStatisticsModel.cs | 29 ++ .../Sampling/Model/SamplingTargetModel.cs | 35 +++ .../Model/SamplingTargetResponseModel.cs | 33 +++ .../Model/UnprocessedStatisticsModel.cs | 31 ++ sdk/src/Core/Sampling/SamplingRule.cs | 4 +- sdk/src/Core/Sampling/ServiceConnector.cs | 190 ++++++++---- sdk/src/Core/Sampling/XRayConfig.cs | 37 +++ .../AWSXRayRecorder.UnitTests.csproj | 1 - sdk/test/UnitTests/JsonMapperTest.cs | 275 ++++++++++++++++++ 17 files changed, 731 insertions(+), 67 deletions(-) create mode 100644 sdk/src/Core/Sampling/Model/SamplingRuleModel.cs create mode 100644 sdk/src/Core/Sampling/Model/SamplingRuleRecordsModel.cs create mode 100644 sdk/src/Core/Sampling/Model/SamplingRuleResponseModel.cs create mode 100644 sdk/src/Core/Sampling/Model/SamplingStatisticsDocumentModel.cs create mode 100644 sdk/src/Core/Sampling/Model/SamplingStatisticsModel.cs create mode 100644 sdk/src/Core/Sampling/Model/SamplingTargetModel.cs create mode 100644 sdk/src/Core/Sampling/Model/SamplingTargetResponseModel.cs create mode 100644 sdk/src/Core/Sampling/Model/UnprocessedStatisticsModel.cs create mode 100644 sdk/src/Core/Sampling/XRayConfig.cs create mode 100644 sdk/test/UnitTests/JsonMapperTest.cs diff --git a/sdk/src/Core/AWSXRayRecorder.Core.csproj b/sdk/src/Core/AWSXRayRecorder.Core.csproj index 760a603d..105d7ded 100644 --- a/sdk/src/Core/AWSXRayRecorder.Core.csproj +++ b/sdk/src/Core/AWSXRayRecorder.Core.csproj @@ -39,7 +39,6 @@ - diff --git a/sdk/src/Core/Sampling/DefaultSamplingStrategy.cs b/sdk/src/Core/Sampling/DefaultSamplingStrategy.cs index ea9e02e5..7fecca1b 100644 --- a/sdk/src/Core/Sampling/DefaultSamplingStrategy.cs +++ b/sdk/src/Core/Sampling/DefaultSamplingStrategy.cs @@ -43,9 +43,9 @@ public class DefaultSamplingStrategy : ISamplingStrategy public DaemonConfig DaemonCfg { get; private set; } /// - /// Instance of . + /// Instance of . /// - public AmazonXRayClient XRayClient = null; + public XRayConfig XRayConfig = null; /// /// Instance of . @@ -81,7 +81,7 @@ private void Start() { if (!_isPollerStarted) { - _connector = new ServiceConnector(DaemonCfg, XRayClient); + _connector = new ServiceConnector(DaemonCfg, XRayConfig); _rulePoller.Poll(_connector); _targetPoller.Poll(_connector); _isPollerStarted = true; diff --git a/sdk/src/Core/Sampling/GetSamplingRulesResponse.cs b/sdk/src/Core/Sampling/GetSamplingRulesResponse.cs index 624f6475..a9576622 100644 --- a/sdk/src/Core/Sampling/GetSamplingRulesResponse.cs +++ b/sdk/src/Core/Sampling/GetSamplingRulesResponse.cs @@ -19,7 +19,7 @@ namespace Amazon.XRay.Recorder.Core.Sampling { /// - /// Wrapper to API call response. + /// Class for keep list of sampling rules from x-ray backend. /// public class GetSamplingRulesResponse { diff --git a/sdk/src/Core/Sampling/GetSamplingTargetsResponse.cs b/sdk/src/Core/Sampling/GetSamplingTargetsResponse.cs index bf69a3f4..9fbba06a 100644 --- a/sdk/src/Core/Sampling/GetSamplingTargetsResponse.cs +++ b/sdk/src/Core/Sampling/GetSamplingTargetsResponse.cs @@ -19,7 +19,7 @@ namespace Amazon.XRay.Recorder.Core.Sampling { /// - /// Wrapper for API call response. + /// Class for keep last rule modification timestamp and list of sampling targets from x-ray backend. /// public class GetSamplingTargetsResponse { diff --git a/sdk/src/Core/Sampling/Model/SamplingRuleModel.cs b/sdk/src/Core/Sampling/Model/SamplingRuleModel.cs new file mode 100644 index 00000000..65ee367f --- /dev/null +++ b/sdk/src/Core/Sampling/Model/SamplingRuleModel.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +using System.Collections.Generic; + +namespace Amazon.XRay.Recorder.Core.Sampling.Model +{ + /// + /// Class model for unmarshalling sampling rule from sampling rule response json. + /// + public class SamplingRuleModel + { + public string RuleName; + + public int? Priority; + + public double? FixedRate; + + public int? ReservoirSize; + + public string Host; + + public string ServiceName; + + public string HTTPMethod; + + public string URLPath; + + public string ServiceType; + + public string ResourceARN; + + public string RuleARN; + + public int? Version; + + public Dictionary Attributes; + } +} diff --git a/sdk/src/Core/Sampling/Model/SamplingRuleRecordsModel.cs b/sdk/src/Core/Sampling/Model/SamplingRuleRecordsModel.cs new file mode 100644 index 00000000..25f030df --- /dev/null +++ b/sdk/src/Core/Sampling/Model/SamplingRuleRecordsModel.cs @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +namespace Amazon.XRay.Recorder.Core.Sampling.Model +{ + /// + /// Class model for unmarshalling sampling rule record from sampling rule response json. + /// + public class SamplingRuleRecordsModel + { + public double? CreatedAt; + + public double? ModifiedAt; + + public SamplingRuleModel SamplingRule; + } +} diff --git a/sdk/src/Core/Sampling/Model/SamplingRuleResponseModel.cs b/sdk/src/Core/Sampling/Model/SamplingRuleResponseModel.cs new file mode 100644 index 00000000..f805ad1e --- /dev/null +++ b/sdk/src/Core/Sampling/Model/SamplingRuleResponseModel.cs @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +using System.Collections.Generic; + +namespace Amazon.XRay.Recorder.Core.Sampling.Model +{ + /// + /// Class model for unmarshalling sampling rule response json. + /// + public class SamplingRuleResponseModel + { + public string NextToken; + + public List SamplingRuleRecords = new List(); + } +} diff --git a/sdk/src/Core/Sampling/Model/SamplingStatisticsDocumentModel.cs b/sdk/src/Core/Sampling/Model/SamplingStatisticsDocumentModel.cs new file mode 100644 index 00000000..3182db0b --- /dev/null +++ b/sdk/src/Core/Sampling/Model/SamplingStatisticsDocumentModel.cs @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +namespace Amazon.XRay.Recorder.Core.Sampling.Model +{ + /// + /// Class for marshalling sampling statistics document json. + /// + public class SamplingStatisticsDocumentModel + { + public string ClientID { get; set; } + + public string RuleName { get; set; } + + public int? RequestCount { get; set; } + + public int? SampledCount { get; set; } + + public int? BorrowCount { get; set; } + + public double? Timestamp { get; set; } + } +} diff --git a/sdk/src/Core/Sampling/Model/SamplingStatisticsModel.cs b/sdk/src/Core/Sampling/Model/SamplingStatisticsModel.cs new file mode 100644 index 00000000..69f5917c --- /dev/null +++ b/sdk/src/Core/Sampling/Model/SamplingStatisticsModel.cs @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +using System.Collections.Generic; + +namespace Amazon.XRay.Recorder.Core.Sampling.Model +{ + /// + /// Class for marshalling sampling statistics document json. + /// + public class SamplingStatisticsModel + { + public List SamplingStatisticsDocuments { get; set; } = new List(); + } +} diff --git a/sdk/src/Core/Sampling/Model/SamplingTargetModel.cs b/sdk/src/Core/Sampling/Model/SamplingTargetModel.cs new file mode 100644 index 00000000..56c59c39 --- /dev/null +++ b/sdk/src/Core/Sampling/Model/SamplingTargetModel.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +namespace Amazon.XRay.Recorder.Core.Sampling.Model +{ + /// + /// Class model for unmarshalling sampling target from sampling target response json. + /// + public class SamplingTargetModel + { + public double? FixedRate; + + public int? ReservoirQuota; + + public double? ReservoirQuotaTTL; + + public string RuleName; + + public int? Interval; + } +} diff --git a/sdk/src/Core/Sampling/Model/SamplingTargetResponseModel.cs b/sdk/src/Core/Sampling/Model/SamplingTargetResponseModel.cs new file mode 100644 index 00000000..bc5e395d --- /dev/null +++ b/sdk/src/Core/Sampling/Model/SamplingTargetResponseModel.cs @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +using System.Collections.Generic; + +namespace Amazon.XRay.Recorder.Core.Sampling.Model +{ + /// + /// Class model for unmarshalling sampling target response json. + /// + public class SamplingTargetResponseModel + { + public double? LastRuleModification; + + public List SamplingTargetDocuments = new List(); + + public List UnprocessedStatistics = new List(); + } +} diff --git a/sdk/src/Core/Sampling/Model/UnprocessedStatisticsModel.cs b/sdk/src/Core/Sampling/Model/UnprocessedStatisticsModel.cs new file mode 100644 index 00000000..ec0ee8f6 --- /dev/null +++ b/sdk/src/Core/Sampling/Model/UnprocessedStatisticsModel.cs @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +namespace Amazon.XRay.Recorder.Core.Sampling.Model +{ + /// + /// Class for unmarshalling unprocessed statistics from sampling target response json. + /// + public class UnprocessedStatisticsModel + { + public string RuleName; + + public string ErrorCode; + + public string Message; + } +} diff --git a/sdk/src/Core/Sampling/SamplingRule.cs b/sdk/src/Core/Sampling/SamplingRule.cs index 2f8843e6..02e0b15c 100644 --- a/sdk/src/Core/Sampling/SamplingRule.cs +++ b/sdk/src/Core/Sampling/SamplingRule.cs @@ -85,9 +85,9 @@ internal void IncrementSampledCount() /// /// Validates sampling rule. ResourceARN with "*" value is valid. SDK doesn't support Atrributes parameter with any value. /// - /// Instance of + /// Instance of /// True, if the rule is valid else false. - internal static bool IsValid(Model.SamplingRule rule) + internal static bool IsValid(Model.SamplingRuleModel rule) { if (!string.Equals(rule.ResourceARN, "*")) { diff --git a/sdk/src/Core/Sampling/ServiceConnector.cs b/sdk/src/Core/Sampling/ServiceConnector.cs index de783568..5ca4ebf9 100644 --- a/sdk/src/Core/Sampling/ServiceConnector.cs +++ b/sdk/src/Core/Sampling/ServiceConnector.cs @@ -14,13 +14,16 @@ // permissions and limitations under the License. // //----------------------------------------------------------------------------- + using System.Collections.Generic; -using Amazon.XRay.Model; using System.Threading.Tasks; using System; -using Amazon.Runtime; using Amazon.XRay.Recorder.Core.Internal.Utils; using Amazon.Runtime.Internal.Util; +using Amazon.XRay.Recorder.Core.Sampling.Model; +using ThirdParty.LitJson; +using System.Text; +using System.Net.Http; namespace Amazon.XRay.Recorder.Core.Sampling { @@ -32,19 +35,19 @@ namespace Amazon.XRay.Recorder.Core.Sampling class ServiceConnector : IConnector { private static readonly Logger _logger = Logger.GetLogger(typeof(ServiceConnector)); - private AmazonXRayClient _xrayClient; + private XRayConfig _xrayConfig; private readonly object _xrayClientLock = new object(); private const int Version = 1; - private readonly AmazonXRayConfig _config = new AmazonXRayConfig(); - private readonly AWSCredentials _credentials = new AnonymousAWSCredentials(); // sends unsigned requests to daemon endpoint private readonly DaemonConfig _daemonConfig; + private readonly DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + private static readonly HttpClient _httpClient = new HttpClient(); /// /// Client id for the instance. Its 24 digit hex number. /// public string ClientID; - public ServiceConnector(DaemonConfig daemonConfig, AmazonXRayClient xrayClient) + public ServiceConnector(DaemonConfig daemonConfig, XRayConfig xrayConfig) { ClientID = ThreadSafeRandom.GenerateHexNumber(24); if (daemonConfig == null) @@ -53,61 +56,96 @@ public ServiceConnector(DaemonConfig daemonConfig, AmazonXRayClient xrayClient) } _daemonConfig = daemonConfig; - if (xrayClient == null) + if (xrayConfig == null) { - xrayClient = CreateXRayClient(); + xrayConfig = CreateXRayConfig(); } - _xrayClient = xrayClient; + _xrayConfig = xrayConfig; } - private AmazonXRayClient CreateXRayClient() + private XRayConfig CreateXRayConfig() { - _config.ServiceURL = $"http://{_daemonConfig.TCPEndpoint.Address}:{_daemonConfig.TCPEndpoint.Port}"; - return new AmazonXRayClient(_credentials,_config); + var config = new XRayConfig(); + config.ServiceURL = $"http://{_daemonConfig.TCPEndpoint.Address}:{_daemonConfig.TCPEndpoint.Port}"; + return config; } private void RefreshEndPoint() { var serviceUrlCandidate = $"http://{_daemonConfig.TCPEndpoint.Address}:{_daemonConfig.TCPEndpoint.Port}"; - - if (serviceUrlCandidate.Equals(_xrayClient.Config.ServiceURL)) return; // endpoint do not need refreshing - _config.ServiceURL = serviceUrlCandidate; - _xrayClient = new AmazonXRayClient(_credentials, _config); - _logger.DebugFormat($"ServiceConnector Endpoint refreshed to: {_xrayClient.Config.ServiceURL}"); + if (serviceUrlCandidate.Equals(_xrayConfig.ServiceURL)) return; // endpoint do not need refreshing + + _xrayConfig.ServiceURL = serviceUrlCandidate; + _logger.DebugFormat($"ServiceConnector Endpoint refreshed to: {_xrayConfig.ServiceURL}"); } /// - /// Use X-Ray client to get the sampling rules - /// from X-Ray service.The call is proxied and signed by X-Ray Daemon. + /// Get the sampling rules from X-Ray service.The call is proxied and signed by X-Ray Daemon. /// /// - public async Task GetSamplingRules() + public async Task GetSamplingRules() { - List newRules = new List(); - GetSamplingRulesRequest request = new GetSamplingRulesRequest(); - - Task responseTask; + Task responseTask; lock (_xrayClientLock) { RefreshEndPoint(); - responseTask = _xrayClient.GetSamplingRulesAsync(request); + responseTask = GetSamplingInfoAsync(_xrayConfig.ServiceURL + "/GetSamplingRules", string.Empty); } - var response = await responseTask; + var responseContent = await responseTask; + + List samplingRules = UnmarshallSamplingRuleResponse(responseContent); + + GetSamplingRulesResponse result = new GetSamplingRulesResponse(samplingRules); + return result; + } - foreach(var record in response.SamplingRuleRecords) + private async Task GetSamplingInfoAsync(string url, string content) + { + using (var stringContent = new StringContent(content, Encoding.UTF8, "application/json")) { - var rule = record.SamplingRule; - if (rule.Version == Version && SamplingRule.IsValid(rule)) // We currently only handle v1 sampling rules. + // Need to set header "ExpectContinue" as false for Daemon to sign properly. + // https://github.com/aws/aws-sdk-net/blob/master/sdk/src/Core/Amazon.Runtime/Internal/AmazonWebServiceRequest.cs#L41 + _httpClient.DefaultRequestHeaders.ExpectContinue = false; + using (var response = await _httpClient.PostAsync(url, stringContent)) { - var sampleRule = new SamplingRule(rule.RuleName, rule.Priority, rule.FixedRate, rule.ReservoirSize, rule.Host, rule.ServiceName, rule.HTTPMethod, rule.URLPath, rule.ServiceType, rule.ResourceARN, rule.Attributes); - newRules.Add(sampleRule); + response.EnsureSuccessStatusCode(); + return await response.Content.ReadAsStringAsync(); } } + } - GetSamplingRulesResponse result = new GetSamplingRulesResponse(newRules); - return result; + private List UnmarshallSamplingRuleResponse(string responseContent) + { + List samplingRules = new List(); + + var samplingRuleResponse = JsonMapper.ToObject(responseContent); + + foreach (var samplingRuleRecord in samplingRuleResponse.SamplingRuleRecords) + { + var samplingRuleModel = samplingRuleRecord.SamplingRule; + if (samplingRuleModel.Version.GetValueOrDefault() == Version && SamplingRule.IsValid(samplingRuleModel)) + { + var samplingRule = new SamplingRule + ( + samplingRuleModel.RuleName, + samplingRuleModel.Priority.GetValueOrDefault(), + samplingRuleModel.FixedRate.GetValueOrDefault(), + samplingRuleModel.ReservoirSize.GetValueOrDefault(), + samplingRuleModel.Host, + samplingRuleModel.ServiceName, + samplingRuleModel.HTTPMethod, + samplingRuleModel.URLPath, + samplingRuleModel.ServiceType, + samplingRuleModel.ResourceARN, + samplingRuleModel.Attributes + ); + samplingRules.Add(samplingRule); + } + } + + return samplingRules; } /// @@ -119,47 +157,83 @@ public async Task GetSamplingRules() /// Instance of . public async Task GetSamplingTargets(List rules) { - GetSamplingTargetsRequest request = new GetSamplingTargetsRequest(); - IList newTargets = new List(); DateTime currentTime = TimeStamp.CurrentDateTime(); - List samplingStatisticsDocuments = GetSamplingStatisticsDocuments(rules, currentTime); - request.SamplingStatisticsDocuments = samplingStatisticsDocuments; - Task responseTask; + List samplingStatisticsDocumentModels = GetSamplingStatisticsDocuments(rules, currentTime); + var samplingStatisticsModel = new SamplingStatisticsModel(); + samplingStatisticsModel.SamplingStatisticsDocuments = samplingStatisticsDocumentModels; + + string requestContent = JsonMapper.ToJson(samplingStatisticsModel); // Marshall SamplingStatisticsDocument to json + + Task responseTask; lock (_xrayClientLock) { RefreshEndPoint(); - responseTask = _xrayClient.GetSamplingTargetsAsync(request); + responseTask = GetSamplingInfoAsync(_xrayConfig.ServiceURL + "/SamplingTargets", requestContent); } - var response = await responseTask; - foreach (var record in response.SamplingTargetDocuments) + var responseContent = await responseTask; + + var samplingTargetResponse = UnmarshallSamplingTargetResponse(responseContent); + + var targetList = ConvertTargetList(samplingTargetResponse.SamplingTargetDocuments); + + GetSamplingTargetsResponse result = new GetSamplingTargetsResponse(targetList); + result.RuleFreshness = new TimeStamp(ConvertDoubleToDateTime(samplingTargetResponse.LastRuleModification)); + return result; + } + + private List ConvertTargetList(List targetModels) + { + List result = new List(); + foreach (var targetModel in targetModels) { - Target t = new Target(record.RuleName, record.FixedRate, record.ReservoirQuota, record.ReservoirQuotaTTL, record.Interval); - newTargets.Add(t); + Target t = new Target + ( + targetModel.RuleName, + targetModel.FixedRate.GetValueOrDefault(), + targetModel.ReservoirQuota.GetValueOrDefault(), + ConvertDoubleToDateTime(targetModel.ReservoirQuotaTTL), + targetModel.Interval.GetValueOrDefault() + ); + result.Add(t); } - - GetSamplingTargetsResponse result = new GetSamplingTargetsResponse(newTargets); - result.RuleFreshness = new TimeStamp(response.LastRuleModification); return result; } - private List GetSamplingStatisticsDocuments(List rules, DateTime currentTime) + private SamplingTargetResponseModel UnmarshallSamplingTargetResponse(string responseContent) { - List samplingStatisticsDocuments = new List(); + var samplingTargetResponse = JsonMapper.ToObject(responseContent); + + return samplingTargetResponse; + } + + private List GetSamplingStatisticsDocuments(List rules, DateTime currentTime) + { + List samplingStatisticsDocumentModels = new List(); foreach (var rule in rules) { Statistics statistics = rule.SnapShotStatistics(); - SamplingStatisticsDocument doc = new SamplingStatisticsDocument(); - doc.ClientID = ClientID; - doc.RuleName = rule.RuleName; - doc.RequestCount = statistics.RequestCount; - doc.SampledCount = statistics.SampledCount; - doc.BorrowCount = statistics.BorrowCount; - doc.Timestamp = currentTime; - samplingStatisticsDocuments.Add(doc); + SamplingStatisticsDocumentModel item = new SamplingStatisticsDocumentModel(); + item.ClientID = ClientID; + item.RuleName = rule.RuleName; + item.RequestCount = statistics.RequestCount; + item.SampledCount = statistics.SampledCount; + item.BorrowCount = statistics.BorrowCount; + item.Timestamp = ConvertDateTimeToDouble(currentTime); + samplingStatisticsDocumentModels.Add(item); } - return samplingStatisticsDocuments; + return samplingStatisticsDocumentModels; + } + + private double ConvertDateTimeToDouble(DateTime currentTime) + { + var current = new TimeSpan(currentTime.ToUniversalTime().Ticks - EpochStart.Ticks); + return Math.Round(current.TotalMilliseconds, 0) / 1000.0; + } + + private DateTime ConvertDoubleToDateTime(double? seconds) + { + return seconds == null ? default(DateTime) : EpochStart.AddSeconds(seconds.GetValueOrDefault()); } } } - diff --git a/sdk/src/Core/Sampling/XRayConfig.cs b/sdk/src/Core/Sampling/XRayConfig.cs new file mode 100644 index 00000000..35795dde --- /dev/null +++ b/sdk/src/Core/Sampling/XRayConfig.cs @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +namespace Amazon.XRay.Recorder.Core.Sampling +{ + /// + /// Class for xray configuration for getting sampling rules and sampling targets. + /// + public class XRayConfig + { + /// + /// Gets and sets of the ServiceURL property. + /// + public string ServiceURL { get; set; } + + /// + /// Default constructor. + /// + public XRayConfig() + { + } + } +} diff --git a/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj b/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj index 70129ece..c2e116cc 100644 --- a/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj +++ b/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj @@ -40,7 +40,6 @@ - diff --git a/sdk/test/UnitTests/JsonMapperTest.cs b/sdk/test/UnitTests/JsonMapperTest.cs new file mode 100644 index 00000000..65c16807 --- /dev/null +++ b/sdk/test/UnitTests/JsonMapperTest.cs @@ -0,0 +1,275 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +using Amazon.XRay.Recorder.Core.Sampling.Model; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using ThirdParty.LitJson; + +namespace Amazon.XRay.Recorder.UnitTests +{ + [TestClass] + public class JsonMapperTest + { + [TestMethod] + public void TestMarshallSamplingStatisticsDocuments() + { + var samplingStatisticsModel = new SamplingStatisticsModel(); + var samplingStatisticsDocumentModel = new SamplingStatisticsDocumentModel + { + ClientID = "07492221d7fd13a86e750de2", + RuleName = "Test", + RequestCount = 108, + SampledCount = 4, + BorrowCount = 6, + Timestamp = 1604297926.362 + }; + + samplingStatisticsModel.SamplingStatisticsDocuments.Add(samplingStatisticsDocumentModel); + + var expected = "{\"SamplingStatisticsDocuments\":[{\"ClientID\":\"07492221d7fd13a86e750de2\",\"RuleName\":\"Test\",\"RequestCount\":108,\"SampledCount\":4,\"BorrowCount\":6,\"Timestamp\":1604297926.362}]}"; + var actual = JsonMapper.ToJson(samplingStatisticsModel); + + Assert.AreEqual(expected, actual); + } + + [TestMethod] + public void TestMarshallSamplingStatisticsDocumentsWithEmptyValues() + { + var samplingStatisticsModel = new SamplingStatisticsModel(); + var samplingStatisticsDocumentModel = new SamplingStatisticsDocumentModel(); + + samplingStatisticsModel.SamplingStatisticsDocuments.Add(samplingStatisticsDocumentModel); + + var expected = "{\"SamplingStatisticsDocuments\":[{\"ClientID\":null,\"RuleName\":null,\"RequestCount\":null,\"SampledCount\":null,\"BorrowCount\":null,\"Timestamp\":null}]}"; + var actual = JsonMapper.ToJson(samplingStatisticsModel); + + Assert.AreEqual(expected, actual); + } + + [TestMethod] + public void TestMarshallSamplingStatisticsDocumentsWithEmptyItems() + { + var samplingStatisticsModel = new SamplingStatisticsModel(); + + var expected = "{\"SamplingStatisticsDocuments\":[]}"; + var actual = JsonMapper.ToJson(samplingStatisticsModel); + + Assert.AreEqual(expected, actual); + } + + [TestMethod] + public void TestUnmarshallSamplingRuleResponse() + { + var samplingRuleResponseJson = "{\"NextToken\":null,\"SamplingRuleRecords\":[{\"CreatedAt\":0.0,\"ModifiedAt\":1.602621583E9,\"SamplingRule\":{\"Attributes\":{},\"FixedRate\":0.05,\"HTTPMethod\":\"*\",\"Host\":\"*\",\"Priority\":10000,\"ReservoirSize\":1,\"ResourceARN\":\"*\",\"RuleARN\":\"arn:aws:xray:us-east-1:1234567:sampling-rule/Default\",\"RuleName\":\"Default\",\"ServiceName\":\"*\",\"ServiceType\":\"*\",\"URLPath\":\"*\",\"Version\":1}}]}"; + + var samplingRuleResponseModel = JsonMapper.ToObject(samplingRuleResponseJson); + + Assert.IsNull(samplingRuleResponseModel.NextToken); + Assert.IsTrue(samplingRuleResponseModel.SamplingRuleRecords.Count > 0); + + foreach (var samplingRuleRecord in samplingRuleResponseModel.SamplingRuleRecords) + { + Assert.AreEqual(0.0, samplingRuleRecord.CreatedAt.GetValueOrDefault()); + Assert.AreEqual(1.602621583E9, samplingRuleRecord.ModifiedAt.GetValueOrDefault()); + Assert.IsNotNull(samplingRuleRecord.SamplingRule); + Assert.IsTrue(samplingRuleRecord.SamplingRule.Attributes.Count == 0); + Assert.AreEqual(0.05, samplingRuleRecord.SamplingRule.FixedRate.GetValueOrDefault()); + Assert.AreEqual("*", samplingRuleRecord.SamplingRule.HTTPMethod); + Assert.AreEqual("*", samplingRuleRecord.SamplingRule.Host); + Assert.AreEqual(10000, samplingRuleRecord.SamplingRule.Priority.GetValueOrDefault()); + Assert.AreEqual(1, samplingRuleRecord.SamplingRule.ReservoirSize.GetValueOrDefault()); + Assert.AreEqual("*", samplingRuleRecord.SamplingRule.ResourceARN); + Assert.AreEqual("arn:aws:xray:us-east-1:1234567:sampling-rule/Default", samplingRuleRecord.SamplingRule.RuleARN); + Assert.AreEqual("Default", samplingRuleRecord.SamplingRule.RuleName); + Assert.AreEqual("*", samplingRuleRecord.SamplingRule.ServiceName); + Assert.AreEqual("*", samplingRuleRecord.SamplingRule.ServiceType); + Assert.AreEqual("*", samplingRuleRecord.SamplingRule.URLPath); + Assert.AreEqual(1, samplingRuleRecord.SamplingRule.Version.GetValueOrDefault()); + } + } + + [TestMethod] + public void TestUnmarshallSamplingRuleResponseWithEmptyValues() + { + var samplingRuleResponseJson = "{\"NextToken\":null,\"SamplingRuleRecords\":[{\"CreatedAt\":null,\"ModifiedAt\":null,\"SamplingRule\":{\"Attributes\":{},\"FixedRate\":null,\"HTTPMethod\":null,\"Host\":null,\"Priority\":null,\"ReservoirSize\":null,\"ResourceARN\":null,\"RuleARN\":null,\"RuleName\":null,\"ServiceName\":null,\"ServiceType\":null,\"URLPath\":null,\"Version\":null}}]}"; + + var samplingRuleResponseModel = JsonMapper.ToObject(samplingRuleResponseJson); + + Assert.IsNull(samplingRuleResponseModel.NextToken); + Assert.IsTrue(samplingRuleResponseModel.SamplingRuleRecords.Count > 0); + + foreach (var samplingRuleRecord in samplingRuleResponseModel.SamplingRuleRecords) + { + Assert.AreEqual(0, samplingRuleRecord.CreatedAt.GetValueOrDefault()); + Assert.AreEqual(0, samplingRuleRecord.ModifiedAt.GetValueOrDefault()); + Assert.IsNotNull(samplingRuleRecord.SamplingRule); + Assert.IsTrue(samplingRuleRecord.SamplingRule.Attributes.Count == 0); + Assert.AreEqual(0, samplingRuleRecord.SamplingRule.FixedRate.GetValueOrDefault()); + Assert.AreEqual(null, samplingRuleRecord.SamplingRule.HTTPMethod); + Assert.AreEqual(null, samplingRuleRecord.SamplingRule.Host); + Assert.AreEqual(0, samplingRuleRecord.SamplingRule.Priority.GetValueOrDefault()); + Assert.AreEqual(0, samplingRuleRecord.SamplingRule.ReservoirSize.GetValueOrDefault()); + Assert.AreEqual(null, samplingRuleRecord.SamplingRule.ResourceARN); + Assert.AreEqual(null, samplingRuleRecord.SamplingRule.RuleARN); + Assert.AreEqual(null, samplingRuleRecord.SamplingRule.RuleName); + Assert.AreEqual(null, samplingRuleRecord.SamplingRule.ServiceName); + Assert.AreEqual(null, samplingRuleRecord.SamplingRule.ServiceType); + Assert.AreEqual(null, samplingRuleRecord.SamplingRule.URLPath); + Assert.AreEqual(0, samplingRuleRecord.SamplingRule.Version.GetValueOrDefault()); + } + } + + [TestMethod] + public void TestUnmarshallSamplingRuleResponseWithInvalidFormat() + { + var samplingRuleResponseJson = "{\"a\":null,\"b\":[{\"c\":0.0,\"d\":1.602621583E9,\"e\":{\"f\":{},\"g\":0.05,\"h\":\"*\",\"i\":\"*\",\"j\":10000,\"k\":1,\"l\":\"*\",\"m\":\"arn:aws:xray:us-east-1:1234567:sampling-rule/Default\",\"n\":\"Default\",\"o\":\"*\",\"p\":\"*\",\"q\":\"*\",\"r\":1}}]}"; + + var samplingRuleResponseModel = JsonMapper.ToObject(samplingRuleResponseJson); + + Assert.IsNull(samplingRuleResponseModel.NextToken); + Assert.IsTrue(samplingRuleResponseModel.SamplingRuleRecords.Count == 0); + } + + [TestMethod] + public void TestUnmarshallSamplingRuleResponseWithNull() + { + string samplingRuleResponseJson = ""; + + var samplingRuleResponseModel = JsonMapper.ToObject(samplingRuleResponseJson); + + Assert.IsNull(samplingRuleResponseModel); + } + + [TestMethod] + public void TestUnmarshallSamplingTargetResponse() + { + string samplingTargetResponseJson = "{\"LastRuleModification\":1.603923208E9,\"SamplingTargetDocuments\":[{\"FixedRate\":0.05,\"Interval\":2,\"ReservoirQuota\":1,\"ReservoirQuotaTTL\":1.5,\"RuleName\":\"Test\"}],\"UnprocessedStatistics\":[{\"ErrorCode\":\"400\",\"Message\":\"Unknown rule\",\"RuleName\":\"Fault\"}]}"; + + var samplingTargetResponseModel = JsonMapper.ToObject(samplingTargetResponseJson); + + Assert.AreEqual(1.603923208E9, samplingTargetResponseModel.LastRuleModification); + Assert.IsTrue(samplingTargetResponseModel.SamplingTargetDocuments.Count > 0); + Assert.IsTrue(samplingTargetResponseModel.UnprocessedStatistics.Count > 0); + + foreach (var target in samplingTargetResponseModel.SamplingTargetDocuments) + { + Assert.AreEqual(0.05, target.FixedRate.GetValueOrDefault()); + Assert.AreEqual(2, target.Interval.GetValueOrDefault()); + Assert.AreEqual(1, target.ReservoirQuota.GetValueOrDefault()); + Assert.AreEqual(1.5, target.ReservoirQuotaTTL.GetValueOrDefault()); + Assert.AreEqual("Test", target.RuleName); + } + + foreach (var unprocessed in samplingTargetResponseModel.UnprocessedStatistics) + { + Assert.AreEqual("400", unprocessed.ErrorCode); + Assert.AreEqual("Unknown rule", unprocessed.Message); + Assert.AreEqual("Fault", unprocessed.RuleName); + } + } + + [TestMethod] + public void TestUnmarshallSamplingTargetResponseWithoutSamplingTargetDocuments() + { + string samplingTargetResponseJson = "{\"LastRuleModification\":1.603923208E9,\"SamplingTargetDocuments\":[],\"UnprocessedStatistics\":[{\"ErrorCode\":\"400\",\"Message\":\"Unknown rule\",\"RuleName\":\"Fault\"}]}"; + + var samplingTargetResponseModel = JsonMapper.ToObject(samplingTargetResponseJson); + + Assert.AreEqual(1.603923208E9, samplingTargetResponseModel.LastRuleModification); + Assert.IsTrue(samplingTargetResponseModel.SamplingTargetDocuments.Count == 0); + Assert.IsTrue(samplingTargetResponseModel.UnprocessedStatistics.Count > 0); + + foreach (var unprocessed in samplingTargetResponseModel.UnprocessedStatistics) + { + Assert.AreEqual("400", unprocessed.ErrorCode); + Assert.AreEqual("Unknown rule", unprocessed.Message); + Assert.AreEqual("Fault", unprocessed.RuleName); + } + } + + [TestMethod] + public void TestUnmarshallSamplingTargetResponseWithoutUnprocessedStatistics() + { + string samplingTargetResponseJson = "{\"LastRuleModification\":1.603923208E9,\"SamplingTargetDocuments\":[{\"FixedRate\":0.05,\"Interval\":2,\"ReservoirQuota\":1,\"ReservoirQuotaTTL\":1.5,\"RuleName\":\"Test\"}],\"UnprocessedStatistics\":[]}"; + + var samplingTargetResponseModel = JsonMapper.ToObject(samplingTargetResponseJson); + + Assert.AreEqual(1.603923208E9, samplingTargetResponseModel.LastRuleModification); + Assert.IsTrue(samplingTargetResponseModel.SamplingTargetDocuments.Count > 0); + Assert.IsTrue(samplingTargetResponseModel.UnprocessedStatistics.Count == 0); + + foreach (var target in samplingTargetResponseModel.SamplingTargetDocuments) + { + Assert.AreEqual(0.05, target.FixedRate.GetValueOrDefault()); + Assert.AreEqual(2, target.Interval.GetValueOrDefault()); + Assert.AreEqual(1, target.ReservoirQuota.GetValueOrDefault()); + Assert.AreEqual(1.5, target.ReservoirQuotaTTL.GetValueOrDefault()); + Assert.AreEqual("Test", target.RuleName); + } + } + + [TestMethod] + public void TestUnmarshallSamplingTargetResponseWithEmptyValues() + { + string samplingTargetResponseJson = "{\"LastRuleModification\":null,\"SamplingTargetDocuments\":[{\"FixedRate\":null,\"Interval\":null,\"ReservoirQuota\":null,\"ReservoirQuotaTTL\":null,\"RuleName\":null}],\"UnprocessedStatistics\":[{\"ErrorCode\":null,\"Message\":null,\"RuleName\":null}]}"; + + var samplingTargetResponseModel = JsonMapper.ToObject(samplingTargetResponseJson); + + Assert.AreEqual(0, samplingTargetResponseModel.LastRuleModification.GetValueOrDefault()); + Assert.IsTrue(samplingTargetResponseModel.SamplingTargetDocuments.Count > 0); + Assert.IsTrue(samplingTargetResponseModel.UnprocessedStatistics.Count > 0); + + foreach (var target in samplingTargetResponseModel.SamplingTargetDocuments) + { + Assert.AreEqual(0, target.FixedRate.GetValueOrDefault()); + Assert.AreEqual(0, target.Interval.GetValueOrDefault()); + Assert.AreEqual(0, target.ReservoirQuota.GetValueOrDefault()); + Assert.AreEqual(0, target.ReservoirQuotaTTL.GetValueOrDefault()); + Assert.IsNull(target.RuleName); + } + + foreach (var unprocessed in samplingTargetResponseModel.UnprocessedStatistics) + { + Assert.IsNull(unprocessed.ErrorCode); + Assert.IsNull(unprocessed.Message); + Assert.IsNull(unprocessed.RuleName); + } + } + + [TestMethod] + public void TestUnmarshallSamplingTargetResponseWithInvalidFormat() + { + string samplingTargetResponseJson = "{\"a\":1.603923208E9,\"b\":[{\"c\":0.05,\"d\":2,\"e\":1,\"f\":1.5,\"g\":\"Test\"}],\"h\":[{\"i\":\"400\",\"j\":\"Unknown rule\",\"k\":\"Fault\"}]}"; + + var samplingTargetResponseModel = JsonMapper.ToObject(samplingTargetResponseJson); + + Assert.IsNull(samplingTargetResponseModel.LastRuleModification); + Assert.IsTrue(samplingTargetResponseModel.SamplingTargetDocuments.Count == 0); + Assert.IsTrue(samplingTargetResponseModel.UnprocessedStatistics.Count == 0); + } + + [TestMethod] + public void TestUnmarshallSamplingTargetResponseWithNull() + { + string samplingTargetResponseJson = ""; + + var samplingTargetResponseModel = JsonMapper.ToObject(samplingTargetResponseJson); + + Assert.IsNull(samplingTargetResponseModel); + } + } +} From a9833381ec203473e112779e662bb6b11f9f4be8 Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Thu, 3 Dec 2020 10:54:41 -0800 Subject: [PATCH 10/37] Adding limitation for EFCore with multiple DbCommandInterceptor (#164) * Adding limitation for EFCore with multiple DbCommandInterceptor * Adding doc ref for AsyncLocal --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d29ff8a6..66c037bc 100644 --- a/README.md +++ b/README.md @@ -395,6 +395,8 @@ For how to start with Entity Framework Core in an ASP.NET Core web app, please t * You need to install `AWSXRayRecorder.Handlers.EntityFramework` nuget package. This package adds extension methods to the `DbContextOptionsBuilder` to make it easy to register AWS X-Ray interceptor. * Not all database provider support Entity Framework Core 3.0 and above, please make sure that you are using the [Nuget package](https://docs.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli) with a compatible version (EF Core >= 3.0). +*Known Limitation (as of 12-03-2020):* If you're using another `DbCommandInterceptor` implementation along with the `AddXRayInterceptor` in the `DbContext`, it may not work as expected and you may see a "EntityNotAvailableException" from the XRay EFCore interceptor. This is due to [`AsyncLocal`](https://docs.microsoft.com/en-us/dotnet/api/system.threading.asynclocal-1?view=netcore-2.0) not being able to maintain context across the `ReaderExecutingAsync` and `ReaderExecutedAsync` methods. Ref [here](https://github.com/dotnet/efcore/issues/22766) for more details on the issue. + #### Setup In order to trace SQL query, you can register your `DbContext` with `AddXRayInterceptor()` accordingly in the `ConfigureServices` method in `startup.cs` file. From 8a9c600ee656a22b2a28bf873d2d069a69c8b9d9 Mon Sep 17 00:00:00 2001 From: Stephen D'Olier Date: Tue, 15 Dec 2020 09:09:47 +1100 Subject: [PATCH 11/37] Updated xraycontext to use a concurrent dictionary (#157) To avoid concurrent thread access to the dictionary causing an exception --- sdk/src/Core/AWSXRayRecorderImpl.cs | 8 ++++---- sdk/test/UnitTests/AWSXRayRecorderTests.cs | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/sdk/src/Core/AWSXRayRecorderImpl.cs b/sdk/src/Core/AWSXRayRecorderImpl.cs index a75b5c33..6ad0d6a1 100644 --- a/sdk/src/Core/AWSXRayRecorderImpl.cs +++ b/sdk/src/Core/AWSXRayRecorderImpl.cs @@ -15,6 +15,7 @@ // //----------------------------------------------------------------------------- using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; @@ -379,13 +380,12 @@ private void AddRuleName(Segment newSegment, SamplingResponse sampleResponse) IDictionary xrayContext; if (newSegment.Aws.TryGetValue("xray", out object value)) { - IDictionary tempXrayContext = (Dictionary) value; - xrayContext = new Dictionary(tempXrayContext); // deep copy for thread safety + xrayContext = (ConcurrentDictionary)value; xrayContext[ruleNameKey] = ruleName; } else { - xrayContext = new Dictionary(); + xrayContext = new ConcurrentDictionary(); xrayContext[ruleNameKey] = ruleName; } @@ -725,7 +725,7 @@ protected void PopulateContexts() RuntimeContext = new Dictionary(); // Prepare XRay section for runtime context - var xrayContext = new Dictionary(); + var xrayContext = new ConcurrentDictionary(); #if NET45 xrayContext["sdk"] = "X-Ray for .NET"; diff --git a/sdk/test/UnitTests/AWSXRayRecorderTests.cs b/sdk/test/UnitTests/AWSXRayRecorderTests.cs index c4c007d5..54871163 100644 --- a/sdk/test/UnitTests/AWSXRayRecorderTests.cs +++ b/sdk/test/UnitTests/AWSXRayRecorderTests.cs @@ -16,6 +16,7 @@ //----------------------------------------------------------------------------- using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Configuration; using System.Diagnostics; @@ -768,7 +769,7 @@ public void TestXrayContext() var segment = AWSXRayRecorder.Instance.TraceContext.GetEntity(); _recorder.EndSegment(); - IDictionary xray = (Dictionary)segment.Aws["xray"]; + IDictionary xray = (ConcurrentDictionary)segment.Aws["xray"]; var versionText = FileVersionInfo.GetVersionInfo(Assembly.GetAssembly(typeof(AWSXRayRecorderBuilder)).Location) .ProductVersion; From 412185fa732d41f1cfb727c8041a77babc4074b4 Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Tue, 29 Dec 2020 14:21:52 -0800 Subject: [PATCH 12/37] Enable tracing S3 id pairs and fix SNS naming issue. (#168) * Enable tracing S3 id pairs and fix SNS naming issue. * Changed AWSSDK.Core version * Changed parameter names and updated comments. * Set parameters as default --- sdk/src/Core/AWSXRayRecorder.Core.csproj | 2 +- .../AwsSdk/Internal/AWSXRaySDKUtils.cs | 17 +++++++ .../AwsSdk/Internal/XRayPipelineHandler.cs | 26 ++++++++--- sdk/test/UnitTests/AWSSDKHandlerTests.cs | 45 +++++++++++++++---- .../AWSXRayRecorder.UnitTests.csproj | 1 + sdk/test/UnitTests/Tools/CustomResponses.cs | 26 ++++++++--- 6 files changed, 95 insertions(+), 22 deletions(-) diff --git a/sdk/src/Core/AWSXRayRecorder.Core.csproj b/sdk/src/Core/AWSXRayRecorder.Core.csproj index 105d7ded..dc20b777 100644 --- a/sdk/src/Core/AWSXRayRecorder.Core.csproj +++ b/sdk/src/Core/AWSXRayRecorder.Core.csproj @@ -38,7 +38,7 @@ - + diff --git a/sdk/src/Handlers/AwsSdk/Internal/AWSXRaySDKUtils.cs b/sdk/src/Handlers/AwsSdk/Internal/AWSXRaySDKUtils.cs index b8d64d3e..13437eea 100644 --- a/sdk/src/Handlers/AwsSdk/Internal/AWSXRaySDKUtils.cs +++ b/sdk/src/Handlers/AwsSdk/Internal/AWSXRaySDKUtils.cs @@ -26,6 +26,13 @@ internal class AWSXRaySDKUtils { private static readonly String XRayServiceName = "XRay"; private static readonly ISet WhitelistedOperations = new HashSet { "GetSamplingRules", "GetSamplingTargets" }; + + // Collection to uniform service names across X-Ray SDKs. + private static readonly Dictionary FormattedServiceNames = new Dictionary() + { + { "SimpleNotificationService" , "SNS" }, + }; + internal static bool IsBlacklistedOperation(String serviceName, string operation) { if (string.Equals(serviceName, XRayServiceName) && WhitelistedOperations.Contains(operation)) @@ -34,5 +41,15 @@ internal static bool IsBlacklistedOperation(String serviceName, string operation } return false; } + + internal static string FormatServiceName(string serviceName) + { + if (FormattedServiceNames.TryGetValue(serviceName, out string formattedName)) + { + return formattedName; + } + + return serviceName; + } } } diff --git a/sdk/src/Handlers/AwsSdk/Internal/XRayPipelineHandler.cs b/sdk/src/Handlers/AwsSdk/Internal/XRayPipelineHandler.cs index 25c8b306..67fa9d30 100755 --- a/sdk/src/Handlers/AwsSdk/Internal/XRayPipelineHandler.cs +++ b/sdk/src/Handlers/AwsSdk/Internal/XRayPipelineHandler.cs @@ -44,9 +44,6 @@ public class XRayPipelineHandler : PipelineHandler private const string DefaultAwsWhitelistManifestResourceName = "Amazon.XRay.Recorder.Handlers.AwsSdk.DefaultAWSWhitelist.json"; private static readonly Logger _logger = Runtime.Internal.Util.Logger.GetLogger(typeof(AWSXRayRecorder)); private AWSXRayRecorder _recorder; - private const String S3RequestIdHeaderKey = "x-amz-request-id"; - private const String S3ExtendedRequestIdHeaderKey = "x-amz-id-2"; - private const String ExtendedRquestIdSegmentKey = "id_2"; /// /// Gets AWS service manifest of operation parameter whitelist. @@ -319,7 +316,8 @@ private void ProcessBeginRequest(IExecutionContext executionContext) _recorder.TraceContext.HandleEntityMissing(_recorder, e, "Cannot get entity while processing AWS SDK request"); } - _recorder.BeginSubsegment(RemoveAmazonPrefixFromServiceName(request.ServiceName)); + var serviceName = RemoveAmazonPrefixFromServiceName(request.ServiceName); + _recorder.BeginSubsegment(AWSXRaySDKUtils.FormatServiceName(serviceName)); _recorder.SetNamespace("aws"); entity = entity == null ? null : _recorder.GetEntity(); @@ -380,20 +378,27 @@ private void ProcessEndRequest(IExecutionContext executionContext) // s3 doesn't follow request header id convention else { - if (requestContext.Request.Headers.TryGetValue(S3RequestIdHeaderKey, out requestId)) + if (requestContext.Request.Headers.TryGetValue("x-amz-request-id", out requestId)) { subsegment.Aws["request_id"] = requestId; } - if (requestContext.Request.Headers.TryGetValue(S3ExtendedRequestIdHeaderKey, out requestId)) + if (requestContext.Request.Headers.TryGetValue("x-amz-id-2", out requestId)) { - subsegment.Aws[ExtendedRquestIdSegmentKey] = requestId; + subsegment.Aws["id_2"] = requestId; } } } else { subsegment.Aws["request_id"] = responseContext.Response.ResponseMetadata.RequestId; + + // try getting x-amz-id-2 if dealing with s3 request + if (responseContext.Response.ResponseMetadata.Metadata.TryGetValue("x-amz-id-2", out string extendedRequestId)) + { + subsegment.Aws["id_2"] = extendedRequestId; + } + AddResponseSpecificInformation(serviceName, operation, responseContext.Response, subsegment.Aws); } @@ -451,6 +456,13 @@ private void ProcessException(AmazonServiceException ex, Entity subsegment) _recorder.AddHttpInformation("response", responseAttributes); subsegment.Aws["request_id"] = ex.RequestId; + + // AmazonId2 property in AmazonS3Exception corresponds to the x-amz-id-2 Http header + var property = ex.GetType().GetProperty("AmazonId2"); + if (property != null) + { + subsegment.Aws["id_2"] = (string)property.GetValue(ex, null); + } } private void AddRequestSpecificInformation(string serviceName, string operation, AmazonWebServiceRequest request, IDictionary aws) diff --git a/sdk/test/UnitTests/AWSSDKHandlerTests.cs b/sdk/test/UnitTests/AWSSDKHandlerTests.cs index b95fd481..684a8267 100644 --- a/sdk/test/UnitTests/AWSSDKHandlerTests.cs +++ b/sdk/test/UnitTests/AWSSDKHandlerTests.cs @@ -26,6 +26,7 @@ using Amazon.Lambda.Model; using Amazon.Runtime; using Amazon.S3; +using Amazon.SimpleNotificationService; using Amazon.XRay.Recorder.Core; using Amazon.XRay.Recorder.Core.Internal.Utils; using Amazon.XRay.Recorder.Handlers.AwsSdk; @@ -80,7 +81,7 @@ public void TestContextMissingStrategyForAWSSDKHandler() AWSXRayRecorder.Instance.ContextMissingStrategy = Core.Strategies.ContextMissingStrategy.LOG_ERROR; AWSSDKHandler.RegisterXRayForAllServices(); var dynamo = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - CustomResponses.SetResponse(dynamo, null, null, true); + CustomResponses.SetResponse(dynamo); AWSXRayRecorder.Instance.BeginSegment("test dynamo", TraceId); var segment = AWSXRayRecorder.Instance.TraceContext.GetEntity(); @@ -101,7 +102,7 @@ public void TestS3SubsegmentNameIsCorrectForAWSSDKHandler() { AWSSDKHandler.RegisterXRay(); var s3 = new AmazonS3Client(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - CustomResponses.SetResponse(s3, null, null, true); + CustomResponses.SetResponse(s3, null, "TestAmazonId"); _recorder.BeginSegment("test s3", TraceId); #if NET45 @@ -115,6 +116,7 @@ public void TestS3SubsegmentNameIsCorrectForAWSSDKHandler() Assert.IsTrue(segment.Subsegments[0].Aws.ContainsKey("version_id")); Assert.AreEqual(segment.Subsegments[0].Aws["bucket_name"], "testBucket"); Assert.AreEqual(segment.Subsegments[0].Aws["operation"], "GetObject"); + Assert.AreEqual(segment.Subsegments[0].Aws["id_2"], "TestAmazonId"); } [TestMethod] @@ -126,7 +128,7 @@ public void TestDynamoDbClient() using (var client = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1)) { string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; - CustomResponses.SetResponse(client, null, requestId, true); + CustomResponses.SetResponse(client, requestId); _recorder.BeginSegment("test", TraceId); #if NET45 @@ -184,7 +186,7 @@ public void TestRequestResponseParameterAndDescriptorForAWSSDKHandler() { using (var client = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1)) { - CustomResponses.SetResponse(client, null, null, true); + CustomResponses.SetResponse(client); _recorder.BeginSegment("test", TraceId); var segment = AWSXRayRecorder.Instance.TraceContext.GetEntity(); @@ -255,7 +257,7 @@ await client.GetItemAsync( public void TestDynamoSubsegmentNameIsCorrectForAWSSDKHandler() { var dynamo = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - CustomResponses.SetResponse(dynamo, null, null, true); + CustomResponses.SetResponse(dynamo); _recorder.BeginSegment("test dynamo", TraceId); #if NET45 dynamo.ListTables(); @@ -272,7 +274,7 @@ public void TestDynamoSubsegmentNameIsCorrectForAWSSDKHandler() public void TestManifestFileNoLambda() //At this point, current manifest file doen't contain Lambda service. { var lambda = new AmazonLambdaClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - CustomResponses.SetResponse(lambda, null, null, true); + CustomResponses.SetResponse(lambda); _recorder.BeginSegment("lambda", TraceId); #if NET45 lambda.Invoke(new InvokeRequest @@ -296,7 +298,7 @@ public void TestLambdaInvokeSubsegmentContainsFunctionNameForAWSSDKHandler() String temp_path = $"JSONs{Path.DirectorySeparatorChar}AWSRequestInfoWithLambda.json"; //registering manifest file with Lambda AWSSDKHandler.RegisterXRayManifest(temp_path); var lambda = new AmazonLambdaClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - CustomResponses.SetResponse(lambda, null, null, true); + CustomResponses.SetResponse(lambda); _recorder.BeginSegment("lambda", TraceId); #if NET45 lambda.Invoke(new InvokeRequest @@ -325,7 +327,7 @@ public void TestRegisterXRayManifestWithStreamLambdaForAWSSDKHandler() AWSSDKHandler.RegisterXRayManifest(stream); } var lambda = new AmazonLambdaClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - CustomResponses.SetResponse(lambda, null, null, true); + CustomResponses.SetResponse(lambda); _recorder.BeginSegment("lambda", TraceId); #if NET45 lambda.Invoke(new InvokeRequest @@ -343,5 +345,32 @@ public void TestRegisterXRayManifestWithStreamLambdaForAWSSDKHandler() Assert.AreEqual("Invoke", segment.Subsegments[0].Aws["operation"]); } + + [TestMethod] + public void TestSNSSubsegment() + { + AWSSDKHandler.RegisterXRay(); + var sns = new AmazonSimpleNotificationServiceClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + CustomResponses.SetResponse(sns); + + _recorder.BeginSegment("test sns", TraceId); + + try + { + sns.ListTopicsAsync().Wait(); + } + catch + { + // will throw exception for using anonymous AWS credentials, but will not affect generating traces + } + + var segment = _recorder.TraceContext.GetEntity(); + _recorder.EndSegment(); + Assert.AreEqual(1, segment.Subsegments.Count); + Assert.AreEqual("SNS", segment.Subsegments[0].Name); // Name should be SNS instead of SimpleNotificationService + Assert.AreEqual("ListTopics", segment.Subsegments[0].Aws["operation"]); + Assert.AreEqual("us-east-1", segment.Subsegments[0].Aws["region"]); + Assert.AreEqual("aws", segment.Subsegments[0].Namespace); + } } } diff --git a/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj b/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj index c2e116cc..a46ce2e6 100644 --- a/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj +++ b/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj @@ -40,6 +40,7 @@ + diff --git a/sdk/test/UnitTests/Tools/CustomResponses.cs b/sdk/test/UnitTests/Tools/CustomResponses.cs index c88be0f9..e81f47af 100644 --- a/sdk/test/UnitTests/Tools/CustomResponses.cs +++ b/sdk/test/UnitTests/Tools/CustomResponses.cs @@ -31,9 +31,9 @@ public static class CustomResponses { #if NET45 public static void SetResponse( - AmazonServiceClient client, string content, string requestId, bool isOK) + AmazonServiceClient client, string requestId = null, string s3ExtendedRequestId = null, string content = null, bool isOK = true) { - var response = Create(content, requestId, isOK); + var response = Create(content, requestId, s3ExtendedRequestId, isOK); SetResponse(client, response); } @@ -54,7 +54,7 @@ public static void SetResponse( } private static Func Create( - string content, string requestId, bool isOK) + string content, string requestId, string s3ExtendedRequestId, bool isOK) { var status = isOK ? HttpStatusCode.OK : HttpStatusCode.NotFound; @@ -65,6 +65,13 @@ private static Func Create( { headers.Add(HeaderKeys.RequestIdHeader, requestId); } + + // https://aws.amazon.com/premiumsupport/knowledge-center/s3-request-id-values/ + if (!string.IsNullOrEmpty(s3ExtendedRequestId)) + { + headers.Add(HeaderKeys.XAmzId2Header, s3ExtendedRequestId); + } + var response = MockWebResponse.Create(status, headers, content); if (isOK) @@ -77,9 +84,9 @@ private static Func Create( } #else - public static void SetResponse(AmazonServiceClient client, string content, string requestId, bool isOK) + public static void SetResponse(AmazonServiceClient client, string requestId = null, string s3ExtendedRequestId = null, string content = null, bool isOK = true) { - var response = Create(content, requestId, isOK); + var response = Create(content, requestId, s3ExtendedRequestId, isOK); SetResponse(client, response); } @@ -98,7 +105,7 @@ public static void SetResponse(AmazonServiceClient client, Func Create( - string content, string requestId, bool isOK) + string content, string requestId, string s3ExtendedRequestId, bool isOK) { var status = isOK ? HttpStatusCode.OK : HttpStatusCode.NotFound; @@ -109,6 +116,13 @@ private static Func Create( { headers.Add(HeaderKeys.RequestIdHeader, requestId); } + + // https://aws.amazon.com/premiumsupport/knowledge-center/s3-request-id-values/ + if (!string.IsNullOrEmpty(s3ExtendedRequestId)) + { + headers.Add(HeaderKeys.XAmzId2Header, s3ExtendedRequestId); + } + var response = MockWebResponse.Create(status, headers, content); if (isOK) From ff3648df79f485479a63c0cfe6b13c0761feaba9 Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Fri, 15 Jan 2021 13:50:53 -0800 Subject: [PATCH 13/37] Fixed appvoyer building configuration issue. (#173) --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 77a25320..21250b5b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ before_build: build_script: # output will be in ./src/bin/debug/netcoreapp1.1/publish - cmd: dotnet restore sdk/AWSXRayRecorder.sln - - cmd: dotnet build sdk/AWSXRayRecorder.sln /p:SignAssembly=false + - cmd: dotnet build sdk/AWSXRayRecorder.sln clone_depth: 1 test_script: - cmd : dotnet test sdk/test/UnitTests From 2a1891a6b051e20e7188861a6c799feb11f20d7a Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Wed, 27 Jan 2021 13:26:52 -0800 Subject: [PATCH 14/37] Add tracing support for EntityFramework 6 (.NET Framework) (#171) * Added support for EntityFramework 6 for .NET framework. --- README.md | 67 ++++++- .../AWSXRayEntityFramework6.cs | 38 ++++ .../AWSXRayInterceptorExtensions.cs | 2 +- ...ayRecorder.Handlers.EntityFramework.csproj | 14 +- .../Handlers/EntityFramework/EFInterceptor.cs | 141 ++----------- .../EntityFramework/EFInterceptor.net45.cs | 113 +++++++++++ sdk/src/Handlers/EntityFramework/EFUtil.cs | 186 +++++++++++++----- .../Properties/AssemblyInfo.cs | 9 + .../AWSXRayRecorder.UnitTests.csproj | 10 +- sdk/test/UnitTests/EF6Tests.cs | 186 ++++++++++++++++++ sdk/test/UnitTests/EFUtilTests.cs | 28 +++ sdk/test/UnitTests/Tools/TestEFContext.cs | 19 +- 12 files changed, 620 insertions(+), 193 deletions(-) create mode 100644 sdk/src/Handlers/EntityFramework/AWSXRayEntityFramework6.cs create mode 100644 sdk/src/Handlers/EntityFramework/EFInterceptor.net45.cs create mode 100644 sdk/src/Handlers/EntityFramework/Properties/AssemblyInfo.cs create mode 100644 sdk/test/UnitTests/EF6Tests.cs diff --git a/README.md b/README.md index 66c037bc..01c7d389 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Following API reference documentation provides guidance for using the SDK and mo 4. [Trace AWS SDK request](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-aws-sdk-request-net-and-net-core--nuget) 5. [Trace out-going HTTP requests](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-out-going-http-requests-net-and-net-core--nuget) 6. [Trace Query to SQL Server](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-query-to-sql-server-net-and-net-core--nuget) -7. [Trace SQL Query through Entity Framework Core 3.0 and above](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-sql-query-through-entity-framework-core-30-and-above-net-core--nuget) +7. [Trace SQL Query through Entity Framework](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-sql-query-through-entity-framework-net-and-net-core--nuget) 8. [Multithreaded Execution](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#multithreaded-execution-net-and-net-core--nuget) 9. [Trace custom methods ](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#trace-custom-methods-net-and-net-core) 10. [Creating custom Segment/Subsegment](https://github.com/aws/aws-xray-sdk-dotnet/tree/master#creating-custom-segmentsubsegment-net-and-net-core) @@ -384,7 +384,11 @@ using (var command = new TraceableSqlCommand("SELECT * FROM products", connectio 2. Parameterized values will appear in their tokenized form and will not be expanded. 3. The value of `collectSqlQueries` in the `TraceableSqlCommand` instance overrides the value set in the global configuration using the `CollectSqlQueries` property. -### Trace SQL Query through Entity Framework Core 3.0 and above (.NET Core) : [Nuget](https://www.nuget.org/packages/AWSXRayRecorder.Handlers.EntityFramework/) +### Trace SQL Query through Entity Framework (.NET and .NET Core) : [Nuget](https://www.nuget.org/packages/AWSXRayRecorder.Handlers.EntityFramework/) + +#### Setup + +##### .NET Core AWS XRay SDK for .NET Core provides interceptor for tracing SQL query through Entity Framework Core (>=3.0). @@ -397,8 +401,6 @@ For how to start with Entity Framework Core in an ASP.NET Core web app, please t *Known Limitation (as of 12-03-2020):* If you're using another `DbCommandInterceptor` implementation along with the `AddXRayInterceptor` in the `DbContext`, it may not work as expected and you may see a "EntityNotAvailableException" from the XRay EFCore interceptor. This is due to [`AsyncLocal`](https://docs.microsoft.com/en-us/dotnet/api/system.threading.asynclocal-1?view=netcore-2.0) not being able to maintain context across the `ReaderExecutingAsync` and `ReaderExecutedAsync` methods. Ref [here](https://github.com/dotnet/efcore/issues/22766) for more details on the issue. -#### Setup - In order to trace SQL query, you can register your `DbContext` with `AddXRayInterceptor()` accordingly in the `ConfigureServices` method in `startup.cs` file. For instance, when dealing with MySql server using Nuget: [Pomelo.EntityFrameworkCore.MySql](https://www.nuget.org/packages/Pomelo.EntityFrameworkCore.MySql) (V 3.1.1). @@ -426,10 +428,45 @@ public class your_DbContext : DbContext The connection string can be either hard coded or configured from `appsettings.json` file. +##### .NET + +AWS XRay SDK for .NET provides interceptor for tracing SQL query through Entity Framework 6 (>= 6.2.0). + +For how to start with Entity Framework 6 in an ASP.NET web app, please take reference to [link](https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application). + +For instrumentation, you will need to install `AWSXRayRecorder.Handlers.EntityFramework` nuget package and call `AWSXRayEntityFramework6.AddXRayInterceptor()` in your code. Make sure to call it **only once** to avoid duplicate tracing. + +For instance, you can call `AddXRayInterceptor()` in the `Application_Start` method of **Global.asax** file. + +``` +using Amazon.XRay.Recorder.Handlers.EntityFramework; + +protected void Application_Start() +{ + AWSXRayEntityFramework6.AddXRayInterceptor(); +} +``` + +Or you can call it in the `DbConfiguration` class if there is one in your application to configure execution policy. + +``` +using Amazon.XRay.Recorder.Handlers.EntityFramework; + +public class YourDbConfiguration : DbConfiguration +{ + public YourDbConfiguration() + { + AWSXRayEntityFramework6.AddXRayInterceptor(); + } +} +``` + #### Capture SQL Query text in the traced SQL calls to SQL Server You can also opt in to capture the `DbCommand.CommandText` as part of the subsegment created for your SQL query. The collected `DbCommand.CommandText` will appear as `sanitized_query` in the subsegment JSON. By default, this feature is disabled due to security reasons. +##### .NET Core + If you want to enable this feature, it can be done in two ways. First, by setting the `CollectSqlQueries` to **true** in the `appsettings.json` file as follows: ```json @@ -440,7 +477,7 @@ If you want to enable this feature, it can be done in two ways. First, by settin } ``` -Secondly, you can set the `collectSqlQueries` parameter in the `AddXRayInterceptor()` as **true** to collect the SQL query text. If you set this parameter as **false**, it will disable the `collectSqlQueries` feature for this `AddXRayInterceptor()`. +Secondly, you can set the `collectSqlQueries` parameter in the `AddXRayInterceptor()` as **true** to collect the SQL query text. If you set this parameter as **false**, it will disable the `collectSqlQueries` feature for this `AddXRayInterceptor()`. Opting in `AddXRayInterceptor()` has the highest execution priority, which will override the configuration item in `appsettings.json` mentioned above. ```csharp using Microsoft.EntityFrameworkCore; @@ -463,6 +500,26 @@ public class your_DbContext : DbContext } ``` +##### .NET + +You can enable tracing SQL query text for EF 6 interceptor in the `Web.config` file. + +```xml + + + + + +``` + +You can also pass **true** to `AddXRayInterceptor()` to collect SQL query text, otherwise pass **false** to disable. Opting in `AddXRayInterceptor()` has the highest execution priority, which will override the configuration item in `Web.config` mentioned above. + +``` +using Amazon.XRay.Recorder.Handlers.EntityFramework; + +AWSXRayEntityFramework6.AddXRayInterceptor(true); +``` + ### Multithreaded Execution (.NET and .NET Core) : [Nuget](https://www.nuget.org/packages/AWSXRayRecorder.Core/) In multithreaded execution, X-Ray context from current to its child thread is automatically set. diff --git a/sdk/src/Handlers/EntityFramework/AWSXRayEntityFramework6.cs b/sdk/src/Handlers/EntityFramework/AWSXRayEntityFramework6.cs new file mode 100644 index 00000000..c17fb06c --- /dev/null +++ b/sdk/src/Handlers/EntityFramework/AWSXRayEntityFramework6.cs @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +using System.Data.Entity.Infrastructure.Interception; + +namespace Amazon.XRay.Recorder.Handlers.EntityFramework +{ + /// + /// Class for to add . + /// User can pass collectSqlQueries to AddXRayInterceptor() to decide if sanitized_query should be included in the trace + /// context or not. + /// + public static class AWSXRayEntityFramework6 + { + /// + /// Enable tracing SQL queries through EntityFramework 6 for .NET framework by calling AWSXRayEntityFramework6.AddXRayInterceptor() to add into to register X-Ray tracing interceptor. + /// + /// Set this parameter to true to capture sql query text. The value set here overrides the value of CollectSqlQueries in Web.config if present. The default value of this parameter is null. + public static void AddXRayInterceptor(bool? collectSqlQueries = null) + { + DbInterception.Add(new EFInterceptor(collectSqlQueries)); + } + } +} diff --git a/sdk/src/Handlers/EntityFramework/AWSXRayInterceptorExtensions.cs b/sdk/src/Handlers/EntityFramework/AWSXRayInterceptorExtensions.cs index 83084c45..c9919ea9 100644 --- a/sdk/src/Handlers/EntityFramework/AWSXRayInterceptorExtensions.cs +++ b/sdk/src/Handlers/EntityFramework/AWSXRayInterceptorExtensions.cs @@ -30,7 +30,7 @@ public static class AWSXRayInterceptorExtensions /// Add to . /// /// Instance of . - /// + /// Set this parameter to true to capture sql query text. The value set here overrides the value of CollectSqlQueries in appsettings.json if present. The default value of this parameter is null. /// Instance of . public static DbContextOptionsBuilder AddXRayInterceptor(this DbContextOptionsBuilder dbContextOptionsBuilder, bool? collectSqlQueries = null) { diff --git a/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj b/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj index baaa9804..14865753 100644 --- a/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj +++ b/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj @@ -1,7 +1,7 @@ - netstandard2.0 + net45;netstandard2.0 Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -11,7 +11,7 @@ AWSXRayRecorder.Handlers.EntityFramework Amazon.XRay.Recorder.Handlers.EntityFramework Amazon Web Services - This package contains libraries to trace SQL queries through Entity Framework Core. + This package contains libraries to trace SQL queries through Entity Framework. http://aws.amazon.com/apache2.0/ https://aws.amazon.com/documentation/xray/ https://github.com/aws/aws-xray-sdk-dotnet @@ -30,8 +30,16 @@ 1701;1702;1591; - + + + + + + + + + diff --git a/sdk/src/Handlers/EntityFramework/EFInterceptor.cs b/sdk/src/Handlers/EntityFramework/EFInterceptor.cs index 8b632ca4..071d7e8d 100644 --- a/sdk/src/Handlers/EntityFramework/EFInterceptor.cs +++ b/sdk/src/Handlers/EntityFramework/EFInterceptor.cs @@ -17,9 +17,6 @@ using System.Data.Common; using Microsoft.EntityFrameworkCore.Diagnostics; -using Amazon.XRay.Recorder.Core; -using Amazon.XRay.Recorder.Core.Internal.Entities; -using Amazon.XRay.Recorder.Core.Exceptions; using System.Threading; using System.Threading.Tasks; @@ -27,22 +24,10 @@ namespace Amazon.XRay.Recorder.Handlers.EntityFramework { public class EFInterceptor : DbCommandInterceptor { - private readonly AWSXRayRecorder _recorder; private readonly bool? _collectSqlQueriesOverride; - public EFInterceptor() : this(AWSXRayRecorder.Instance) + public EFInterceptor(bool? collectSqlQueries = null) : base() { - - } - - public EFInterceptor(bool? collectSqlQueries = null) : this(AWSXRayRecorder.Instance, collectSqlQueries) - { - - } - - public EFInterceptor(AWSXRayRecorder recorder, bool? collectSqlQueries = null) : base() - { - _recorder = recorder; _collectSqlQueriesOverride = collectSqlQueries; } @@ -55,7 +40,7 @@ public EFInterceptor(AWSXRayRecorder recorder, bool? collectSqlQueries = null) : /// Result from . public override InterceptionResult ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result) { - ProcessBeginCommand(eventData); + EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.ReaderExecuting(command, eventData, result); } @@ -68,7 +53,7 @@ public override InterceptionResult ReaderExecuting(DbCommand comma /// Instance of . public override DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventData, DbDataReader result) { - ProcessEndCommand(); + EFUtil.ProcessEndCommand(); return base.ReaderExecuted(command, eventData, result); } @@ -82,7 +67,7 @@ public override DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEv /// Task representing the async operation. public override Task> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) { - ProcessBeginCommand(eventData); + EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.ReaderExecutingAsync(command, eventData, result, cancellationToken); } @@ -96,7 +81,7 @@ public override Task> ReaderExecutingAsync(DbCo /// Task representing the async operation. public override Task ReaderExecutedAsync(DbCommand command, CommandExecutedEventData eventData, DbDataReader result, CancellationToken cancellationToken = default) { - ProcessEndCommand(); + EFUtil.ProcessEndCommand(); return base.ReaderExecutedAsync(command, eventData, result, cancellationToken); } @@ -107,7 +92,7 @@ public override Task ReaderExecutedAsync(DbCommand command, Comman /// Instance of . public override void CommandFailed(DbCommand command, CommandErrorEventData eventData) { - ProcessCommandError(eventData); + EFUtil.ProcessCommandError(eventData.Exception); base.CommandFailed(command, eventData); } @@ -120,7 +105,7 @@ public override void CommandFailed(DbCommand command, CommandErrorEventData even /// Task representing the async operation. public override Task CommandFailedAsync(DbCommand command, CommandErrorEventData eventData, CancellationToken cancellationToken = default) { - ProcessCommandError(eventData); + EFUtil.ProcessCommandError(eventData.Exception); return base.CommandFailedAsync(command, eventData, cancellationToken); } @@ -133,7 +118,7 @@ public override Task CommandFailedAsync(DbCommand command, CommandErrorEventData /// Task representing the operation. public override InterceptionResult NonQueryExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result) { - ProcessBeginCommand(eventData); + EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.NonQueryExecuting(command, eventData, result); } @@ -147,7 +132,7 @@ public override InterceptionResult NonQueryExecuting(DbCommand command, Com /// Task representing the async operation. public override Task> NonQueryExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) { - ProcessBeginCommand(eventData); + EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.NonQueryExecutingAsync(command, eventData, result, cancellationToken); } @@ -160,7 +145,7 @@ public override Task> NonQueryExecutingAsync(DbCommand c /// Result as integer. public override int NonQueryExecuted(DbCommand command, CommandExecutedEventData eventData, int result) { - ProcessEndCommand(); + EFUtil.ProcessEndCommand(); return base.NonQueryExecuted(command, eventData, result); } @@ -174,7 +159,7 @@ public override int NonQueryExecuted(DbCommand command, CommandExecutedEventData /// Task representing the async operation. public override Task NonQueryExecutedAsync(DbCommand command, CommandExecutedEventData eventData, int result, CancellationToken cancellationToken = default) { - ProcessEndCommand(); + EFUtil.ProcessEndCommand(); return base.NonQueryExecutedAsync(command, eventData, result, cancellationToken); } @@ -187,7 +172,7 @@ public override Task NonQueryExecutedAsync(DbCommand command, CommandExecut /// Result from . public override InterceptionResult ScalarExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result) { - ProcessBeginCommand(eventData); + EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.ScalarExecuting(command, eventData, result); } @@ -201,7 +186,7 @@ public override InterceptionResult ScalarExecuting(DbCommand command, Co /// Task representing the async operation. public override Task> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) { - ProcessBeginCommand(eventData); + EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.ScalarExecutingAsync(command, eventData, result, cancellationToken); } @@ -214,7 +199,7 @@ public override Task> ScalarExecutingAsync(DbCommand /// Result object. public override object ScalarExecuted(DbCommand command, CommandExecutedEventData eventData, object result) { - ProcessEndCommand(); + EFUtil.ProcessEndCommand(); return base.ScalarExecuted(command, eventData, result); } @@ -228,104 +213,8 @@ public override object ScalarExecuted(DbCommand command, CommandExecutedEventDat /// Task representing the async operation. public override Task ScalarExecutedAsync(DbCommand command, CommandExecutedEventData eventData, object result, CancellationToken cancellationToken = default) { - ProcessEndCommand(); + EFUtil.ProcessEndCommand(); return base.ScalarExecutedAsync(command, eventData, result, cancellationToken); } - - private void ProcessBeginCommand(CommandEventData eventData) - { - Entity entity = null; - try - { - entity = _recorder.GetEntity(); - } - catch (EntityNotAvailableException e) - { - _recorder.TraceContext.HandleEntityMissing(_recorder, e, "Cannot get entity while processing start of Entity Framework command."); - } - - _recorder.BeginSubsegment(BuildSubsegmentName(eventData.Command)); - _recorder.SetNamespace("remote"); - CollectSqlInformation(eventData); - } - - private void ProcessEndCommand() - { - Entity entity = null; - try - { - entity = _recorder.GetEntity(); - } - catch (EntityNotAvailableException e) - { - _recorder.TraceContext.HandleEntityMissing(_recorder, e, "Cannot get entity while processing end of Entity Framework command."); - return; - } - - _recorder.EndSubsegment(); - } - - private void ProcessCommandError(CommandErrorEventData eventData) - { - Entity subsegment; - try - { - subsegment = _recorder.GetEntity(); - } - catch (EntityNotAvailableException e) - { - _recorder.TraceContext.HandleEntityMissing(_recorder, e, "Cannot get entity while processing failure of Entity Framework command."); - return; - } - - subsegment.AddException(eventData.Exception); - - _recorder.EndSubsegment(); - } - - /// - /// Records the SQL information on the current subsegment, - /// - protected virtual void CollectSqlInformation(CommandEventData eventData) - { - // Get database type from DbContext - string databaseType = EFUtil.GetDataBaseType(eventData.Context); - _recorder.AddSqlInformation("database_type", databaseType); - - _recorder.AddSqlInformation("database_version", eventData.Command.Connection.ServerVersion); - - DbConnectionStringBuilder connectionStringBuilder = new DbConnectionStringBuilder - { - ConnectionString = eventData.Command.Connection.ConnectionString - }; - - // Remove sensitive information from connection string - connectionStringBuilder.Remove("Password"); - - // Do a pre-check for UserID since in the case of TrustedConnection, a UserID may not be available. - var user_id = EFUtil.GetUserId(connectionStringBuilder); - if (user_id != null) - { - _recorder.AddSqlInformation("user", user_id.ToString()); - } - - _recorder.AddSqlInformation("connection_string", connectionStringBuilder.ToString()); - - if (ShouldCollectSqlText()) - { - _recorder.AddSqlInformation("sanitized_query", eventData.Command.CommandText); - } - } - - /// - /// Builds the name of the subsegment in the format database@datasource - /// - /// Instance of . - /// Returns the formed subsegment name as a string. - private string BuildSubsegmentName(DbCommand command) - => command.Connection.Database + "@" + EFUtil.RemovePortNumberFromDataSource(command.Connection.DataSource); - - private bool ShouldCollectSqlText() - => _collectSqlQueriesOverride ?? _recorder.XRayOptions.CollectSqlQueries; } } \ No newline at end of file diff --git a/sdk/src/Handlers/EntityFramework/EFInterceptor.net45.cs b/sdk/src/Handlers/EntityFramework/EFInterceptor.net45.cs new file mode 100644 index 00000000..70825467 --- /dev/null +++ b/sdk/src/Handlers/EntityFramework/EFInterceptor.net45.cs @@ -0,0 +1,113 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +using System; +using System.Data.Common; +using System.Data.Entity.Infrastructure.Interception; + +namespace Amazon.XRay.Recorder.Handlers.EntityFramework +{ + /// + /// Class to intercept SQL query through EF 6 for .NET framework. + /// + public class EFInterceptor : IDbCommandInterceptor + { + private readonly bool? _collectSqlQueriesOverride; + + public EFInterceptor(bool? collectSqlQueries = null) : base() + { + _collectSqlQueriesOverride = collectSqlQueries; + } + + /// + /// Trace before executing non query. + /// + /// Instance of . + /// Instance of . + public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext interceptionContext) + { + OnCommandStart(command); + } + + /// + /// Trace after executing non query. + /// + /// Instance of . + /// Instance of . + public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext interceptionContext) + { + OnCommandStop(interceptionContext.Exception); + } + + /// + /// Trace before executing reader. + /// + /// Instance of . + /// Instance of . + public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext interceptionContext) + { + OnCommandStart(command); + } + + /// + /// Trace after executing reader. + /// + /// Instance of . + /// Instance of . + public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext interceptionContext) + { + OnCommandStop(interceptionContext.Exception); + } + + /// + /// Trace before executing scalar. + /// + /// Instance of . + /// Instance of . + public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext interceptionContext) + { + OnCommandStart(command); + } + + /// + /// Trace after executing scalar. + /// + /// Instance of . + /// Instance of . + public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext interceptionContext) + { + OnCommandStop(interceptionContext.Exception); + } + + private void OnCommandStart(DbCommand command) + { + EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); + } + + private void OnCommandStop(Exception exception) + { + if (exception != null) + { + EFUtil.ProcessCommandError(exception); + } + else + { + EFUtil.ProcessEndCommand(); + } + } + } +} diff --git a/sdk/src/Handlers/EntityFramework/EFUtil.cs b/sdk/src/Handlers/EntityFramework/EFUtil.cs index 2f40034a..74d49182 100644 --- a/sdk/src/Handlers/EntityFramework/EFUtil.cs +++ b/sdk/src/Handlers/EntityFramework/EFUtil.cs @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // -// Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"). // You may not use this file except in compliance with the License. @@ -15,78 +15,152 @@ // //----------------------------------------------------------------------------- -using System.Collections.Generic; +using System; using System.Data.Common; using System.Text.RegularExpressions; -using Microsoft.EntityFrameworkCore; +using Amazon.Runtime.Internal.Util; +using Amazon.XRay.Recorder.Core; +#if NET45 +using Amazon.XRay.Recorder.Core.Internal.Utils; +#endif namespace Amazon.XRay.Recorder.Handlers.EntityFramework { /// /// Utilities for EFInterceptor /// - public static class EFUtil + internal static class EFUtil { - private static readonly string DefaultDatabaseType = "EntityFrameworkCore"; + private static readonly string DefaultDbTypeEntityFramework = "entityframework"; + private static readonly string SqlServerCompact35 = "sqlservercompact35"; + private static readonly string SqlServerCompact40 = "sqlservercompact40"; + private static readonly string MicrosoftSqlClient = "microsoft.data.sqlclient"; + private static readonly string SystemSqlClient = "system.data.sqlclient"; + private static readonly string SqlServer = "sqlserver"; private static readonly string[] UserIdFormatOptions = { "user id", "username", "user", "userid" }; // case insensitive - // Some database providers may not support Entity Framework Core 3.0 and above now - // https://docs.microsoft.com/en-us/ef/core/providers/?tabs=dotnet-core-cli - private static readonly Dictionary DatabaseTypes = new Dictionary() - { - { "Microsoft.EntityFrameworkCore.SqlServer" , "sqlserver" }, - { "Microsoft.EntityFrameworkCore.Sqlite" , "sqlite" }, - { "Npgsql.EntityFrameworkCore.PostgreSQL" , "postgresql" }, - { "Pomelo.EntityFrameworkCore.MySql" , "mysql" }, - { "FirebirdSql.EntityFrameworkCore.Firebird" , "firebirdsql" }, - - { "Microsoft.EntityFrameworkCore.InMemory" , "inmemory" }, - { "Microsoft.EntityFrameworkCore.Cosmos" , "cosmosdb" }, - { "Devart.Data.MySql.EFCore" , "mysql" }, - { "Devart.Data.Oracle.EFCore" , "oracle" }, - { "Devart.Data.PostgreSql.EFCore" , "postgresql" }, - { "Devart.Data.SQLite.EFCore" , "sqlite" }, - { "FileContextCore" , "filecontextcore" }, - { "EntityFrameworkCore.Jet" , "jet" }, - { "EntityFrameworkCore.SqlServerCompact35" , "sqlservercompact35" }, - { "EntityFrameworkCore.SqlServerCompact40" , "sqlservercompact40" }, - { "Teradata.EntityFrameworkCore" , "teradata" }, - { "EntityFrameworkCore.FirebirdSql" , "firebirdsql" }, - { "EntityFrameworkCore.OpenEdge" , "openedge" }, - { "MySql.Data.EntityFrameworkCore" , "mysql" }, - { "Oracle.EntityFrameworkCore" , "oracle" }, - { "IBM.EntityFrameworkCore" , "ibm" }, - { "IBM.EntityFrameworkCore-lnx" , "ibm" }, - { "IBM.EntityFrameworkCore-osx" , "ibm" }, - { "Pomelo.EntityFrameworkCore.MyCat" , "mycat" } - }; + private static readonly string[] DatabaseTypes = { "sqlserver", "sqlite", "postgresql", "mysql", "firebirdsql", + "inmemory" , "cosmosdb" , "oracle" , "filecontextcore" , + "jet" , "teradata" , "openedge" , "ibm" , "mycat" , "vfp"}; private static readonly Regex _portNumberRegex = new Regex(@"[,|:]\d+$"); + private static readonly AWSXRayRecorder _recorder = AWSXRayRecorder.Instance; + + private static readonly Logger _logger = Logger.GetLogger(typeof(EFUtil)); + + /// + /// Process command to begin subsegment. + /// + /// Instance of . + /// Nullable to indicate whether to collect sql query text or not. + internal static void ProcessBeginCommand(DbCommand command, bool? collectSqlQueriesOverride) + { + _recorder.BeginSubsegment(BuildSubsegmentName(command)); + _recorder.SetNamespace("remote"); + CollectSqlInformation(command, collectSqlQueriesOverride); + } + + /// + /// Process to end subsegment + /// + internal static void ProcessEndCommand() + { + _recorder.EndSubsegment(); + } + /// - /// Extract database_type from . + /// Process exception. /// - /// Instance of . + /// Instance of . + internal static void ProcessCommandError(Exception exception) + { + _recorder.AddException(exception); + _recorder.EndSubsegment(); + } + + /// + /// Builds the name of the subsegment in the format database@datasource + /// + /// Instance of . + /// Returns the formed subsegment name as a string. + private static string BuildSubsegmentName(DbCommand command) + => command.Connection.Database + "@" + RemovePortNumberFromDataSource(command.Connection.DataSource); + + /// + /// Records the SQL information on the current subsegment, + /// + private static void CollectSqlInformation(DbCommand command, bool? collectSqlQueriesOverride) + { + // Get database type from DbCommand + string databaseType = GetDataBaseType(command); + _recorder.AddSqlInformation("database_type", databaseType); + + DbConnectionStringBuilder connectionStringBuilder = new DbConnectionStringBuilder + { + ConnectionString = command.Connection.ConnectionString + }; + + // Remove sensitive information from connection string + connectionStringBuilder.Remove("Password"); + + _recorder.AddSqlInformation("connection_string", connectionStringBuilder.ToString()); + + // Do a pre-check for UserID since in the case of TrustedConnection, a UserID may not be available. + var user_id = GetUserId(connectionStringBuilder); + if (user_id != null) + { + _recorder.AddSqlInformation("user", user_id.ToString()); + } + + if (ShouldCollectSqlText(collectSqlQueriesOverride)) + { + _recorder.AddSqlInformation("sanitized_query", command.CommandText); + } + + _recorder.AddSqlInformation("database_version", command.Connection.ServerVersion); + } + + /// + /// Extract database_type from . + /// + /// Instance of . /// Type of database. - public static string GetDataBaseType(DbContext context) + internal static string GetDataBaseType(DbCommand command) { - string databaseProvider = context?.Database?.ProviderName; + var typeString = command?.Connection?.GetType()?.FullName?.ToLower(); - // Need to check if the context and its following parameter is null or not to avoid exception - if (string.IsNullOrEmpty(databaseProvider)) + if (string.IsNullOrEmpty(typeString)) { - return DefaultDatabaseType; + _logger.DebugFormat("Can't extract database type from connection, setting it as default: ({0})", DefaultDbTypeEntityFramework); + return DefaultDbTypeEntityFramework; } - string value = null; + if (typeString.Contains(MicrosoftSqlClient) || typeString.Contains(SystemSqlClient)) + { + return SqlServer; + } + + if (typeString.Contains(SqlServerCompact35)) + { + return SqlServerCompact35; + } + + if (typeString.Contains(SqlServerCompact40)) + { + return SqlServerCompact40; + } - if (DatabaseTypes.TryGetValue(databaseProvider, out value)) + foreach (var databaseType in DatabaseTypes) { - return value; + if (typeString.Contains(databaseType)) + { + return databaseType; + } } - return databaseProvider; + return typeString; } /// @@ -94,17 +168,17 @@ public static string GetDataBaseType(DbContext context) /// /// Instance of . /// - public static object GetUserId(DbConnectionStringBuilder builder) + internal static string GetUserId(DbConnectionStringBuilder builder) { - object value = null; foreach (string key in UserIdFormatOptions) { - if (builder.TryGetValue(key, out value)) + if (builder.TryGetValue(key, out object value)) { - break; + return (string)value; } } - return value; + + return null; } /// @@ -112,9 +186,17 @@ public static object GetUserId(DbConnectionStringBuilder builder) /// /// The data source. /// The data source string with port number removed. - public static string RemovePortNumberFromDataSource(string dataSource) + private static string RemovePortNumberFromDataSource(string dataSource) { return _portNumberRegex.Replace(dataSource, string.Empty); } + +#if !NET45 + private static bool ShouldCollectSqlText(bool? collectSqlQueriesOverride) + => collectSqlQueriesOverride ?? _recorder.XRayOptions.CollectSqlQueries; +#else + private static bool ShouldCollectSqlText(bool? collectSqlQueriesOverride) + => collectSqlQueriesOverride ?? AppSettings.CollectSqlQueries; +#endif } } diff --git a/sdk/src/Handlers/EntityFramework/Properties/AssemblyInfo.cs b/sdk/src/Handlers/EntityFramework/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..bbe308c3 --- /dev/null +++ b/sdk/src/Handlers/EntityFramework/Properties/AssemblyInfo.cs @@ -0,0 +1,9 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("AWSXRayRecorder.UnitTests,PublicKey=" + +"0024000004800000940000000602000000240000525341310004000001000100712913451f6deb" ++ "158da1d2129b21119cca7d4eebeef5b310e8acd7f2d9506346071207652f1210a3bfa1545d6897" ++ "a607fc3a515954e660ec6fc5797730022867514e58411e8ecd61c767a319d2c29facee20f5d4f4" ++ "2b5425f27518616a8f4c1e5ac0e3e2b407bd8786d1b360af6b49c2b987478fe76b124c72f48864" ++ "55199df6" +)] diff --git a/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj b/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj index a46ce2e6..3c0a5672 100644 --- a/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj +++ b/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj @@ -1,4 +1,4 @@ - + @@ -54,9 +54,9 @@ - + @@ -64,6 +64,7 @@ + @@ -74,8 +75,11 @@ + + + @@ -83,8 +87,8 @@ + - diff --git a/sdk/test/UnitTests/EF6Tests.cs b/sdk/test/UnitTests/EF6Tests.cs new file mode 100644 index 00000000..bf86f378 --- /dev/null +++ b/sdk/test/UnitTests/EF6Tests.cs @@ -0,0 +1,186 @@ +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- + +using Amazon.XRay.Recorder.Core; +using Amazon.XRay.Recorder.Core.Internal.Entities; +using Amazon.XRay.Recorder.Handlers.EntityFramework; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Data.Entity.Infrastructure.Interception; +using System.Data.SQLite; + +namespace Amazon.XRay.Recorder.UnitTests +{ + [TestClass] + public class EF6Tests : TestBase + { + private SQLiteConnection connection = null; + private AWSXRayRecorder recorder = null; + private const string connectionString = "data source=:memory:"; + private const string database = "sqlite"; + private const string nameSpace = "remote"; + private const string commandText = "Test command text"; + + [TestInitialize] + public void Initialize() + { + recorder = new AWSXRayRecorder(); + recorder.BeginSegment("Test EF6"); + connection = new SQLiteConnection(connectionString); + connection.Open(); + } + + [TestCleanup] + public new void TestCleanup() + { + connection.Close(); + connection.Dispose(); + recorder.EndSegment(); + recorder.Dispose(); + base.TestCleanup(); + } + + [TestMethod] + public void TestEFInterceptorNonQuery() + { + var efInterceptor = RegisterInterceptor(true); + + try + { + using (var command = new SQLiteCommand(commandText, connection)) + { + DbInterception.Dispatch.Command.NonQuery(command, new DbCommandInterceptionContext()); // calling API from IDbCommandInterceptor + } + } + catch + { + // Will throw exception as command text is invalid + } + + var segment = recorder.GetEntity() as Segment; + Assert.IsTrue(segment.Subsegments.Count != 0); + + var subsegment = segment.Subsegments[0]; + AssertTraceCollected(subsegment); + Assert.AreEqual(commandText, subsegment.Sql["sanitized_query"]); + + RemoveInterceptor(efInterceptor); + } + + [TestMethod] + public void TestEFInterceptorReader() + { + var efInterceptor = RegisterInterceptor(true); + + try + { + using (var command = new SQLiteCommand(commandText, connection)) + { + DbInterception.Dispatch.Command.Reader(command, new DbCommandInterceptionContext()); // calling API from IDbCommandInterceptor + } + } + catch + { + // Will throw exception as command text is invalid + } + + var segment = recorder.GetEntity() as Segment; + Assert.IsTrue(segment.Subsegments.Count != 0); + + var subsegment = segment.Subsegments[0]; + AssertTraceCollected(subsegment); + Assert.AreEqual(commandText, subsegment.Sql["sanitized_query"]); + + RemoveInterceptor(efInterceptor); + } + + [TestMethod] + public void TestEFInterceptorScalar() + { + var efInterceptor = RegisterInterceptor(true); + + try + { + using (var command = new SQLiteCommand(commandText, connection)) + { + DbInterception.Dispatch.Command.Scalar(command, new DbCommandInterceptionContext()); // calling API from IDbCommandInterceptor + } + } + catch + { + // Will throw exception as command text is invalid + } + + var segment = recorder.GetEntity() as Segment; + Assert.IsTrue(segment.Subsegments.Count != 0); + + var subsegment = segment.Subsegments[0]; + AssertTraceCollected(subsegment); + Assert.AreEqual(commandText, subsegment.Sql["sanitized_query"]); + + RemoveInterceptor(efInterceptor); + } + + [TestMethod] + public void TestEFInterceptorNonQueryWithoutQueryText() + { + var efInterceptor = RegisterInterceptor(false); + + try + { + using (var command = new SQLiteCommand(commandText, connection)) + { + DbInterception.Dispatch.Command.NonQuery(command, new DbCommandInterceptionContext()); // calling API from IDbCommandInterceptor + } + } + catch + { + // Will throw exception as command text is invalid + } + + var segment = recorder.GetEntity() as Segment; + Assert.IsTrue(segment.Subsegments.Count != 0); + + var subsegment = segment.Subsegments[0]; + AssertTraceCollected(subsegment); + Assert.IsFalse(subsegment.Sql.ContainsKey("sanitized_query")); + + RemoveInterceptor(efInterceptor); + } + + private EFInterceptor RegisterInterceptor(bool collectSqlQueries) + { + var efInterceptor = new EFInterceptor(collectSqlQueries); + DbInterception.Add(efInterceptor); + return efInterceptor; + } + + // Remove EFInterceptor from DbInterceptor to avoid duplicate tracing + private void RemoveInterceptor(EFInterceptor interceptor) + { + DbInterception.Remove(interceptor); + } + + private void AssertTraceCollected(Subsegment subsegment) + { + Assert.AreEqual(connection.ConnectionString, subsegment.Sql["connection_string"]); + Assert.AreEqual(database, subsegment.Sql["database_type"]); + Assert.AreEqual(connection.ServerVersion, subsegment.Sql["database_version"]); + Assert.AreEqual(nameSpace, subsegment.Namespace); + Assert.IsTrue(subsegment.HasFault); + } + } +} diff --git a/sdk/test/UnitTests/EFUtilTests.cs b/sdk/test/UnitTests/EFUtilTests.cs index b429ef29..31941fab 100644 --- a/sdk/test/UnitTests/EFUtilTests.cs +++ b/sdk/test/UnitTests/EFUtilTests.cs @@ -18,6 +18,8 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Data.Common; using Amazon.XRay.Recorder.Handlers.EntityFramework; +using System.Data.SQLite; +using System.Data.SqlClient; namespace Amazon.XRay.Recorder.UnitTests { @@ -90,5 +92,31 @@ public void Test_Get_UserId_FirebirdSql() object result = EFUtil.GetUserId(builder); Assert.AreEqual("SYSDBA", result.ToString()); } + + [TestMethod] + public void Test_Get_Database_Type_Sqlite() + { + var connection = new SQLiteConnection(); + var command = new SQLiteCommand(null, connection); + var databaseType = EFUtil.GetDataBaseType(command); + Assert.AreEqual("sqlite", databaseType); + } + + [TestMethod] + public void Test_Get_Database_Type_SqlServer() + { + var connection = new SqlConnection(); + var command = new SqlCommand(null, connection); + var databaseType = EFUtil.GetDataBaseType(command); + Assert.AreEqual("sqlserver", databaseType); + } + + [TestMethod] + public void Test_Get_Database_Type_EmptyConnection() + { + var command = new SqlCommand(); + var databaseType = EFUtil.GetDataBaseType(command); + Assert.AreEqual("entityframework", databaseType); // Empty connection will return entityframework by default. + } } } \ No newline at end of file diff --git a/sdk/test/UnitTests/Tools/TestEFContext.cs b/sdk/test/UnitTests/Tools/TestEFContext.cs index b786f046..607531ed 100644 --- a/sdk/test/UnitTests/Tools/TestEFContext.cs +++ b/sdk/test/UnitTests/Tools/TestEFContext.cs @@ -1,6 +1,19 @@ -using System; -using System.Collections.Generic; -using System.Text; +//----------------------------------------------------------------------------- +// +// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//----------------------------------------------------------------------------- using Microsoft.EntityFrameworkCore; From 280b6dcec85ab4204a38342d78c0d9dea41adc5c Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Thu, 11 Feb 2021 15:45:06 -0800 Subject: [PATCH 15/37] Added release workflow (#179) * Added release workflow * Added space line * Update configuration --- .github/workflows/release.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..499c6bfa --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,27 @@ +name: Release X-Ray .NET SDK + +on: + workflow_dispatch: + inputs: + version: + description: The version to tag the release with, e.g., 1.2.0, 1.3.0 + required: true + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout master branch + uses: actions/checkout@v2 + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: 'V${{ github.event.inputs.version }}' + release_name: 'Release ${{ github.event.inputs.version }}' + body: 'Please refer [change-log](https://github.com/aws/aws-xray-sdk-dotnet/blob/master/CHANGELOG.md) for more details' + draft: true + prerelease: false From 34134f0e5eb939a42e7297799db4ba6391b7e63f Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Thu, 18 Feb 2021 16:57:00 -0500 Subject: [PATCH 16/37] Switching out AppVeyor for GH workflow (#181) * Switching out AppVeyor for GH workflow * Running workflow on linux as well. building wth release config --- .github/workflows/pr-build.yml | 33 +++++++++++++++++++++++++++++++++ appveyor.yml | 23 ----------------------- 2 files changed, 33 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/pr-build.yml delete mode 100644 appveyor.yml diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml new file mode 100644 index 00000000..ae4638f7 --- /dev/null +++ b/.github/workflows/pr-build.yml @@ -0,0 +1,33 @@ +name: PR build workflow + +on: + pull_request: + branches: + - master + +jobs: + build: + name: build + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [windows-latest,ubuntu-latest] + version: [net452,netcoreapp2.0] + exclude: + - os: ubuntu-latest + version: net452 + + steps: + - name: Checkout repository + - uses: actions/checkout@v2 + + - name: Install dependencies + run: dotnet restore sdk/AWSXRayRecorder.sln --locked-mode + + - name: Build solution + run: dotnet build sdk/AWSXRayRecorder.sln --configuration Release --no-restore + + - name: Run tests + run: dotnet test sdk/test/UnitTests/bin/Release/${{matrix.version}}/AWSXRayRecorder.UnitTests.dll diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 21250b5b..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,23 +0,0 @@ -version: '1.0.{build}' -image: Visual Studio 2017 -init: - # Good practise, because Windows line endings are different from Unix/Linux ones - - cmd: git config --global core.autocrlf true -before_build: - # Display .NET Core version - - cmd: dotnet --version -build_script: - # output will be in ./src/bin/debug/netcoreapp1.1/publish - - cmd: dotnet restore sdk/AWSXRayRecorder.sln - - cmd: dotnet build sdk/AWSXRayRecorder.sln -clone_depth: 1 -test_script: - - cmd : dotnet test sdk/test/UnitTests -deploy: off -notifications: - - provider: Email - to: - - aws-xray-peryton@amazon.com - on_build_success: false - on_build_failure: true - on_build_status_changed: false From c114331cfae8482457120f17f2ad9a1e3c6c6c50 Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Tue, 23 Feb 2021 10:35:08 -0800 Subject: [PATCH 17/37] Revert "Switching out AppVeyor for GH workflow (#181)" (#185) This reverts commit 34134f0e5eb939a42e7297799db4ba6391b7e63f. --- .github/workflows/pr-build.yml | 33 --------------------------------- appveyor.yml | 23 +++++++++++++++++++++++ 2 files changed, 23 insertions(+), 33 deletions(-) delete mode 100644 .github/workflows/pr-build.yml create mode 100644 appveyor.yml diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml deleted file mode 100644 index ae4638f7..00000000 --- a/.github/workflows/pr-build.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: PR build workflow - -on: - pull_request: - branches: - - master - -jobs: - build: - name: build - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - matrix: - os: [windows-latest,ubuntu-latest] - version: [net452,netcoreapp2.0] - exclude: - - os: ubuntu-latest - version: net452 - - steps: - - name: Checkout repository - - uses: actions/checkout@v2 - - - name: Install dependencies - run: dotnet restore sdk/AWSXRayRecorder.sln --locked-mode - - - name: Build solution - run: dotnet build sdk/AWSXRayRecorder.sln --configuration Release --no-restore - - - name: Run tests - run: dotnet test sdk/test/UnitTests/bin/Release/${{matrix.version}}/AWSXRayRecorder.UnitTests.dll diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..21250b5b --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,23 @@ +version: '1.0.{build}' +image: Visual Studio 2017 +init: + # Good practise, because Windows line endings are different from Unix/Linux ones + - cmd: git config --global core.autocrlf true +before_build: + # Display .NET Core version + - cmd: dotnet --version +build_script: + # output will be in ./src/bin/debug/netcoreapp1.1/publish + - cmd: dotnet restore sdk/AWSXRayRecorder.sln + - cmd: dotnet build sdk/AWSXRayRecorder.sln +clone_depth: 1 +test_script: + - cmd : dotnet test sdk/test/UnitTests +deploy: off +notifications: + - provider: Email + to: + - aws-xray-peryton@amazon.com + on_build_success: false + on_build_failure: true + on_build_status_changed: false From 57e976a36c8f4b87060a8f503453a2cf48512a21 Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Tue, 2 Mar 2021 13:18:49 -0800 Subject: [PATCH 18/37] Added public key token (#186) --- .../Handlers/EntityFramework/Properties/AssemblyInfo.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sdk/src/Handlers/EntityFramework/Properties/AssemblyInfo.cs b/sdk/src/Handlers/EntityFramework/Properties/AssemblyInfo.cs index bbe308c3..1da1e66a 100644 --- a/sdk/src/Handlers/EntityFramework/Properties/AssemblyInfo.cs +++ b/sdk/src/Handlers/EntityFramework/Properties/AssemblyInfo.cs @@ -7,3 +7,11 @@ + "2b5425f27518616a8f4c1e5ac0e3e2b407bd8786d1b360af6b49c2b987478fe76b124c72f48864" + "55199df6" )] + +[assembly: InternalsVisibleTo("AWSXRayRecorder.UnitTests,PublicKey=" + +"002400000480000094000000060200000024000052534131000400000100010073e1dd0de5ae76" ++ "719229eb94db01747e7235a3c7064c6c81105abc100da228179e3ef1177fa9fcf9c62fbc2854e5" ++ "4394098ca20ab0ac3d99ce7e257c0c6613d775a2d40f1d8aa002c950f903da7658f6102af93fa3" ++ "112815dd5fb0d9023803d11b52d6b0d3e9f4a7ea4640b494c4744d20756f540ee1b33d2974fa01" ++ "9bf013af" +)] From 652f8f7bf915d3cc138794ed45118762c32eaa86 Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Tue, 2 Mar 2021 15:13:01 -0800 Subject: [PATCH 19/37] Release commit for v2.10.0 (#187) --- CHANGELOG.md | 30 +++++++++++++++++++ sdk/AWSXRayRecorder.nuspec | 25 ++++++++-------- sdk/src/Core/AWSXRayRecorder.Core.csproj | 6 ++-- .../AWSXRayRecorder.Handlers.AspNet.csproj | 6 ++-- ...AWSXRayRecorder.Handlers.AspNetCore.csproj | 6 ++-- .../AWSXRayRecorder.Handlers.AwsSdk.csproj | 6 ++-- ...ayRecorder.Handlers.EntityFramework.csproj | 6 ++-- .../AWSXRayRecorder.Handlers.SqlServer.csproj | 6 ++-- ...AWSXRayRecorder.Handlers.System.Net.csproj | 6 ++-- 9 files changed, 64 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d07331f..4858a45e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,36 @@ # Change Log All notable changes to this project will be documented in this file. +## 2.10.0 (2021-03-02) +### AWSXRayRecorder.Core (2.10.0) +#### Fixed +- Fixed race condition where the rule poller may start immediately before initializing the timer [PR#154](https://github.com/aws/aws-xray-sdk-dotnet/pull/154) +- Updated xraycontext to use a concurrent dictionary [PR#157](https://github.com/aws/aws-xray-sdk-dotnet/pull/157) + +#### Improved +- Added timeout for EC2 metadata requests [PR#138](https://github.com/aws/aws-xray-sdk-dotnet/pull/138) +- Applied HttpClient to get sampling info [PR#159](https://github.com/aws/aws-xray-sdk-dotnet/pull/159) + +### AWSXRayRecorder.Handlers.AwsSdk (2.8.2) +#### Fixed +- Fixed tracing S3 id pairs and SNS naming issue [#168](https://github.com/aws/aws-xray-sdk-dotnet/pull/168) + +### AWSXRayRecorder.Handlers.EntityFramework (1.1.0) +#### New Feature +- Added tracing support for EntityFramework 6 (.NET Framework) [PR#171](https://github.com/aws/aws-xray-sdk-dotnet/pull/171) + +### AWSXRayRecorder.Handlers.AspNet (2.7.2) +- Bumped version to address AWSXRayRecorder.Core package change + +### AWSXRayRecorder.Handlers.AspNetCore (2.7.2) +- Bumped version to address AWSXRayRecorder.Core package change + +### AWSXRayRecorder.Handlers.SqlServer (2.7.2) +- Bumped version to address AWSXRayRecorder.Core package change + +### AWSXRayRecorder.Handlers.System.Net (2.7.2) +- Bumped version to address AWSXRayRecorder.Core package change + ## 2.9.0 (2020-06-09) ### AWSXRayRecorder.Core (2.9.0) #### Fixed diff --git a/sdk/AWSXRayRecorder.nuspec b/sdk/AWSXRayRecorder.nuspec index dfa5307d..891c148c 100644 --- a/sdk/AWSXRayRecorder.nuspec +++ b/sdk/AWSXRayRecorder.nuspec @@ -2,7 +2,7 @@ AWSXRayRecorder - 2.9.0 + 2.10.0 AWS X-Ray Recorder AWS Web Service http://aws.amazon.com/apache2.0/ @@ -15,19 +15,20 @@ AWS Amazon cloud AWSXRay XRay - - - - - + + + + + + - - - - - - + + + + + + diff --git a/sdk/src/Core/AWSXRayRecorder.Core.csproj b/sdk/src/Core/AWSXRayRecorder.Core.csproj index dc20b777..a971f730 100644 --- a/sdk/src/Core/AWSXRayRecorder.Core.csproj +++ b/sdk/src/Core/AWSXRayRecorder.Core.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.9.0.0 - 2.9.0.0 - 2.9.0 + 2.10.0.0 + 2.10.0.0 + 2.10.0 Amazon.XRay.Recorder.Core true ../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj b/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj index 60622d02..48333269 100644 --- a/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj +++ b/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.1.0 - 2.7.1.0 - 2.7.1 + 2.7.2.0 + 2.7.2.0 + 2.7.2 Amazon.XRay.Recorder.Handlers.AspNet true ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj b/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj index 0c3cae83..153cc21a 100644 --- a/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj +++ b/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj @@ -4,9 +4,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.1.0 - 2.7.1.0 - 2.7.1 + 2.7.2.0 + 2.7.2.0 + 2.7.2 true Amazon.XRay.Recorder.Handlers.AspNetCore ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj b/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj index fa1b21c2..604e9533 100644 --- a/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj +++ b/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.8.1.0 - 2.8.1.0 - 2.8.1 + 2.8.2.0 + 2.8.2.0 + 2.8.2 Amazon.XRay.Recorder.Handlers.AwsSdk true ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj b/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj index 14865753..8660eb70 100644 --- a/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj +++ b/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 1.0.1.0 - 1.0.1.0 - 1.0.1 + 1.1.0.0 + 1.1.0.0 + 1.1.0 AWSXRayRecorder.Handlers.EntityFramework Amazon.XRay.Recorder.Handlers.EntityFramework Amazon Web Services diff --git a/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj b/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj index 86e2bcd7..a3478809 100644 --- a/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj +++ b/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.1.0 - 2.7.1.0 - 2.7.1 + 2.7.2.0 + 2.7.2.0 + 2.7.2 Amazon.XRay.Recorder.Handlers.SqlServer true ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj b/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj index 2a1d7a0b..11b6d91b 100644 --- a/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj +++ b/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.1.0 - 2.7.1.0 - 2.7.1 + 2.7.2.0 + 2.7.2.0 + 2.7.2 Amazon.XRay.Recorder.Handlers.System.Net true ../../../../buildtools/local-development.snk From d2b64125ecdd734af220795d5b102bd96b037981 Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Wed, 3 Mar 2021 10:38:01 -0800 Subject: [PATCH 20/37] Updated API Doc (#188) --- .../AWSXRayDotNetCoreDocumentation.shfbproj | 2 ++ .../AWSXRayDotNetDocumentation.shfbproj | 2 ++ 2 files changed, 4 insertions(+) diff --git a/buildtools/API_Reference/AWSXRayDotNetCoreDocumentation/AWSXRayDotNetCoreDocumentation.shfbproj b/buildtools/API_Reference/AWSXRayDotNetCoreDocumentation/AWSXRayDotNetCoreDocumentation.shfbproj index 826082c1..9f30d21a 100644 --- a/buildtools/API_Reference/AWSXRayDotNetCoreDocumentation/AWSXRayDotNetCoreDocumentation.shfbproj +++ b/buildtools/API_Reference/AWSXRayDotNetCoreDocumentation/AWSXRayDotNetCoreDocumentation.shfbproj @@ -35,6 +35,8 @@ + + diff --git a/buildtools/API_Reference/AWSXRayDotNetDocumentation/AWSXRayDotNetDocumentation.shfbproj b/buildtools/API_Reference/AWSXRayDotNetDocumentation/AWSXRayDotNetDocumentation.shfbproj index 58197046..ab0e4420 100644 --- a/buildtools/API_Reference/AWSXRayDotNetDocumentation/AWSXRayDotNetDocumentation.shfbproj +++ b/buildtools/API_Reference/AWSXRayDotNetDocumentation/AWSXRayDotNetDocumentation.shfbproj @@ -37,6 +37,8 @@ + + From 551cdaa792e21e4d195d9fa3b608289f3c0e2baf Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Tue, 30 Mar 2021 15:16:22 -0700 Subject: [PATCH 21/37] Add smoke test of distribution channel (#189) * Add smoke test of distribution channel * Updated AWSXRayRecorder.sln * Points to the latest version --- .github/workflows/continuous-monitoring.yml | 33 +++++++++++++++++++ sdk/AWSXRayRecorder.sln | 11 ++++++- .../AWSXRayRecorder.SmokeTests.csproj | 25 ++++++++++++++ sdk/test/SmokeTests/SmokeTest.cs | 32 ++++++++++++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/continuous-monitoring.yml create mode 100644 sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj create mode 100644 sdk/test/SmokeTests/SmokeTest.cs diff --git a/.github/workflows/continuous-monitoring.yml b/.github/workflows/continuous-monitoring.yml new file mode 100644 index 00000000..a3b79d10 --- /dev/null +++ b/.github/workflows/continuous-monitoring.yml @@ -0,0 +1,33 @@ +name: Continuous monitoring of distribution channels + +on: + workflow_dispatch: + schedule: + - cron: '0 */1 * * *' + +jobs: + smoke-tests: + name: Run smoke tests + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [windows-latest,ubuntu-latest] + version: [net452,netcoreapp2.0] + exclude: + - os: ubuntu-latest + version: net452 + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install dependencies + run: dotnet restore sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj + + - name: Build tests + run: dotnet build sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj --configuration Release --no-restore + + - name: Run tests + run: dotnet test sdk/test/SmokeTests/bin/Release/${{matrix.version}}/AWSXRayRecorder.SmokeTests.dll diff --git a/sdk/AWSXRayRecorder.sln b/sdk/AWSXRayRecorder.sln index 5f4d36fd..c4fecb59 100644 --- a/sdk/AWSXRayRecorder.sln +++ b/sdk/AWSXRayRecorder.sln @@ -25,7 +25,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWSXRayRecorder.UnitTests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWSXRayRecorder.Handlers.AspNet", "src\Handlers\AspNet\AWSXRayRecorder.Handlers.AspNet.csproj", "{C647F311-4023-4E0B-9147-074EAF243D54}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AWSXRayRecorder.Handlers.EntityFramework", "src\Handlers\EntityFramework\AWSXRayRecorder.Handlers.EntityFramework.csproj", "{B5C2F674-6539-4A04-9B7D-14E300962BFE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWSXRayRecorder.Handlers.EntityFramework", "src\Handlers\EntityFramework\AWSXRayRecorder.Handlers.EntityFramework.csproj", "{B5C2F674-6539-4A04-9B7D-14E300962BFE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AWSXRayRecorder.SmokeTests", "test\SmokeTests\AWSXRayRecorder.SmokeTests.csproj", "{157BF1A6-324B-4F56-B5A5-619F22F5F314}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -88,6 +90,12 @@ Global {B5C2F674-6539-4A04-9B7D-14E300962BFE}.Nuget|Any CPU.Build.0 = Release|Any CPU {B5C2F674-6539-4A04-9B7D-14E300962BFE}.Release|Any CPU.ActiveCfg = Release|Any CPU {B5C2F674-6539-4A04-9B7D-14E300962BFE}.Release|Any CPU.Build.0 = Release|Any CPU + {157BF1A6-324B-4F56-B5A5-619F22F5F314}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {157BF1A6-324B-4F56-B5A5-619F22F5F314}.Debug|Any CPU.Build.0 = Debug|Any CPU + {157BF1A6-324B-4F56-B5A5-619F22F5F314}.Nuget|Any CPU.ActiveCfg = Debug|Any CPU + {157BF1A6-324B-4F56-B5A5-619F22F5F314}.Nuget|Any CPU.Build.0 = Debug|Any CPU + {157BF1A6-324B-4F56-B5A5-619F22F5F314}.Release|Any CPU.ActiveCfg = Release|Any CPU + {157BF1A6-324B-4F56-B5A5-619F22F5F314}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -102,6 +110,7 @@ Global {B7D60B1F-C452-454E-AD4B-202A40E628E8} = {F0ED74B6-1639-47D3-9511-B4217012AC88} {C647F311-4023-4E0B-9147-074EAF243D54} = {6FD9C919-1504-445D-B70D-D0F8AC2829C4} {B5C2F674-6539-4A04-9B7D-14E300962BFE} = {6FD9C919-1504-445D-B70D-D0F8AC2829C4} + {157BF1A6-324B-4F56-B5A5-619F22F5F314} = {F0ED74B6-1639-47D3-9511-B4217012AC88} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E3276CD5-62B3-466D-BFDD-2AFDB8819B46} diff --git a/sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj b/sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj new file mode 100644 index 00000000..c1cf4749 --- /dev/null +++ b/sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj @@ -0,0 +1,25 @@ + + + + net452;netcoreapp2.0 + Amazon.com, Inc + Amazon Web Service X-Ray Recorder + Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + 1.0.0.0 + 1.0.0.0 + Amazon.XRay.Recorder.SmokeTests + true + + + + NET45 + + + + + + + + + + diff --git a/sdk/test/SmokeTests/SmokeTest.cs b/sdk/test/SmokeTests/SmokeTest.cs new file mode 100644 index 00000000..4774d5b7 --- /dev/null +++ b/sdk/test/SmokeTests/SmokeTest.cs @@ -0,0 +1,32 @@ +using Amazon.XRay.Recorder.Core.Internal.Emitters; +using Amazon.XRay.Recorder.Core.Internal.Entities; +using Amazon.XRay.Recorder.Core.Internal.Utils; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace Amazon.XRay.Recorder.SmokeTests +{ + [TestClass] + public class SmokeTest + { + private Mock mockEmitter; + + [TestInitialize] + public void Initialize() + { + mockEmitter = new Mock(); + } + + [TestMethod] + public void Emits() + { + using (var client = AWSXRayRecorderFactory.CreateAWSXRayRecorder(mockEmitter.Object)) + { + client.BeginSegment("test"); + client.EndSegment(); + + mockEmitter.Verify(x => x.Send(It.IsAny()), Times.Once); + } + } + } +} From 437b81c03fdb2c46a3ab1d2a3ca90b34482283b2 Mon Sep 17 00:00:00 2001 From: Bhautik Pipaliya <56270044+bhautikpip@users.noreply.github.com> Date: Thu, 1 Apr 2021 17:40:49 -0700 Subject: [PATCH 22/37] Publish metric on distribution availability (#190) --- .github/workflows/continuous-monitoring.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/continuous-monitoring.yml b/.github/workflows/continuous-monitoring.yml index a3b79d10..de064906 100644 --- a/.github/workflows/continuous-monitoring.yml +++ b/.github/workflows/continuous-monitoring.yml @@ -22,6 +22,13 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 - name: Install dependencies run: dotnet restore sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj @@ -30,4 +37,14 @@ jobs: run: dotnet build sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj --configuration Release --no-restore - name: Run tests + id: distribution-availability run: dotnet test sdk/test/SmokeTests/bin/Release/${{matrix.version}}/AWSXRayRecorder.SmokeTests.dll + + - name: Publish metric on X-Ray Dotnet SDK distribution availability + if: ${{ always() }} + run: | + if [[ "${{ steps.distribution-availability.outcome }}" == "failure" ]]; then + aws cloudwatch put-metric-data --metric-name XRayDotnetSDKDistributionUnavailability --dimensions failure=rate --namespace MonitorSDK --value 1 --timestamp $(date +%s) + else + aws cloudwatch put-metric-data --metric-name XRayDotnetSDKDistributionUnavailability --dimensions failure=rate --namespace MonitorSDK --value 0 --timestamp $(date +%s) + fi From c32a39d85d3d571633ec63a2d1c97c715c6c2604 Mon Sep 17 00:00:00 2001 From: Bhautik Pipaliya <56270044+bhautikpip@users.noreply.github.com> Date: Thu, 1 Apr 2021 20:47:39 -0700 Subject: [PATCH 23/37] Run test on ubuntu (#191) --- .github/workflows/continuous-monitoring.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/continuous-monitoring.yml b/.github/workflows/continuous-monitoring.yml index de064906..14bb8d17 100644 --- a/.github/workflows/continuous-monitoring.yml +++ b/.github/workflows/continuous-monitoring.yml @@ -13,11 +13,8 @@ jobs: strategy: fail-fast: false matrix: - os: [windows-latest,ubuntu-latest] - version: [net452,netcoreapp2.0] - exclude: - - os: ubuntu-latest - version: net452 + os: [ubuntu-latest] + version: [netcoreapp2.0] steps: - name: Checkout repository From 42de8000df622cc17ca9e2ba741c8e7a09de0c35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Apr 2021 13:12:04 -0700 Subject: [PATCH 24/37] Bump System.Net.Http from 4.3.3 to 4.3.4 in /sdk/src/Core (#193) Bumps System.Net.Http from 4.3.3 to 4.3.4. Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- sdk/src/Core/AWSXRayRecorder.Core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/src/Core/AWSXRayRecorder.Core.csproj b/sdk/src/Core/AWSXRayRecorder.Core.csproj index a971f730..f0855ecd 100644 --- a/sdk/src/Core/AWSXRayRecorder.Core.csproj +++ b/sdk/src/Core/AWSXRayRecorder.Core.csproj @@ -42,7 +42,7 @@ - + From 3b0cb9162068051c4944c913bf78cd5577248fd5 Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Wed, 21 Apr 2021 15:15:03 -0700 Subject: [PATCH 25/37] Release commit for v2.10.1 (#194) --- CHANGELOG.md | 23 ++++++++++++++++ sdk/AWSXRayRecorder.nuspec | 26 +++++++++---------- sdk/src/Core/AWSXRayRecorder.Core.csproj | 6 ++--- .../AWSXRayRecorder.Handlers.AspNet.csproj | 6 ++--- ...AWSXRayRecorder.Handlers.AspNetCore.csproj | 6 ++--- .../AWSXRayRecorder.Handlers.AwsSdk.csproj | 6 ++--- ...ayRecorder.Handlers.EntityFramework.csproj | 6 ++--- .../AWSXRayRecorder.Handlers.SqlServer.csproj | 6 ++--- ...AWSXRayRecorder.Handlers.System.Net.csproj | 6 ++--- 9 files changed, 57 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4858a45e..eea9f6be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,29 @@ # Change Log All notable changes to this project will be documented in this file. +## 2.10.1 (2021-04-21) +### AWSXRayRecorder.Core (2.10.1) +#### Fixed +- Bump System.Net.Http from 4.3.3 to 4.3.4 in /sdk/src/Core [PR#193](https://github.com/aws/aws-xray-sdk-dotnet/pull/193) + +### AWSXRayRecorder.Handlers.AwsSdk (2.8.3) +- Bumped version to address AWSXRayRecorder.Core package change + +### AWSXRayRecorder.Handlers.EntityFramework (1.1.1) +- Bumped version to address AWSXRayRecorder.Core package change + +### AWSXRayRecorder.Handlers.AspNet (2.7.3) +- Bumped version to address AWSXRayRecorder.Core package change + +### AWSXRayRecorder.Handlers.AspNetCore (2.7.3) +- Bumped version to address AWSXRayRecorder.Core package change + +### AWSXRayRecorder.Handlers.SqlServer (2.7.3) +- Bumped version to address AWSXRayRecorder.Core package change + +### AWSXRayRecorder.Handlers.System.Net (2.7.3) +- Bumped version to address AWSXRayRecorder.Core package change + ## 2.10.0 (2021-03-02) ### AWSXRayRecorder.Core (2.10.0) #### Fixed diff --git a/sdk/AWSXRayRecorder.nuspec b/sdk/AWSXRayRecorder.nuspec index 891c148c..861af27d 100644 --- a/sdk/AWSXRayRecorder.nuspec +++ b/sdk/AWSXRayRecorder.nuspec @@ -2,7 +2,7 @@ AWSXRayRecorder - 2.10.0 + 2.10.1 AWS X-Ray Recorder AWS Web Service http://aws.amazon.com/apache2.0/ @@ -15,20 +15,20 @@ AWS Amazon cloud AWSXRay XRay - - - - - - + + + + + + - - - - - - + + + + + + diff --git a/sdk/src/Core/AWSXRayRecorder.Core.csproj b/sdk/src/Core/AWSXRayRecorder.Core.csproj index f0855ecd..032f7bcd 100644 --- a/sdk/src/Core/AWSXRayRecorder.Core.csproj +++ b/sdk/src/Core/AWSXRayRecorder.Core.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.10.0.0 - 2.10.0.0 - 2.10.0 + 2.10.1.0 + 2.10.1.0 + 2.10.1 Amazon.XRay.Recorder.Core true ../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj b/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj index 48333269..5644af64 100644 --- a/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj +++ b/sdk/src/Handlers/AspNet/AWSXRayRecorder.Handlers.AspNet.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.2.0 - 2.7.2.0 - 2.7.2 + 2.7.3.0 + 2.7.3.0 + 2.7.3 Amazon.XRay.Recorder.Handlers.AspNet true ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj b/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj index 153cc21a..817c5259 100644 --- a/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj +++ b/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj @@ -4,9 +4,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.2.0 - 2.7.2.0 - 2.7.2 + 2.7.3.0 + 2.7.3.0 + 2.7.3 true Amazon.XRay.Recorder.Handlers.AspNetCore ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj b/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj index 604e9533..95d32ab4 100644 --- a/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj +++ b/sdk/src/Handlers/AwsSdk/AWSXRayRecorder.Handlers.AwsSdk.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.8.2.0 - 2.8.2.0 - 2.8.2 + 2.8.3.0 + 2.8.3.0 + 2.8.3 Amazon.XRay.Recorder.Handlers.AwsSdk true ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj b/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj index 8660eb70..ca9b4cba 100644 --- a/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj +++ b/sdk/src/Handlers/EntityFramework/AWSXRayRecorder.Handlers.EntityFramework.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 1.1.0.0 - 1.1.0.0 - 1.1.0 + 1.1.1.0 + 1.1.1.0 + 1.1.1 AWSXRayRecorder.Handlers.EntityFramework Amazon.XRay.Recorder.Handlers.EntityFramework Amazon Web Services diff --git a/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj b/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj index a3478809..b21bd430 100644 --- a/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj +++ b/sdk/src/Handlers/SqlServer/AWSXRayRecorder.Handlers.SqlServer.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.2.0 - 2.7.2.0 - 2.7.2 + 2.7.3.0 + 2.7.3.0 + 2.7.3 Amazon.XRay.Recorder.Handlers.SqlServer true ../../../../buildtools/local-development.snk diff --git a/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj b/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj index 11b6d91b..6801c864 100644 --- a/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj +++ b/sdk/src/Handlers/System.Net/AWSXRayRecorder.Handlers.System.Net.csproj @@ -5,9 +5,9 @@ Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. - 2.7.2.0 - 2.7.2.0 - 2.7.2 + 2.7.3.0 + 2.7.3.0 + 2.7.3 Amazon.XRay.Recorder.Handlers.System.Net true ../../../../buildtools/local-development.snk From 0506c3c3c45ddda51ed0857eb669953fd0f3dee2 Mon Sep 17 00:00:00 2001 From: William Armiros <54150514+willarmiros@users.noreply.github.com> Date: Tue, 18 May 2021 15:33:04 -0600 Subject: [PATCH 26/37] Update continuous-monitoring.yml --- .github/workflows/continuous-monitoring.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous-monitoring.yml b/.github/workflows/continuous-monitoring.yml index 14bb8d17..df94c383 100644 --- a/.github/workflows/continuous-monitoring.yml +++ b/.github/workflows/continuous-monitoring.yml @@ -3,7 +3,7 @@ name: Continuous monitoring of distribution channels on: workflow_dispatch: schedule: - - cron: '0 */1 * * *' + - cron: '*/30 * * * *' jobs: smoke-tests: From 5be713a4f3a3a7a677b854b4666ff06b37e4d486 Mon Sep 17 00:00:00 2001 From: William Armiros <54150514+willarmiros@users.noreply.github.com> Date: Tue, 18 May 2021 17:48:20 -0600 Subject: [PATCH 27/37] Increase continuous monitoring to 10 minutes --- .github/workflows/continuous-monitoring.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous-monitoring.yml b/.github/workflows/continuous-monitoring.yml index df94c383..c308d090 100644 --- a/.github/workflows/continuous-monitoring.yml +++ b/.github/workflows/continuous-monitoring.yml @@ -3,7 +3,7 @@ name: Continuous monitoring of distribution channels on: workflow_dispatch: schedule: - - cron: '*/30 * * * *' + - cron: '*/10 * * * *' jobs: smoke-tests: From e87cf50dd5ac89d545b639c86bd7048830ad090c Mon Sep 17 00:00:00 2001 From: martincostello Date: Thu, 14 Oct 2021 09:00:40 +0100 Subject: [PATCH 28/37] Add netcoreapp3.1 target framework Add a target framework moniker for .NET Core 3.1. --- sdk/AWSXRayRecorder.nuspec | 13 +++++++++++++ sdk/src/Core/AWSXRayRecorder.Core.csproj | 10 +++++++--- .../AWSXRayRecorder.Handlers.AspNetCore.csproj | 8 ++++++-- .../AWSXRayRecorder.IntegrationTests.csproj | 2 +- .../AWSXRayRecorder.SmokeTests.csproj | 2 +- .../UnitTests/AWSXRayRecorder.UnitTests.csproj | 18 ++++++++++++++++-- .../UnitTests/JsonSegmentMarshallerTest.cs | 7 ++++++- 7 files changed, 50 insertions(+), 10 deletions(-) diff --git a/sdk/AWSXRayRecorder.nuspec b/sdk/AWSXRayRecorder.nuspec index 861af27d..bdf6f3c8 100644 --- a/sdk/AWSXRayRecorder.nuspec +++ b/sdk/AWSXRayRecorder.nuspec @@ -30,6 +30,19 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/sdk/src/Core/AWSXRayRecorder.Core.csproj b/sdk/src/Core/AWSXRayRecorder.Core.csproj index 032f7bcd..49a169f8 100644 --- a/sdk/src/Core/AWSXRayRecorder.Core.csproj +++ b/sdk/src/Core/AWSXRayRecorder.Core.csproj @@ -1,7 +1,7 @@  - net45;netstandard2.0 + net45;netstandard2.0;netcoreapp3.1 Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -46,7 +46,11 @@ - + + + + + @@ -54,7 +58,7 @@ - + diff --git a/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj b/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj index 817c5259..5c1bb088 100644 --- a/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj +++ b/sdk/src/Handlers/AspNetCore/AWSXRayRecorder.Handlers.AspNetCore.csproj @@ -1,6 +1,6 @@  - netstandard2.0 + netstandard2.0;netcoreapp3.1 Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2017-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -28,11 +28,15 @@ 1701;1702;1705;1591;1587;1573;1572 - + + + + + diff --git a/sdk/test/IntegrationTests/AWSXRayRecorder.IntegrationTests.csproj b/sdk/test/IntegrationTests/AWSXRayRecorder.IntegrationTests.csproj index 58460316..62e5fdd0 100644 --- a/sdk/test/IntegrationTests/AWSXRayRecorder.IntegrationTests.csproj +++ b/sdk/test/IntegrationTests/AWSXRayRecorder.IntegrationTests.csproj @@ -2,7 +2,7 @@ - net45;netcoreapp2.0 + net45;netcoreapp2.0;netcoreapp3.1 Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj b/sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj index c1cf4749..15b0da58 100644 --- a/sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj +++ b/sdk/test/SmokeTests/AWSXRayRecorder.SmokeTests.csproj @@ -1,7 +1,7 @@  - net452;netcoreapp2.0 + net452;netcoreapp2.0;netcoreapp3.1 Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj b/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj index 3c0a5672..42c7300f 100644 --- a/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj +++ b/sdk/test/UnitTests/AWSXRayRecorder.UnitTests.csproj @@ -2,7 +2,7 @@ - net452;netcoreapp2.0 + net452;netcoreapp2.0;netcoreapp3.1 Amazon.com, Inc Amazon Web Service X-Ray Recorder Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. @@ -35,6 +35,15 @@ 0618;1701;1702;1705 + + TRACE;DEBUG + 0618;1701;1702;1705 + + + + 0618;1701;1702;1705 + + @@ -55,6 +64,11 @@ + + + + + @@ -77,7 +91,7 @@ - + diff --git a/sdk/test/UnitTests/JsonSegmentMarshallerTest.cs b/sdk/test/UnitTests/JsonSegmentMarshallerTest.cs index c85d30f6..ff2d8fea 100644 --- a/sdk/test/UnitTests/JsonSegmentMarshallerTest.cs +++ b/sdk/test/UnitTests/JsonSegmentMarshallerTest.cs @@ -114,7 +114,7 @@ public void TestMarshallDelegate() public object SyncFunction(object obj) => obj; public void SyncAction(object obj) { return; } - public async Task AsyncFunction(object obj) => obj; + public Task AsyncFunction(object obj) => Task.FromResult(obj); [TestMethod] public void TestMarshallSimpleSegment() @@ -190,7 +190,12 @@ public void TestMarshallAddException() var filePath = trace.GetFrame(0).GetFileName().Replace("\\", "\\\\"); var line = new StackTrace(e, true).GetFrame(0).GetFileLineNumber(); var workingDirectory = Directory.GetCurrentDirectory().Replace("\\", "\\\\"); + +#if NETCOREAPP3_1_OR_GREATER + var expected = "{\"format\":\"json\",\"version\":1}\n{\"id\":\"1111111111111111\",\"start_time\":0,\"end_time\":0,\"name\":\"test\",\"fault\":true,\"cause\":{\"working_directory\":\"" + workingDirectory + "\",\"exceptions\":[{\"id\":\"" + subsegment.Cause.ExceptionDescriptors[0].Id + "\",\"message\":\"Value cannot be null. (Parameter 'value')\",\"type\":\"ArgumentNullException\",\"remote\":false,\"stack\":[{\"path\":\"" + filePath + "\",\"line\":" + line + ",\"label\":\"Amazon.XRay.Recorder.UnitTests.JsonSegmentMarshallerTest.TestMarshallAddException\"}]}]}}"; +#else var expected = "{\"format\":\"json\",\"version\":1}\n{\"id\":\"1111111111111111\",\"start_time\":0,\"end_time\":0,\"name\":\"test\",\"fault\":true,\"cause\":{\"working_directory\":\"" + workingDirectory + "\",\"exceptions\":[{\"id\":\"" + subsegment.Cause.ExceptionDescriptors[0].Id + "\",\"message\":\"Value cannot be null." + Environment.NewLine.Replace("\r", @"\r").Replace("\n", @"\n") + "Parameter name: value\",\"type\":\"ArgumentNullException\",\"remote\":false,\"stack\":[{\"path\":\"" + filePath + "\",\"line\":" + line + ",\"label\":\"Amazon.XRay.Recorder.UnitTests.JsonSegmentMarshallerTest.TestMarshallAddException\"}]}]}}"; +#endif Assert.AreEqual(expected, actual); } From 9b4015d70c5ce5a50d9281c50515ccee74abfe8b Mon Sep 17 00:00:00 2001 From: William Armiros <54150514+willarmiros@users.noreply.github.com> Date: Tue, 9 Nov 2021 20:10:59 -0800 Subject: [PATCH 29/37] Create CODEOWNERS --- CODEOWNERS | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..ec4e534a --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,11 @@ +##################################################### +# +# List of approvers for this repository +# +##################################################### +# +# Learn about CODEOWNERS file format: +# https://help.github.com/en/articles/about-code-owners +# + +* @aws/aws-x-ray From 97e7a8a40a64598cf4e55ae1761b30014e674887 Mon Sep 17 00:00:00 2001 From: Lu Peng <61207760+lupengamzn@users.noreply.github.com> Date: Thu, 10 Feb 2022 15:26:01 -0800 Subject: [PATCH 30/37] Update appveyor.yml (#226) * Update appveyor.yml * Update appveyor.yml --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 21250b5b..a4ef33b8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ version: '1.0.{build}' -image: Visual Studio 2017 +image: Visual Studio 2019 init: # Good practise, because Windows line endings are different from Unix/Linux ones - cmd: git config --global core.autocrlf true From 193d70d5ca9de0fd8453232dfe341a68abb061be Mon Sep 17 00:00:00 2001 From: Bhautik Pipaliya <56270044+bhautikpip@users.noreply.github.com> Date: Mon, 21 Feb 2022 11:51:16 -0800 Subject: [PATCH 31/37] Update .netappcore version for smoke tests (#228) * Update continuous-monitoring.yml * Update netcoreapp version in .csproj file * Update continuous-monitoring.yml * Update AWSXRayRecorder.SmokeTests.csproj --- .github/workflows/continuous-monitoring.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous-monitoring.yml b/.github/workflows/continuous-monitoring.yml index c308d090..df54b3c8 100644 --- a/.github/workflows/continuous-monitoring.yml +++ b/.github/workflows/continuous-monitoring.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - version: [netcoreapp2.0] + version: [netcoreapp3.1] steps: - name: Checkout repository From d124bfd1d463e33330df4652e4fb1496363e055d Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Mon, 7 Mar 2022 14:34:46 -0800 Subject: [PATCH 32/37] Use GitHub workflow for CI on PRs and master builds (#231) --- .github/workflows/ci.yml | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..88dc0afc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,46 @@ +name: Continuous Build + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + build-test: + runs-on: windows-latest + + env: + DOTNET_MULTILEVEL_LOOKUP: 1 + + strategy: + fail-fast: false + matrix: + version: [net452, netcoreapp2.0, netcoreapp3.1] + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: '2.0.x' + + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: '3.1.x' + + - name: Install dependencies + run: dotnet restore sdk/AWSXRayRecorder.sln + + - name: Build solution + run: dotnet build sdk/AWSXRayRecorder.sln --configuration Release --no-restore + + - name: Run tests + run: >- + dotnet test sdk/test/UnitTests/bin/Release/${{matrix.version}}/AWSXRayRecorder.UnitTests.dll + --configuration Release + --no-build + --logger "console;verbosity=detailed" From b19035277fbcdb8a742138e2275461fe7f9f6254 Mon Sep 17 00:00:00 2001 From: jon-armen Date: Mon, 7 Mar 2022 22:04:00 -0500 Subject: [PATCH 33/37] Update continuous-monitoring.yml --- .github/workflows/continuous-monitoring.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/continuous-monitoring.yml b/.github/workflows/continuous-monitoring.yml index df54b3c8..00b31323 100644 --- a/.github/workflows/continuous-monitoring.yml +++ b/.github/workflows/continuous-monitoring.yml @@ -2,8 +2,6 @@ name: Continuous monitoring of distribution channels on: workflow_dispatch: - schedule: - - cron: '*/10 * * * *' jobs: smoke-tests: From 0f57392c556b23eba305a574625315e4c3c28f6d Mon Sep 17 00:00:00 2001 From: jon-armen Date: Mon, 7 Mar 2022 22:20:05 -0500 Subject: [PATCH 34/37] Add Source Link support for enhanced debugging experience (#229) * Add Source Link support for enhanced debugging experience * NetFramework does not support embedded pdb Co-authored-by: Jon Armen --- sdk/Directory.Build.props | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 sdk/Directory.Build.props diff --git a/sdk/Directory.Build.props b/sdk/Directory.Build.props new file mode 100644 index 00000000..79609b15 --- /dev/null +++ b/sdk/Directory.Build.props @@ -0,0 +1,10 @@ + + + + + + + + portable + + \ No newline at end of file From 2034955b33e85e95feb120dccc732e166b61916e Mon Sep 17 00:00:00 2001 From: Jon Armen Date: Thu, 17 Mar 2022 11:43:55 -0400 Subject: [PATCH 35/37] Finding the same exception in different subsegments should reuse the same cause id (#210) Co-authored-by: Jon Armen --- .../DefaultExceptionSerializationStrategy.cs | 1 + .../UnitTests/AWSXRayRecorderBuilderTests.cs | 62 +++++++++++++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/sdk/src/Core/Strategies/DefaultExceptionSerializationStrategy.cs b/sdk/src/Core/Strategies/DefaultExceptionSerializationStrategy.cs index f9a2079b..cbc4898e 100644 --- a/sdk/src/Core/Strategies/DefaultExceptionSerializationStrategy.cs +++ b/sdk/src/Core/Strategies/DefaultExceptionSerializationStrategy.cs @@ -154,6 +154,7 @@ public List DescribeException(Exception e, IEnumerable l = new List(); + l.Add(typeof(ArgumentNullException)); + var recorder = new AWSXRayRecorderBuilder().WithExceptionSerializationStrategy(new DefaultExceptionSerializationStrategy(10, l)).Build(); // set custom stackframe size + AWSXRayRecorder.InitializeInstance(recorder: recorder); + AWSXRayRecorder.Instance.BeginSegment("parent", TraceId); + + var segment = AWSXRayRecorder.Instance.TraceContext.GetEntity(); + + try + { + recorder.BeginSubsegment("child1"); + try + { + try + { + recorder.BeginSubsegment("child2"); + throw new AmazonServiceException(); + } + catch (AmazonServiceException e) + { + recorder.AddException(e); + recorder.EndSubsegment(); + throw; + } + } + catch (AmazonServiceException e) + { + recorder.AddException(e); + recorder.EndSubsegment(); + throw new EntityNotAvailableException("Dummy message", e); + } + } + catch (EntityNotAvailableException e) + { + recorder.AddException(e); + recorder.EndSegment(); + } + + Assert.AreEqual("Dummy message", segment.Cause.ExceptionDescriptors[0].Message); + Assert.AreEqual("EntityNotAvailableException", segment.Cause.ExceptionDescriptors[0].Type); + Assert.IsFalse(segment.Cause.ExceptionDescriptors[0].Remote); // default false + Assert.AreEqual(segment.Cause.ExceptionDescriptors[0].Cause, segment.Subsegments[0].Cause.ExceptionDescriptors[0].Id); + Assert.AreEqual(1, segment.Cause.ExceptionDescriptors.Count); + + Assert.IsNull(segment.Subsegments[0].Cause.ExceptionDescriptors[0].Type); + Assert.IsFalse(segment.Subsegments[0].Cause.ExceptionDescriptors[0].Remote); // default false + + Assert.AreEqual("AmazonServiceException", segment.Subsegments[0].Subsegments[0].Cause.ExceptionDescriptors[0].Type); + Assert.IsTrue(segment.Subsegments[0].Subsegments[0].Cause.ExceptionDescriptors[0].Remote); // set to true + } + [TestMethod] [ExpectedException(typeof(ArgumentNullException))] public void TestSetNullExceptionSerializationStrategy() @@ -457,7 +511,7 @@ public void SetDaemonAddress(string daemonAddress) } } - public class DummyTraceContext : ITraceContext + public class DummyTraceContext : ITraceContext { public void ClearEntity() { From 975f356e721e15fe5f16c0b37d486e625399ecd0 Mon Sep 17 00:00:00 2001 From: Scott Munro Date: Thu, 17 Mar 2022 17:50:30 +0100 Subject: [PATCH 36/37] Removed blocking call which was producing deadlocks from EC2Plugin. (#234) --- sdk/src/Core/Plugins/EC2Plugin.cs | 40 +++++++++++++++++------------ sdk/test/UnitTests/TestEC2Plugin.cs | 8 +++--- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/sdk/src/Core/Plugins/EC2Plugin.cs b/sdk/src/Core/Plugins/EC2Plugin.cs index 19718a2b..cc2f5bc4 100644 --- a/sdk/src/Core/Plugins/EC2Plugin.cs +++ b/sdk/src/Core/Plugins/EC2Plugin.cs @@ -17,9 +17,10 @@ using System; using System.Collections.Generic; -using System.Linq; +using System.IO; +using System.Net; using System.Net.Http; -using System.Threading.Tasks; +using System.Text; using Amazon.Runtime.Internal.Util; using ThirdParty.LitJson; @@ -31,7 +32,6 @@ namespace Amazon.XRay.Recorder.Core.Plugins public class EC2Plugin : IPlugin { private static readonly Logger _logger = Logger.GetLogger(typeof(EC2Plugin)); - private readonly HttpClient _client = new HttpClient(); const string metadata_base_url = "http://169.254.169.254/latest/"; /// @@ -87,7 +87,7 @@ private string GetToken() { Dictionary header = new Dictionary(1); header.Add("X-aws-ec2-metadata-token-ttl-seconds", "60"); - token = DoRequest(metadata_base_url + "api/token", HttpMethod.Put, header).Result; + token = DoRequest(metadata_base_url + "api/token", HttpMethod.Put, header); } catch (Exception) { @@ -109,7 +109,7 @@ private IDictionary GetMetadata(string token) headers.Add("X-aws-ec2-metadata-token", token); } string identity_doc_url = metadata_base_url + "dynamic/instance-identity/document"; - string doc_string = DoRequest(identity_doc_url, HttpMethod.Get, headers).Result; + string doc_string = DoRequest(identity_doc_url, HttpMethod.Get, headers); return ParseMetadata(doc_string); } catch (Exception) @@ -120,26 +120,34 @@ private IDictionary GetMetadata(string token) } - protected virtual async Task DoRequest(string url, HttpMethod method, Dictionary headers = null) + protected virtual string DoRequest(string url, HttpMethod method, Dictionary headers = null) { - HttpRequestMessage request = new HttpRequestMessage(method, url); + var httpWebRequest = WebRequest.CreateHttp(url); + + httpWebRequest.Timeout = 2000; // 2 seconds timeout + httpWebRequest.Method = method.Method; + if (headers != null) { foreach (var item in headers) { - request.Headers.Add(item.Key, item.Value); + httpWebRequest.Headers.Add(item.Key, item.Value); } } - _client.Timeout = TimeSpan.FromSeconds(2); // 2 seconds timeout - HttpResponseMessage response = await _client.SendAsync(request); - if (response.IsSuccessStatusCode) + using(var response = (HttpWebResponse)httpWebRequest.GetResponse()) { - return await response.Content.ReadAsStringAsync(); - } - else - { - throw new Exception("Unable to complete the request successfully"); + if (response.StatusCode < HttpStatusCode.OK || (int)response.StatusCode > 299) + { + throw new Exception("Unable to complete the request successfully"); + } + + var encoding = Encoding.GetEncoding(response.ContentEncoding); + + using (var streamReader = new StreamReader(response.GetResponseStream(), encoding)) + { + return streamReader.ReadToEnd(); + } } } diff --git a/sdk/test/UnitTests/TestEC2Plugin.cs b/sdk/test/UnitTests/TestEC2Plugin.cs index e8757ffe..dbf746c5 100644 --- a/sdk/test/UnitTests/TestEC2Plugin.cs +++ b/sdk/test/UnitTests/TestEC2Plugin.cs @@ -119,7 +119,7 @@ public MockEC2Plugin(bool failV1, bool failV2) _failV2 = failV2; } - protected override Task DoRequest(string url, HttpMethod method, Dictionary headers = null) + protected override string DoRequest(string url, HttpMethod method, Dictionary headers = null) { if (_failV2 && url == "http://169.254.169.254/latest/api/token") { @@ -127,7 +127,7 @@ protected override Task DoRequest(string url, HttpMethod method, Diction } else if (!_failV2 && url == "http://169.254.169.254/latest/api/token") { - return Task.FromResult("dummyTokenfromferg"); + return "dummyTokenfromferg"; } else if (_failV1) { @@ -138,12 +138,12 @@ protected override Task DoRequest(string url, HttpMethod method, Diction if (headers == null) // for v1 endpoint request { meta_string = "{\"availabilityZone\" : \"us-west-2a\", \"imageId\" : \"ami-03cca83dd001d4d11\", \"instanceId\" : \"i-07a181803de94c477\", \"instanceType\" : \"t2.xlarge\"}"; - return Task.FromResult(meta_string); + return meta_string; } else { // for v2 endpoint meta_string = "{\"availabilityZone\" : \"us-east-2a\", \"imageId\" : \"ami-03cca83dd001d4666\", \"instanceId\" : \"i-07a181803de94c666\", \"instanceType\" : \"t3.xlarge\"}"; - return Task.FromResult(meta_string); + return meta_string; } } From 2d9c99a588b8796ae85566e3c4a6cc5d57048929 Mon Sep 17 00:00:00 2001 From: Jon Armen Date: Thu, 17 Mar 2022 19:51:22 -0400 Subject: [PATCH 37/37] Adding 3.x for continous build --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88dc0afc..0d098c9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,9 +4,11 @@ on: push: branches: - master + - 3.x pull_request: branches: - master + - 3.x jobs: build-test: