diff --git a/Directory.Build.props b/Directory.Build.props index fef9d781511..7e4dc9ad808 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,6 @@ - diff --git a/Directory.Build.targets b/Directory.Build.targets index 5ee66133050..5fcf797523c 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -8,8 +8,6 @@ - - $(MSBuildWarningsAsMessages);NETSDK1138;MSB3270 diff --git a/eng/Net9Workarounds.props b/eng/Net9Workarounds.props deleted file mode 100644 index 676bad31897..00000000000 --- a/eng/Net9Workarounds.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - false - true - - \ No newline at end of file diff --git a/eng/Net9Workarounds.targets b/eng/Net9Workarounds.targets deleted file mode 100644 index c92595dd496..00000000000 --- a/eng/Net9Workarounds.targets +++ /dev/null @@ -1,67 +0,0 @@ - - - - 99.9 - - true - - - - - - - - - - $(MicrosoftNETCoreAppRuntimewinx64Version) - $(MicrosoftNETCoreAppRefVersion) - - $(MicrosoftNETCoreAppRuntimeVersion) - - - - $(MicrosoftAspNetCoreAppRuntimewinx64Version) - $(MicrosoftAspNetCoreAppRefVersion) - - $(MicrosoftNETCoreAppRuntimeVersion) - - - - $(MicrosoftNETCoreAppRuntimewinx64Version) - - - - $(MicrosoftNETCoreAppRuntimewinx64Version) - - - - $(MicrosoftAspNetCoreAppRuntimewinx64Version) - - - - \ No newline at end of file diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2d806523a16..e4dcd0226ff 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -170,13 +170,13 @@ - + https://github.com/dotnet/arcade - 04b9022eba9c184a8036328af513c22e6949e8b6 + 1230437de1ab7b3e15fe7cdfe7ffce2f65449959 - + https://github.com/dotnet/arcade - 04b9022eba9c184a8036328af513c22e6949e8b6 + 1230437de1ab7b3e15fe7cdfe7ffce2f65449959 diff --git a/eng/Versions.props b/eng/Versions.props index e5209b4f90b..0d718b9059b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,11 +8,10 @@ $(MajorVersion).$(MinorVersion).$(PatchVersion) true $(MajorVersion).$(MinorVersion).0.0 - true - false + true diff --git a/github-merge-flow.jsonc b/github-merge-flow.jsonc index 2045a8a6989..3071846fbe1 100644 --- a/github-merge-flow.jsonc +++ b/github-merge-flow.jsonc @@ -2,9 +2,10 @@ { "merge-flow-configurations": { // Automate opening PRs to merge extensions main branch back to dev - "main":{ - "MergeToBranch": "dev", - "ExtraSwitches": "-QuietComments" - } + // Disable this for now as dev branch has been merged to main + // "main":{ + // "MergeToBranch": "dev", + // "ExtraSwitches": "-QuietComments" + // } } } \ No newline at end of file diff --git a/global.json b/global.json index 9ace0177b48..bffeb4e2565 100644 --- a/global.json +++ b/global.json @@ -1,9 +1,9 @@ { "sdk": { - "version": "9.0.100-rc.2.24468.2" + "version": "9.0.100-rtm.24479.2" }, "tools": { - "dotnet": "9.0.100-rc.2.24468.2", + "dotnet": "9.0.100-rtm.24479.2", "runtimes": { "dotnet/x64": [ "8.0.0", @@ -18,7 +18,7 @@ "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.2.0", - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24466.2", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24466.2" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24473.1", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24473.1" } } diff --git a/src/Libraries/Microsoft.Extensions.Compliance.Redaction/Microsoft.Extensions.Compliance.Redaction.csproj b/src/Libraries/Microsoft.Extensions.Compliance.Redaction/Microsoft.Extensions.Compliance.Redaction.csproj index 8a6a526acc1..d331d10ff32 100644 --- a/src/Libraries/Microsoft.Extensions.Compliance.Redaction/Microsoft.Extensions.Compliance.Redaction.csproj +++ b/src/Libraries/Microsoft.Extensions.Compliance.Redaction/Microsoft.Extensions.Compliance.Redaction.csproj @@ -7,12 +7,15 @@ true - true true true true true true + + + false + $(NoWarn);IL2026 diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/Hedging/Internals/RequestMessageSnapshotStrategy.cs b/src/Libraries/Microsoft.Extensions.Http.Resilience/Hedging/Internals/RequestMessageSnapshotStrategy.cs index 8f484f1cbcd..9b4fe7e9c8d 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Resilience/Hedging/Internals/RequestMessageSnapshotStrategy.cs +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/Hedging/Internals/RequestMessageSnapshotStrategy.cs @@ -20,7 +20,9 @@ protected override async ValueTask> ExecuteCore RequestMessage = new("Resilience.Http.RequestMessage"); + public static readonly ResiliencePropertyKey RequestMessage = new("Resilience.Http.RequestMessage"); public static readonly ResiliencePropertyKey RoutingStrategy = new("Resilience.Http.RequestRoutingStrategy"); diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/Resilience/HttpResilienceContextExtensions.cs b/src/Libraries/Microsoft.Extensions.Http.Resilience/Resilience/HttpResilienceContextExtensions.cs new file mode 100644 index 00000000000..b04bd37a2ad --- /dev/null +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/Resilience/HttpResilienceContextExtensions.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Net.Http; +using Microsoft.Extensions.Http.Resilience.Internal; +using Microsoft.Shared.DiagnosticIds; +using Microsoft.Shared.Diagnostics; +using Polly; + +namespace Polly; + +/// +/// Provides utility methods for working with . +/// +[Experimental(diagnosticId: DiagnosticIds.Experiments.Resilience, UrlFormat = DiagnosticIds.UrlFormat)] +public static class HttpResilienceContextExtensions +{ + /// + /// Gets the request message from the . + /// + /// The resilience context. + /// + /// The request message. + /// If the request message is not present in the the method returns . + /// + /// is . + public static HttpRequestMessage? GetRequestMessage(this ResilienceContext context) + { + _ = Throw.IfNull(context); + return context.Properties.GetValue(ResilienceKeys.RequestMessage, default); + } + + /// + /// Sets the request message on the . + /// + /// The resilience context. + /// The request message. + /// is . + public static void SetRequestMessage(this ResilienceContext context, HttpRequestMessage? requestMessage) + { + _ = Throw.IfNull(context); + context.Properties.Set(ResilienceKeys.RequestMessage, requestMessage); + } +} diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/Resilience/ResilienceHandler.cs b/src/Libraries/Microsoft.Extensions.Http.Resilience/Resilience/ResilienceHandler.cs index 41a408fa718..aff82260365 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Resilience/Resilience/ResilienceHandler.cs +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/Resilience/ResilienceHandler.cs @@ -58,7 +58,7 @@ protected override async Task SendAsync(HttpRequestMessage ResilienceContext context = GetOrSetResilienceContext(request, cancellationToken, out bool created); TrySetRequestMetadata(context, request); - SetRequestMessage(context, request); + context.SetRequestMessage(request); try { @@ -117,7 +117,7 @@ protected override HttpResponseMessage Send(HttpRequestMessage request, Cancella ResilienceContext context = GetOrSetResilienceContext(request, cancellationToken, out bool created); TrySetRequestMetadata(context, request); - SetRequestMessage(context, request); + context.SetRequestMessage(request); try { @@ -165,11 +165,8 @@ private static void TrySetRequestMetadata(ResilienceContext context, HttpRequest } } - private static void SetRequestMessage(ResilienceContext context, HttpRequestMessage request) - => context.Properties.Set(ResilienceKeys.RequestMessage, request); - private static HttpRequestMessage GetRequestMessage(ResilienceContext context, HttpRequestMessage request) - => context.Properties.GetValue(ResilienceKeys.RequestMessage, request); + => context.GetRequestMessage() ?? request; private static void RestoreResilienceContext(ResilienceContext context, HttpRequestMessage request, bool created) { diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/Routing/Internal/RoutingResilienceStrategy.cs b/src/Libraries/Microsoft.Extensions.Http.Resilience/Routing/Internal/RoutingResilienceStrategy.cs index 0aefc6cf171..2054cbcccbc 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Resilience/Routing/Internal/RoutingResilienceStrategy.cs +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/Routing/Internal/RoutingResilienceStrategy.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Net.Http; using System.Threading.Tasks; using Microsoft.Extensions.Http.Resilience.Internal; using Microsoft.Shared.Diagnostics; @@ -26,7 +27,9 @@ protected override async ValueTask> ExecuteCore @@ -39,5 +39,15 @@ public void ExecuteAsync_RequestMessageNotFound_Throws() strategy.Invoking(s => s.Execute(() => { })).Should().Throw(); } + [Fact] + public void ExecuteAsync_RequestMessageIsNull_Throws() + { + var strategy = Create(); + var context = ResilienceContextPool.Shared.Get(); + context.SetRequestMessage(null); + + strategy.Invoking(s => s.Execute(_ => { }, context)).Should().Throw(); + } + private static ResiliencePipeline Create() => new ResiliencePipelineBuilder().AddStrategy(_ => new RequestMessageSnapshotStrategy(), Mock.Of()).Build(); } diff --git a/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/HttpResilienceContextExtensionsTests.cs b/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/HttpResilienceContextExtensionsTests.cs new file mode 100644 index 00000000000..9cd1255c992 --- /dev/null +++ b/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/HttpResilienceContextExtensionsTests.cs @@ -0,0 +1,77 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Net.Http; +using Microsoft.Extensions.Http.Resilience.Internal; +using Polly; +using Xunit; + +namespace Microsoft.Extensions.Http.Resilience.Test.Resilience; + +public class HttpResilienceContextExtensionsTests +{ + [Fact] + public void GetRequestMessage_ResilienceContextIsNull_Throws() + { + ResilienceContext context = null!; + Assert.Throws(context.GetRequestMessage); + } + + [Fact] + public void GetRequestMessage_RequestMessageIsMissing_ReturnsNull() + { + var context = ResilienceContextPool.Shared.Get(); + + Assert.Null(context.GetRequestMessage()); + } + + [Fact] + public void GetRequestMessage_RequestMessageIsNull_ReturnsNull() + { + var context = ResilienceContextPool.Shared.Get(); + context.Properties.Set(ResilienceKeys.RequestMessage, null); + + Assert.Null(context.GetRequestMessage()); + } + + [Fact] + public void GetRequestMessage_RequestMessageIsPresent_ReturnsRequestMessage() + { + var context = ResilienceContextPool.Shared.Get(); + using var request = new HttpRequestMessage(); + context.Properties.Set(ResilienceKeys.RequestMessage, request); + + Assert.Same(request, context.GetRequestMessage()); + } + + [Fact] + public void SetRequestMessage_ResilienceContextIsNull_Throws() + { + ResilienceContext context = null!; + using var request = new HttpRequestMessage(); + + Assert.Throws(() => context.SetRequestMessage(request)); + } + + [Fact] + public void SetRequestMessage_RequestMessageIsNull_SetsNullRequestMessage() + { + var context = ResilienceContextPool.Shared.Get(); + context.SetRequestMessage(null); + + Assert.True(context.Properties.TryGetValue(ResilienceKeys.RequestMessage, out HttpRequestMessage? request)); + Assert.Null(request); + } + + [Fact] + public void SetRequestMessage_RequestMessageIsNotNull_SetsRequestMessage() + { + var context = ResilienceContextPool.Shared.Get(); + using var request = new HttpRequestMessage(); + context.SetRequestMessage(request); + + Assert.True(context.Properties.TryGetValue(ResilienceKeys.RequestMessage, out HttpRequestMessage? actualRequest)); + Assert.Same(request, actualRequest); + } +} diff --git a/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/ResilienceHandlerTest.cs b/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/ResilienceHandlerTest.cs index 8a1831d67b8..9de72555401 100644 --- a/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/ResilienceHandlerTest.cs +++ b/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Resilience/ResilienceHandlerTest.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; using FluentAssertions; using Microsoft.Extensions.Http.Diagnostics; -using Microsoft.Extensions.Http.Resilience.Internal; using Microsoft.Extensions.Http.Resilience.Test.Helpers; using Polly; using Xunit; @@ -108,7 +107,7 @@ public async Task Send_EnsureInvoker(bool executionContextSet, bool asynchronous handler.InnerHandler = new TestHandlerStub((r, _) => { r.GetResilienceContext().Should().NotBeNull(); - r.GetResilienceContext()!.Properties.GetValue(ResilienceKeys.RequestMessage, null!).Should().BeSameAs(r); + r.GetResilienceContext()!.GetRequestMessage().Should().BeSameAs(r); return Task.FromResult(new HttpResponseMessage { StatusCode = HttpStatusCode.Created }); }); diff --git a/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Routing/RoutingResilienceStrategyTests.cs b/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Routing/RoutingResilienceStrategyTests.cs index 341d32087f8..ed1a6d5c6b2 100644 --- a/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Routing/RoutingResilienceStrategyTests.cs +++ b/test/Libraries/Microsoft.Extensions.Http.Resilience.Tests/Routing/RoutingResilienceStrategyTests.cs @@ -4,7 +4,6 @@ using System; using System.Net.Http; using FluentAssertions; -using Microsoft.Extensions.Http.Resilience.Internal; using Microsoft.Extensions.Http.Resilience.Routing.Internal; using Moq; using Polly; @@ -22,6 +21,16 @@ public void NoRequestMessage_Throws() strategy.Invoking(s => s.Execute(() => { })).Should().Throw().WithMessage("The HTTP request message was not found in the resilience context."); } + [Fact] + public void RequestMessageIsNull_Throws() + { + var strategy = Create(() => Mock.Of()); + var context = ResilienceContextPool.Shared.Get(); + context.SetRequestMessage(null); + + strategy.Invoking(s => s.Execute(_ => { }, context)).Should().Throw().WithMessage("The HTTP request message was not found in the resilience context."); + } + [Fact] public void NoRoutingProvider_Ok() { @@ -29,7 +38,7 @@ public void NoRoutingProvider_Ok() var strategy = Create(null); var context = ResilienceContextPool.Shared.Get(); - context.Properties.Set(ResilienceKeys.RequestMessage, request); + context.SetRequestMessage(request); strategy.Invoking(s => s.Execute(_ => { }, context)).Should().NotThrow(); }