From 2f2a7f5a32b34dd5694768ac2c7a4dcd2e424207 Mon Sep 17 00:00:00 2001 From: Scott Kearney <=> Date: Wed, 7 Aug 2024 14:23:22 -0400 Subject: [PATCH 1/4] fix: Check that x-ms-request-id header exists before accessing value. If no value is found, getFirstHeader returns null. Accessing getValue throws an error. --- .../objectmodel/utilities/network/CdmHttpClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/objectModel/Java/objectmodel/src/main/java/com/microsoft/commondatamodel/objectmodel/utilities/network/CdmHttpClient.java b/objectModel/Java/objectmodel/src/main/java/com/microsoft/commondatamodel/objectmodel/utilities/network/CdmHttpClient.java index da7842a57..9c32f9968 100644 --- a/objectModel/Java/objectmodel/src/main/java/com/microsoft/commondatamodel/objectmodel/utilities/network/CdmHttpClient.java +++ b/objectModel/Java/objectmodel/src/main/java/com/microsoft/commondatamodel/objectmodel/utilities/network/CdmHttpClient.java @@ -174,7 +174,7 @@ private CdmHttpResponse sendAsyncHelper(final CdmHttpRequest cdmHttpRequest, final Instant endTime = java.time.Instant.now(); Logger.info(ctx, TAG, "sendAsyncHelper", null, Logger.format("Response for request id: {0}, elapsed time: {1} ms, content length: {2}, status code: {3}.", - response.getFirstHeader("x-ms-request-id").getValue(), + response.getFirstHeader("x-ms-request-id") != null ? response.getFirstHeader("x-ms-request-id").getValue() : "", Duration.between(startTime, endTime).toMillis(), response.getEntity() != null ? response.getEntity().getContentLength() : "", response.getStatusLine() != null ? response.getStatusLine().getStatusCode() : "" From 65652ded879ed92f60c971bfe929c75fe588a3e5 Mon Sep 17 00:00:00 2001 From: Scott Kearney <=> Date: Wed, 7 Aug 2024 14:23:30 -0400 Subject: [PATCH 2/4] fix: Check that x-ms-request-id header exists before accessing value. If no value is found, GetValues returns null. Accessing FirstOrDefault throws an error. --- .../Utilities/Network/CdmHttpClient.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel/Utilities/Network/CdmHttpClient.cs b/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel/Utilities/Network/CdmHttpClient.cs index f13444a59..b3c2fb7b3 100644 --- a/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel/Utilities/Network/CdmHttpClient.cs +++ b/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel/Utilities/Network/CdmHttpClient.cs @@ -177,7 +177,13 @@ private async Task SendAsyncHelper(CdmHttpRequest cdmRequest, C { contentLength = response.Content.Headers.ContentLength.ToString(); } - string adlsRequestId = response?.Headers.GetValues("x-ms-request-id").FirstOrDefault(); + + string adlsRequestId = string.Empty; + if (response?.Content.Headers.Contains("x-ms-request-id") == true) + { + adlsRequestId = response?.Headers.GetValues("x-ms-request-id").FirstOrDefault(); + } + Logger.Info(ctx, Tag, nameof(SendAsyncHelper), null, $"Response for request id: {adlsRequestId}, elapsed time: {endTime.Subtract(startTime).TotalMilliseconds} ms, content length: {contentLength}, status code: {response.StatusCode}."); } From d889a074c7ac755972153cfef14273c555682b1e Mon Sep 17 00:00:00 2001 From: Scott Kearney <=> Date: Wed, 7 Aug 2024 15:20:33 -0400 Subject: [PATCH 3/4] fix: Add Moq package to Tests project Moq is referenced in the code, but wasn't defined as a package for the project. --- .../Microsoft.CommonDataModel.ObjectModel.Tests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel.Tests/Microsoft.CommonDataModel.ObjectModel.Tests.csproj b/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel.Tests/Microsoft.CommonDataModel.ObjectModel.Tests.csproj index 3c9050faf..d10ebe692 100644 --- a/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel.Tests/Microsoft.CommonDataModel.ObjectModel.Tests.csproj +++ b/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel.Tests/Microsoft.CommonDataModel.ObjectModel.Tests.csproj @@ -10,6 +10,7 @@ + From 2576032b2ac9b03ddce05782559a995b4ea18cef Mon Sep 17 00:00:00 2001 From: Scott Kearney <=> Date: Wed, 7 Aug 2024 15:22:04 -0400 Subject: [PATCH 4/4] test: Add test for HttpClient to address newly-fixed functionality. Test should run successfully when the x-ms-request-id header null reference is fixed. --- .../Utilities/HttpClient/CdmHttpClientTest.cs | 49 +++++++++++++++++++ .../Input/default.manifest.cdm.json | 11 +++++ 2 files changed, 60 insertions(+) create mode 100644 objectModel/TestData/Utilities/TestHttpClient/Input/default.manifest.cdm.json diff --git a/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel.Tests/Utilities/HttpClient/CdmHttpClientTest.cs b/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel.Tests/Utilities/HttpClient/CdmHttpClientTest.cs index 13e115f75..0bc32e28e 100644 --- a/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel.Tests/Utilities/HttpClient/CdmHttpClientTest.cs +++ b/objectModel/CSharp/Microsoft.CommonDataModel.ObjectModel.Tests/Utilities/HttpClient/CdmHttpClientTest.cs @@ -12,11 +12,35 @@ namespace Microsoft.CommonDataModel.ObjectModel.Tests.Utilities.Network using System.Threading; using System.Threading.Tasks; using FluentAssertions; + using Microsoft.CommonDataModel.ObjectModel.Utilities; + using Microsoft.CommonDataModel.ObjectModel.Cdm; [TestClass] public class CdmHttpClientTest { private int requestsExecutionCounter = 0; + + /// + /// The path between TestDataPath and TestName. + /// + private readonly string testsSubpath = "Utilities"; + + /// + /// Dummy value used for correlation ID testing. + /// + private readonly string DummyCorrelationId = "12345"; + + /// + /// Declare a blackhole callback. We're focusing on event recorder, don't care about output going to the standard log stream. + /// + private readonly EventCallback eventCallback = new EventCallback + { + Invoke = (level, message) => + { + // NOOP + } + }; + private async Task CompleteResponseMethod(HttpRequestMessage request, CancellationToken token) { @@ -77,6 +101,31 @@ public async Task TestResultReturnedFirstTime() } } + /// + /// Testing for a result returned immediatelly when a corpus is defined + /// + [TestMethod] + public async Task TestResultReturnedFirstTimeWithCorpus() + { + CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestHttpClient"); + corpus.SetEventCallback(eventCallback, CdmStatusLevel.Warning, DummyCorrelationId); + + using (var cdmHttpClient = new CdmHttpClient("https://www.example.com", new CdmHttpMessageHandlerStub(CompleteResponseMethod))) + { + var cdmHttpRequest = new CdmHttpRequest("/folder1") + { + Timeout = TimeSpan.FromSeconds(5), + MaximumTimeout = TimeSpan.FromSeconds(9) + }; + + var result = await cdmHttpClient.SendAsync(cdmHttpRequest, null, corpus.Ctx); + + var content = await result.Content.ReadAsStringAsync(); + + Assert.AreEqual("REPLY1", content); + } + } + /// /// Testing for an HTTP exception when a wrong path is provided. /// diff --git a/objectModel/TestData/Utilities/TestHttpClient/Input/default.manifest.cdm.json b/objectModel/TestData/Utilities/TestHttpClient/Input/default.manifest.cdm.json new file mode 100644 index 000000000..8bc1e14c0 --- /dev/null +++ b/objectModel/TestData/Utilities/TestHttpClient/Input/default.manifest.cdm.json @@ -0,0 +1,11 @@ +{ + "manifestName": "default.manifest.cdm.json", + "entities": [], + "jsonSchemaSemanticVersion": "1.0.0", + "imports": [ + { + "corpusPath": "cdm:/foundations.cdm.json", + "moniker": "" + } + ] + } \ No newline at end of file