diff --git a/.circleci/config.yml b/.circleci/config.yml index 4a5f1d936..09178e49c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,13 +4,13 @@ orbs: jobs: build: docker: - - image: mijitt0m/ocelot-build:0.0.9 + - image: ocelot2/circleci-build:8.21.0 steps: - checkout - run: dotnet tool restore && dotnet cake release: docker: - - image: mijitt0m/ocelot-build:0.0.9 + - image: ocelot2/circleci-build:8.21.0 steps: - checkout - run: dotnet tool restore && dotnet cake --target=Release @@ -19,7 +19,7 @@ workflows: main: jobs: - queue/block_workflow: - time: "20" + time: '20' only-on-branch: main - release: requires: @@ -38,6 +38,6 @@ workflows: - build: filters: branches: - ignore: + ignore: - main - develop diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index ce3369c2e..d9c539fb0 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "cake.tool": { - "version": "3.0.0", + "version": "4.0.0", "commands": [ "dotnet-cake" ] @@ -15,4 +15,4 @@ ] } } -} \ No newline at end of file +} diff --git a/.editorconfig b/.editorconfig index 6aa3d30f4..e4e769b52 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,7 +4,12 @@ root = true end_of_line = lf insert_final_newline = true -[*.cs] +[*.cs] end_of_line = lf indent_style = space indent_size = 4 + +# XML files +[*.xml] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore index 220172830..1c30928ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,21 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore # User-specific files +*.rsuser *.suo *.user *.userosscache *.sln.docstates -*.DS_Store + # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +# Mono auto generated files +mono_crash.* + # Build results [Dd]ebug/ [Dd]ebugPublic/ @@ -17,44 +23,62 @@ [Rr]eleases/ x64/ x86/ -build/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ -results/ +[Ll]og/ +[Ll]ogs/ -# Visual Studio 2015 cache/options directory +# Visual Studio 2015/2017 cache/options directory .vs/ -.vscode/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ -site/wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* -# NUNIT +# NUnit *.VisualState.xml TestResult.xml +nunit-*.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c -# DNX +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core project.lock.json +project.fragment.lock.json artifacts/ +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio *_i.c *_p.c -*_i.h +*_h.h *.ilk *.meta *.obj +*.iobj *.pch *.pdb +*.ipdb *.pgc *.pgd *.rsp @@ -64,7 +88,9 @@ artifacts/ *.tlh *.tmp *.tmp_proj +*_wpftmp.csproj *.log +*.tlog *.vspscc *.vssscc .builds @@ -83,6 +109,8 @@ ipch/ *.opensdf *.sdf *.cachefile +*.VC.db +*.VC.VC.opendb # Visual Studio profiler *.psess @@ -90,6 +118,9 @@ ipch/ *.vspx *.sap +# Visual Studio Trace Files +*.e2e + # TFS 2012 Local Workspace $tf/ @@ -101,15 +132,25 @@ _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user -# JustCode is a .NET coding add-in -.JustCode - # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + # NCrunch _NCrunch_* .*crunch*.local.xml @@ -141,19 +182,29 @@ publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings +# Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + # NuGet Packages *.nupkg +# NuGet Symbol Packages +*.snupkg # The packages folder can be ignored because of Package Restore -**/packages/* +**/[Pp]ackages/* # except build/, which is used as an MSBuild target. -!**/packages/build/ +!**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets # Microsoft Azure Build Output csx/ @@ -163,18 +214,20 @@ csx/ ecf/ rcf/ -# Microsoft Azure ApplicationInsights config file -ApplicationInsights.config - -# Windows Store app package directory +# Windows Store app package directories and files AppPackages/ BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache -!*.[Cc]ache/ +!?*.[Cc]ache/ # Others ClientBin/ @@ -182,12 +235,19 @@ ClientBin/ *~ *.dbmdl *.dbproj.schemaview +*.jfm *.pfx -!mycert.pfx *.publishsettings -node_modules/ orleans.codegen.cs +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + # RIA/Silverlight projects Generated_Code/ @@ -198,15 +258,22 @@ _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak # SQL Server files *.mdf *.ldf +*.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ @@ -216,6 +283,7 @@ FakesAssemblies/ # Node.js Tools for Visual Studio .ntvs_analysis.dat +node_modules/ # Visual Studio 6 build log *.plg @@ -223,6 +291,20 @@ FakesAssemblies/ # Visual Studio 6 workspace options file *.opt +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts @@ -233,25 +315,107 @@ _Pvt_Extensions # Paket dependency manager .paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +.idea/ + +# Visual Studio Test Results +# Quick Facts: https://file.org/extension/trx#visualstudiotestresults +# Running automated tests from the command line: https://learn.microsoft.com/en-us/previous-versions/ms182486(v=vs.140) +# Run unit tests with Test Explorer: https://learn.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer +*.trx + +# OCELOT # FAKE - F# Make .fake/ !tools/packages.config tools/ -# MacOS -.DS_Store - # Ocelot acceptance test config test/Ocelot.AcceptanceTests/ocelot.json -# Read the docstates +# Read the Docs +# https://ocelot.readthedocs.io _build/ _static/ _templates/ - -# JetBrains Rider -.idea/ - -# Test Results -*.trx diff --git a/LICENSE.md b/LICENSE.md index d47ecafdf..f81511d45 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,8 +1,8 @@ The MIT License (MIT) -Copyright (c) 2016 Tom Pallister +Copyright (c) 2023 Tom Pallister, Ocelot Core team at ThreeMammals, and GitHub Ocelot community. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Ocelot.sln b/Ocelot.sln index c4abd99a9..1215130de 100644 --- a/Ocelot.sln +++ b/Ocelot.sln @@ -1,7 +1,7 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.6.33723.286 +VisualStudioVersion = 17.8.34309.116 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5CFB79B7-C9DC-45A4-9A75-625D92471702}" EndProject diff --git a/README.md b/README.md index 02385e021..c4d879464 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,8 @@ A quick list of Ocelot's capabilities, for more information see the [Documentati ## Install -Ocelot is designed to work with ASP.NET Core and it targets `net7.0` framework. +Ocelot is designed to work with ASP.NET Core and it targets `net6.0`, `net7.0` and `net8.0` frameworks. [^4] + Install [Ocelot package](https://www.nuget.org/packages/Ocelot) and its dependencies using NuGet Package Manager: ```powershell Install-Package Ocelot @@ -78,7 +79,7 @@ We can also give advice on the easiest way to do things :octocat: Finally, we mark all existing issues as [![label: help wanted][~helpwanted]](https://github.com/ThreeMammals/Ocelot/labels/help%20wanted) [![label: small effort][~smalleffort]](https://github.com/ThreeMammals/Ocelot/labels/small%20effort) [![label: medium effort][~mediumeffort]](https://github.com/ThreeMammals/Ocelot/labels/medium%20effort) -[![label: large effort][~largeeffort]](https://github.com/ThreeMammals/Ocelot/labels/large%20effort) [^4]. +[![label: large effort][~largeeffort]](https://github.com/ThreeMammals/Ocelot/labels/large%20effort). [^5]
If you want to contribute for the first time, we suggest looking at a [![label: help wanted][~helpwanted]](https://github.com/ThreeMammals/Ocelot/labels/help%20wanted) [![label: small effort][~smalleffort]](https://github.com/ThreeMammals/Ocelot/labels/small%20effort) [![label: good first issue][~goodfirstissue]](https://github.com/ThreeMammals/Ocelot/labels/good%20first%20issue) :octocat: @@ -93,4 +94,5 @@ Finally, we mark all existing issues as [![label: help wanted][~helpwanted]](htt [^1]: Ocelot doesn’t directly support [GraphQL](https://graphql.org/). Developers can easily integrate the [GraphQL for .NET](/graphql-dotnet/graphql-dotnet) library. [^2]: Ocelot does support [Consul](https://www.consul.io/), [Netflix Eureka](https://www.nuget.org/packages/Steeltoe.Discovery.Eureka), [Service Fabric](https://azure.microsoft.com/en-us/products/service-fabric/) service discovery providers, and special modes like [Dynamic Routing](/ThreeMammals/Ocelot/blob/main/docs/features/servicediscovery.rst#dynamic-routing) and [Custom Providers](/ThreeMammals/Ocelot/blob/main/docs/features/servicediscovery.rst#custom-providers). [^3]: Retry policies only via [Polly](/App-vNext/Polly) library. -[^4]: See all [labels](https://github.com/ThreeMammals/Ocelot/issues/labels) of the repository. +[^4]: Starting with [v21.0](https://github.com/ThreeMammals/Ocelot/releases/tag/21.0.0), the solution's code base supports [Multitargeting](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-multitargeting-overview) as SDK-style projects. It should be easier for teams to move between (migrate to) .NET 6, 7 and 8 frameworks. Also, new features will be available for all .NET SDKs which we support via multitargeting. Find out more here: [Target frameworks in SDK-style projects](https://learn.microsoft.com/en-us/dotnet/standard/frameworks) +[^5]: See all [labels](https://github.com/ThreeMammals/Ocelot/issues/labels) of the repository. diff --git a/ReleaseNotes.md b/ReleaseNotes.md index af4e302ad..1193d5db1 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,2 +1,17 @@ -## Documentation release {0} for [Polish Apple](https://www.google.com/search?q=Polish+Apple), v{1} -Special thanks to @ggnaegi! +## Upgrade to .NET 8 (version {0}) aka [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) release +> Read article: [Announcing .NET 8](https://devblogs.microsoft.com/dotnet/announcing-dotnet-8/) by Gaurav Seth, on November 14th, 2023 + +### About +We are pleased to announce to you that we can now offer the support of [.NET 8](https://dotnet.microsoft.com/en-us/download). +But that is not all, in this release, we are adopting support of several versions of the .NET framework through [multitargeting](https://learn.microsoft.com/en-us/dotnet/standard/frameworks). +The Ocelot distribution is now compatible with .NET **6**, **7** and **8**. :tada: + +In the future, we will try to ensure the support of the [.NET SDKs](https://dotnet.microsoft.com/en-us/download/dotnet) that are still actively maintained by the .NET team and community. +Current .NET versions in support are the following: [6, 7, 8](https://dotnet.microsoft.com/en-us/download/dotnet). + +### Technical info +As an ASP.NET Core app, now Ocelot targets `net6.0`, `net7.0` and `net8.0` frameworks. + +Starting with **v{0}**, the solution's code base supports [Multitargeting](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-multitargeting-overview) as SDK-style projects. +It should be easier for teams to move between (migrate to) .NET 6, 7 and 8 frameworks. Also, new features will be available for all .NET SDKs which we support via multitargeting. +Find out more here: [Target frameworks in SDK-style projects](https://learn.microsoft.com/en-us/dotnet/standard/frameworks) diff --git a/build.cake b/build.cake index ad510b0ac..75f30a755 100644 --- a/build.cake +++ b/build.cake @@ -2,7 +2,7 @@ #tool "dotnet:?package=coveralls.net&version=4.0.1" #addin nuget:?package=Newtonsoft.Json #addin nuget:?package=System.Text.Encodings.Web&version=4.7.1 -#tool "nuget:?package=ReportGenerator&version=5.1.19" +#tool "nuget:?package=ReportGenerator&version=5.2.0" #addin Cake.Coveralls&version=1.1.0 #r "Spectre.Console" @@ -42,8 +42,9 @@ var benchmarkTestAssemblies = @"./test/Ocelot.Benchmarks"; // packaging var packagesDir = artifactsDir + Directory("Packages"); -var releaseNotesFile = packagesDir + File("ReleaseNotes.md"); var artifactsFile = packagesDir + File("artifacts.txt"); +var releaseNotesFile = packagesDir + File("ReleaseNotes.md"); +var releaseNotes = new List(); // stable releases var tagsUrl = "https://api.github.com/repos/ThreeMammals/ocelot/releases/tags/"; @@ -85,8 +86,8 @@ Task("Release") .IsDependentOn("Build") .IsDependentOn("CreateReleaseNotes") .IsDependentOn("CreateArtifacts") - .IsDependentOn("PublishGitHubRelease"); - // .IsDependentOn("PublishToNuget"); + .IsDependentOn("PublishGitHubRelease") + .IsDependentOn("PublishToNuget"); Task("Compile") .IsDependentOn("Clean") @@ -135,7 +136,7 @@ Task("Version") Task("CreateReleaseNotes") .IsDependentOn("Version") .Does(() => - { + { Information($"Generating release notes at {releaseNotesFile}"); // local helper function @@ -158,7 +159,7 @@ Task("CreateReleaseNotes") var releaseVersion = versioning.NuGetVersion; // Read main header from Git file, substitute version in header, and add content further... var releaseHeader = string.Format(System.IO.File.ReadAllText("./ReleaseNotes.md"), releaseVersion, lastRelease); - var releaseNotes = new List { releaseHeader }; + releaseNotes = new List { releaseHeader }; var shortlogSummary = GitHelper($"shortlog --no-merges --numbered --summary {lastRelease}..HEAD"); var re = new Regex(@"^[\s\t]*(?'commits'\d+)[\s\t]+(?'author'.*)$"); @@ -296,9 +297,9 @@ Task("CreateReleaseNotes") } } } // END of Top 3 - //releaseNotes.Add("### Honoring :medal_sports: aka Top Contributors :clap:"); - //releaseNotes.AddRange(topContributors); - //releaseNotes.Add(""); + releaseNotes.Add("### Honoring :medal_sports: aka Top Contributors :clap:"); + releaseNotes.AddRange(topContributors); + releaseNotes.Add(""); releaseNotes.Add("### Starring :star: aka Release Influencers :bowtie:"); releaseNotes.AddRange(starring); releaseNotes.Add(""); @@ -306,17 +307,26 @@ Task("CreateReleaseNotes") var commitsHistory = GitHelper($"log --no-merges --date=format:\"%A, %B %d at %H:%M\" --pretty=format:\"%h by **%aN** on %ad →%n%s\" {lastRelease}..HEAD"); releaseNotes.AddRange(commitsHistory); - EnsureDirectoryExists(packagesDir); - System.IO.File.WriteAllLines(releaseNotesFile, releaseNotes); + WriteReleaseNotes(); + }); + +private void WriteReleaseNotes() +{ + Information($"RUN {nameof(WriteReleaseNotes)} ..."); - if (string.IsNullOrEmpty(System.IO.File.ReadAllText(releaseNotesFile))) - { - System.IO.File.WriteAllText(releaseNotesFile, "No commits since last release"); - } + EnsureDirectoryExists(packagesDir); + System.IO.File.WriteAllLines(releaseNotesFile, releaseNotes); + + var content = System.IO.File.ReadAllText(releaseNotesFile); + if (string.IsNullOrEmpty(content)) + { + System.IO.File.WriteAllText(releaseNotesFile, "No commits since last release"); + } + + Information($"Release notes are >>>\n{content}<<<"); + Information($"EXITED {nameof(WriteReleaseNotes)}"); +} - Information("Release notes are >>>" + Environment.NewLine + System.IO.File.ReadAllText(releaseNotesFile) + "<<<"); - }); - Task("RunUnitTests") .IsDependentOn("Compile") .Does(() => @@ -407,25 +417,24 @@ Task("CreateArtifacts") .IsDependentOn("Compile") .Does(() => { - EnsureDirectoryExists(packagesDir); - + WriteReleaseNotes(); System.IO.File.AppendAllLines(artifactsFile, new[] { "ReleaseNotes.md" }); - CopyFiles("./ReleaseNotes.md", packagesDir); - - // CopyFiles("./src/**/Release/Ocelot.*.nupkg", packagesDir); - // var projectFiles = GetFiles("./src/**/Release/Ocelot.*.nupkg"); - // foreach(var projectFile in projectFiles) - // { - // System.IO.File.AppendAllLines( - // artifactsFile, - // new[] { projectFile.GetFilename().FullPath } - // ); - // } + + CopyFiles("./src/**/Release/Ocelot.*.nupkg", packagesDir); + var projectFiles = GetFiles("./src/**/Release/Ocelot.*.nupkg"); + foreach(var projectFile in projectFiles) + { + System.IO.File.AppendAllLines( + artifactsFile, + new[] { projectFile.GetFilename().FullPath } + ); + } var artifacts = System.IO.File.ReadAllLines(artifactsFile) .Distinct(); - - foreach(var artifact in artifacts) + + Information($"Listing all {nameof(artifacts)}..."); + foreach (var artifact in artifacts) { var codePackage = packagesDir + File(artifact); if (FileExists(codePackage)) diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index 691339490..49b877c10 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine +FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine RUN apk add bash icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib git openssh-client @@ -6,4 +6,11 @@ RUN curl -L --output ./dotnet-install.sh https://dot.net/v1/dotnet-install.sh RUN chmod u+x ./dotnet-install.sh +# Install .NET 8 SDK (already included in the base image, but listed for consistency) +RUN ./dotnet-install.sh -c 8.0 -i /usr/share/dotnet + +# Install .NET 7 SDK +RUN ./dotnet-install.sh -c 7.0 -i /usr/share/dotnet + +# Install .NET 6 SDK RUN ./dotnet-install.sh -c 6.0 -i /usr/share/dotnet diff --git a/docker/Dockerfile.build b/docker/Dockerfile.build index 5498c6106..51dff57ff 100644 --- a/docker/Dockerfile.build +++ b/docker/Dockerfile.build @@ -1,7 +1,8 @@ # call from ocelot repo root with # docker build --platform linux/arm64 --build-arg OCELOT_COVERALLS_TOKEN=$OCELOT_COVERALLS_TOKEN -f ./docker/Dockerfile.build . # docker build --platform linux/amd64 --build-arg OCELOT_COVERALLS_TOKEN=$OCELOT_COVERALLS_TOKEN -f ./docker/Dockerfile.build . -FROM mijitt0m/ocelot-build:0.0.9 + +FROM ocelot2/circleci-build:8.21.0 ARG OCELOT_COVERALLS_TOKEN @@ -13,4 +14,4 @@ COPY ./. . RUN dotnet tool restore -RUN dotnet cake \ No newline at end of file +RUN dotnet cake diff --git a/docker/Dockerfile.release b/docker/Dockerfile.release index e2659c035..90e2d6ee1 100644 --- a/docker/Dockerfile.release +++ b/docker/Dockerfile.release @@ -1,7 +1,8 @@ # call from ocelot repo root with # docker build --platform linux/arm64 --build-arg OCELOT_COVERALLS_TOKEN=$OCELOT_COVERALLS_TOKEN --build-arg OCELOT_GITHUB_API_KEY=$OCELOT_GITHUB_API_KEY --build-arg OCELOT_COVERALLS_TOKEN=$OCELOT_COVERALLS_TOKEN -f ./docker/Dockerfile.build . # docker build --platform linux/amd64 --build-arg OCELOT_COVERALLS_TOKEN=$OCELOT_COVERALLS_TOKEN --build-arg OCELOT_GITHUB_API_KEY=$OCELOT_GITHUB_API_KEY --build-arg OCELOT_COVERALLS_TOKEN=$OCELOT_COVERALLS_TOKEN -f ./docker/Dockerfile.build . -FROM mijitt0m/ocelot-build:0.0.9 + +FROM ocelot2/circleci-build:8.21.0 ARG OCELOT_COVERALLS_TOKEN ARG OCELOT_NUTGET_API_KEY @@ -17,4 +18,4 @@ COPY ./. . RUN dotnet tool restore -RUN dotnet cake \ No newline at end of file +RUN dotnet cake diff --git a/docker/README.md b/docker/README.md index 3eb46aa42..dcecc224d 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,3 +1,3 @@ # docker build -This folder contains the dockerfile and script to create the ocelot build container. \ No newline at end of file +This folder contains the `Dockerfile.*` and `build.sh` script to create the Ocelot build image & container. diff --git a/docker/build.sh b/docker/build.sh index bf2cee9b5..15d1325ad 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -1,7 +1,11 @@ -# this script build the ocelot docker file -version=0.0.9 -docker build --platform linux/amd64 -t mijitt0m/ocelot-build -f Dockerfile.base . +# This script builds the Ocelot Docker file + +# {DotNetSdkVer}.{OcelotVer} -> {.NET8}.{21.0} -> 8.21.0 +version=8.21.0 +docker build --platform linux/amd64 -t ocelot2/circleci-build -f Dockerfile.base . + echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin -docker tag mijitt0m/ocelot-build mijitt0m/ocelot-build:$version -docker push mijitt0m/ocelot-build:latest -docker push mijitt0m/ocelot-build:$version \ No newline at end of file + +docker tag ocelot2/circleci-build ocelot2/circleci-build:$version +docker push ocelot2/circleci-build:latest +docker push ocelot2/circleci-build:$version diff --git a/docs/building/building.rst b/docs/building/building.rst index ec794e296..5873350b8 100644 --- a/docs/building/building.rst +++ b/docs/building/building.rst @@ -10,4 +10,4 @@ Building * There is a `Makefile `_ to make it easier to call the various targets in `build.cake `_. The scripts are called with **.sh** but can be easily changed to **.ps1** if you are using Windows. -* Alternatively you can build the project in VS2022 with the latest `.NET 7.0 `_ SDK. +* Alternatively you can build the project in VS2022 with the latest `.NET 8.0 `_ SDK. diff --git a/docs/building/releaseprocess.rst b/docs/building/releaseprocess.rst index ada142c39..ba7cff45a 100644 --- a/docs/building/releaseprocess.rst +++ b/docs/building/releaseprocess.rst @@ -10,7 +10,7 @@ Ocelot uses the following process to accept work into the NuGet packages. 1. User creates an issue or picks up an `existing issue `_ in GitHub. An issue can be created by converting `discussion `_ topics if necessary and agreed upon. -2. User creates a fork and branches from this (unless a member of core team, they can just create a branch on the head repo) e.g. ``feature/xxx``, ``bug/xxx`` etc. +2. User creates `a fork `_ and branches from this (unless a member of core team, they can just create a branch on the head repo) e.g. ``feature/xxx``, ``bug/xxx`` etc. It doesn't really matter what the "xxx" is. It might make sense to use the issue number and maybe a short description. 3. When the contributor is happy with their work they can create a pull request against **develop** in GitHub with their changes. diff --git a/docs/conf.py b/docs/conf.py index c8dbe77bd..8bd28ecbf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,8 +8,8 @@ project = 'Ocelot' copyright = ' 2023 ThreeMammals Ocelot team' -author = 'Tom Pallister, Ocelot Core team at ThreeMammals and Ocelot GitHub community' -release = '20.0.0' +author = 'Tom Pallister, Ocelot Core team at ThreeMammals' +release = '21.0' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration @@ -19,8 +19,6 @@ templates_path = ['_templates'] exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - - # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output diff --git a/docs/features/configuration.rst b/docs/features/configuration.rst index feec24721..589c4a0b0 100644 --- a/docs/features/configuration.rst +++ b/docs/features/configuration.rst @@ -94,7 +94,7 @@ to you: Ocelot will now use the environment specific configuration and fall back to **ocelot.json** if there isn't one. You also need to set the corresponding environment variable which is ``ASPNETCORE_ENVIRONMENT``. -More info on this can be found in the ASP.NET Core docs: `Use multiple environments in ASP.NET Core `_. +More info on this can be found in the ASP.NET Core docs: `Use multiple environments in ASP.NET Core `_. Merging Configuration Files --------------------------- diff --git a/docs/features/dependencyinjection.rst b/docs/features/dependencyinjection.rst index 711340efc..9dbd9b2be 100644 --- a/docs/features/dependencyinjection.rst +++ b/docs/features/dependencyinjection.rst @@ -108,7 +108,7 @@ It gives you full control on design and buiding of Ocelot pipeline, but be caref Warning! Most of services from minimal part of the pipeline should be reused, but only a few of services could be removed. Warning!! The method above is called after adding required services of ASP.NET MVC pipeline building by -`AddMvcCore `_ method +`AddMvcCore `_ method over the ``Services`` property in upper calling context. These services are absolute minimum core services for ASP.NET MVC pipeline. They must be added to DI container always, and they are added implicitly before calling of the method by caller in upper context. So, ``AddMvcCore`` creates an ``IMvcCoreBuilder`` object with its assignment to the ``MvcCoreBuilder`` property. @@ -124,13 +124,13 @@ The Problem ^^^^^^^^^^^ The default `AddOcelot <#the-addocelot-method>`_ method adds -`Newtonsoft JSON `_ services +`Newtonsoft JSON `_ services by the ``AddNewtonsoftJson`` extension method in default builder (the `AddDefaultAspNetServices <#the-adddefaultaspnetservices-method>`_ method). The ``AddNewtonsoftJson`` method calling was introduced in old .NET and Ocelot releases which was necessary when Microsoft did not launch the ``System.Text.Json`` library, but now it affects normal use, so we have an intention to solve the problem. -Modern `JSON services `_ -out of `the box `_ +Modern `JSON services `_ +out of `the box `_ will help to configure JSON settings by the ``JsonSerializerOptions`` property for JSON formatters during (de)serialization. Solution diff --git a/docs/features/logging.rst b/docs/features/logging.rst index 36572f778..979b16145 100644 --- a/docs/features/logging.rst +++ b/docs/features/logging.rst @@ -2,7 +2,7 @@ Logging ======= Ocelot uses the standard logging interfaces ``ILoggerFactory`` and ``ILogger`` at the moment. -This is encapsulated in ``IOcelotLogger`` and ``IOcelotLoggerFactory`` with an implementation for the standard `ASP.NET Core logging `_ stuff at the moment. +This is encapsulated in ``IOcelotLogger`` and ``IOcelotLoggerFactory`` with an implementation for the standard `ASP.NET Core logging `_ stuff at the moment. This is because Ocelot adds some extra info to the logs such as **request ID** if it is configured. There is a global `error handler middleware `_ that should catch any exceptions thrown and log them as errors. @@ -16,8 +16,8 @@ Nicely onto the next feature. Warning ------- -If you are logging to `Console `_, you will get terrible performance. -The team has had so many issues about performance issues with Ocelot and it is always logging level **Debug**, logging to `Console `_. +If you are logging to `Console `_, you will get terrible performance. +The team has had so many issues about performance issues with Ocelot and it is always logging level **Debug**, logging to `Console `_. * **Warning!** Make sure you are logging to something proper in production environment! * Use **Error** and **Critical** levels in production environment! diff --git a/docs/features/middlewareinjection.rst b/docs/features/middlewareinjection.rst index bf0ac2152..d1ee78478 100644 --- a/docs/features/middlewareinjection.rst +++ b/docs/features/middlewareinjection.rst @@ -38,7 +38,7 @@ So, the next called middlewares **will not** affect Ocelot configuration. ASP.NET Core Middlewares and Ocelot Pipeline Builder ---------------------------------------------------- -Ocelot pipeline is a part of entire `ASP.NET Core Middlewares `_ conveyor aka app pipeline. +Ocelot pipeline is a part of entire `ASP.NET Core Middlewares `_ conveyor aka app pipeline. The `BuildOcelotPipeline `_ method encapsulates Ocelot pipeline. The last middleware in the ``BuildOcelotPipeline`` method is ``HttpRequesterMiddleware`` that calls the next middleware, if added to the pipeline. diff --git a/docs/features/ratelimiting.rst b/docs/features/ratelimiting.rst index e0cf56690..9a69f4ded 100644 --- a/docs/features/ratelimiting.rst +++ b/docs/features/ratelimiting.rst @@ -57,9 +57,9 @@ There is no decision at the moment, and the old version of the feature is includ See more about new feature being added into ASP.NET Core 7.0 release: -* `RateLimiter Class `_, since ASP.NET Core **7.0** +* `RateLimiter Class `_, since ASP.NET Core **7.0** * `System.Threading.RateLimiting `_ NuGet package -* `Rate limiting middleware in ASP.NET Core `_ article by Arvin Kahbazi, Maarten Balliauw, and Rick Anderson +* `Rate limiting middleware in ASP.NET Core `_ article by Arvin Kahbazi, Maarten Balliauw, and Rick Anderson However, it makes sense to keep the old implementation as a Ocelot built-in native feature, but we are going to migrate to the new Rate Limiter from ``Microsoft.AspNetCore.RateLimiting`` namespace. diff --git a/docs/features/websockets.rst b/docs/features/websockets.rst index 8dfc23321..5e1e4fc54 100644 --- a/docs/features/websockets.rst +++ b/docs/features/websockets.rst @@ -38,7 +38,7 @@ Links * WHATWG: `WebSockets Standard `_ * Mozilla Developer Network: `The WebSocket API (WebSockets) `_ -* Microsoft Learn: `WebSockets support in ASP.NET Core `_ +* Microsoft Learn: `WebSockets support in ASP.NET Core `_ * Microsoft Learn: `WebSockets support in .NET `_ SignalR @@ -65,10 +65,10 @@ So, SignalR is `the part -More information on framework compatibility can be found in instrictions: `Use ASP.NET Core APIs in a class library `_. +More information on framework compatibility can be found in instrictions: `Use ASP.NET Core APIs in a class library `_. **Second**, you need to tell your application to use *SignalR*. -Complete reference is here: `ASP.NET Core SignalR configuration `_ +Complete reference is here: `ASP.NET Core SignalR configuration `_ .. code-block:: csharp @@ -79,7 +79,7 @@ Complete reference is here: `ASP.NET Core SignalR configuration `_ to allow *WebSockets* connections. +so `configure allowed transports `_ to allow *WebSockets* connections. **Then** in your **ocelot.json** add the following to proxy a Route using SignalR. Note normal Ocelot routing rules apply the main thing is the scheme which is set to ``ws``. diff --git a/docs/index.rst b/docs/index.rst index 38d6c0a87..3ec283703 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,4 +1,4 @@ -Welcome to Ocelot 20.0 +Welcome to Ocelot 21.0 ====================== Thanks for taking a look at the Ocelot documentation! Please use the left hand navigation to get around. diff --git a/docs/introduction/gettingstarted.rst b/docs/introduction/gettingstarted.rst index efe296971..333261992 100644 --- a/docs/introduction/gettingstarted.rst +++ b/docs/introduction/gettingstarted.rst @@ -1,16 +1,16 @@ Getting Started =============== -Ocelot is designed to work with ASP.NET and is currently on ``net7.0`` framework. +Ocelot is designed to work with ASP.NET and is currently on ``net6.0``, ``net7.0`` and ``net8.0`` frameworks. -.NET 7.0 +.NET 8.0 -------- Install NuGet package ^^^^^^^^^^^^^^^^^^^^^ Install Ocelot and it's dependencies using `NuGet `_. -You will need to create a `ASP.NET Core 7.0 project `_ and bring the package into it. +You will need to create a `ASP.NET Core minimal API project `_ and bring the package into it. Then follow the startup below and :doc:`../features/configuration` sections to get up and running. .. code-block:: powershell diff --git a/docs/introduction/gotchas.rst b/docs/introduction/gotchas.rst index e62e1eedb..9a8f856ae 100644 --- a/docs/introduction/gotchas.rst +++ b/docs/introduction/gotchas.rst @@ -4,14 +4,14 @@ Gotchas IIS ----- - Microsoft Learn: `Host ASP.NET Core on Windows with IIS `_ + Microsoft Learn: `Host ASP.NET Core on Windows with IIS `_ We do not recommend to deploy Ocelot app to IIS environments, but if you do, keep in mind the gotchas below. * When using ASP.NET Core 2.2+ and you want to use In-Process hosting, replace ``UseIISIntegration()`` with ``UseIIS()``, otherwise you will get startup errors. * Make sure you use Out-of-process hosting model instead of In-process one - (see `Out-of-process hosting with IIS and ASP.NET Core `_), + (see `Out-of-process hosting with IIS and ASP.NET Core `_), otherwise you will get very slow responses (see `1657 `_). * Ensure all DNS servers of all downstream hosts are online and they function perfectly, otherwise you will get slow responses (see `1630 `_). diff --git a/samples/AdministrationApi/AdministrationApi.csproj b/samples/AdministrationApi/AdministrationApi.csproj index 691f6bb63..cd995c774 100644 --- a/samples/AdministrationApi/AdministrationApi.csproj +++ b/samples/AdministrationApi/AdministrationApi.csproj @@ -1,6 +1,6 @@  - net7.0 + net6.0;net7.0;net8.0 disable disable @@ -8,8 +8,7 @@ - - - + + diff --git a/samples/OcelotBasic/Ocelot.Samples.OcelotBasic.ApiGateway.csproj b/samples/OcelotBasic/Ocelot.Samples.OcelotBasic.ApiGateway.csproj index 41ad8deb6..9e381bb17 100644 --- a/samples/OcelotBasic/Ocelot.Samples.OcelotBasic.ApiGateway.csproj +++ b/samples/OcelotBasic/Ocelot.Samples.OcelotBasic.ApiGateway.csproj @@ -1,18 +1,14 @@  - - net7.0 + net6.0;net7.0;net8.0 disable disable InProcess - - - diff --git a/samples/OcelotEureka/ApiGateway/ApiGateway.csproj b/samples/OcelotEureka/ApiGateway/ApiGateway.csproj index 90f81c521..a41f67537 100644 --- a/samples/OcelotEureka/ApiGateway/ApiGateway.csproj +++ b/samples/OcelotEureka/ApiGateway/ApiGateway.csproj @@ -1,25 +1,20 @@ - - - - net7.0 - disable - disable - - - - - - - - - PreserveNewest - - - - - - - - - - + + + net6.0;net7.0;net8.0 + disable + disable + + + + + + + PreserveNewest + + + + + + + + diff --git a/samples/OcelotEureka/DownstreamService/DownstreamService.csproj b/samples/OcelotEureka/DownstreamService/DownstreamService.csproj index 73f006405..e0d47d1c9 100644 --- a/samples/OcelotEureka/DownstreamService/DownstreamService.csproj +++ b/samples/OcelotEureka/DownstreamService/DownstreamService.csproj @@ -1,21 +1,16 @@ - - - - net7.0 - disable - disable - - - - - - - - - - - - - - - + + + net6.0;net7.0;net8.0 + disable + disable + + + + + + + + + + + diff --git a/samples/OcelotGraphQL/OcelotGraphQL.csproj b/samples/OcelotGraphQL/OcelotGraphQL.csproj index 6a7658f30..32039beba 100644 --- a/samples/OcelotGraphQL/OcelotGraphQL.csproj +++ b/samples/OcelotGraphQL/OcelotGraphQL.csproj @@ -1,19 +1,21 @@ - - - net7.0 - disable - disable - - - - PreserveNewest - - - - - - - - - + + + net6.0;net7.0;net8.0 + disable + disable + + + + + + + PreserveNewest + + + + + + + + diff --git a/samples/OcelotKube/ApiGateway/Ocelot.Samples.OcelotKube.ApiGateway.csproj b/samples/OcelotKube/ApiGateway/Ocelot.Samples.OcelotKube.ApiGateway.csproj index 548b13d79..f88cd602b 100644 --- a/samples/OcelotKube/ApiGateway/Ocelot.Samples.OcelotKube.ApiGateway.csproj +++ b/samples/OcelotKube/ApiGateway/Ocelot.Samples.OcelotKube.ApiGateway.csproj @@ -1,20 +1,16 @@  - - net7.0 + net6.0;net7.0;net8.0 disable disable InProcess Linux - - + - - diff --git a/samples/OcelotKube/DownstreamService/Ocelot.Samples.OcelotKube.DownstreamService.csproj b/samples/OcelotKube/DownstreamService/Ocelot.Samples.OcelotKube.DownstreamService.csproj index 914c863da..3c1cfefb2 100644 --- a/samples/OcelotKube/DownstreamService/Ocelot.Samples.OcelotKube.DownstreamService.csproj +++ b/samples/OcelotKube/DownstreamService/Ocelot.Samples.OcelotKube.DownstreamService.csproj @@ -1,5 +1,4 @@ - net7.0 disable @@ -7,10 +6,7 @@ InProcess Linux - - - diff --git a/samples/OcelotOpenTracing/OcelotOpenTracing.csproj b/samples/OcelotOpenTracing/OcelotOpenTracing.csproj index 4c7ccf28a..a05368868 100644 --- a/samples/OcelotOpenTracing/OcelotOpenTracing.csproj +++ b/samples/OcelotOpenTracing/OcelotOpenTracing.csproj @@ -1,22 +1,30 @@  - Exe - net7.0 + net6.0;net7.0;net8.0 disable disable - - + - - + + + + + + + + + + + + true @@ -28,5 +36,4 @@ true - diff --git a/samples/OcelotServiceDiscovery/ApiGateway/Ocelot.Samples.ServiceDiscovery.ApiGateway.csproj b/samples/OcelotServiceDiscovery/ApiGateway/Ocelot.Samples.ServiceDiscovery.ApiGateway.csproj index e987ea143..aac1dd20a 100644 --- a/samples/OcelotServiceDiscovery/ApiGateway/Ocelot.Samples.ServiceDiscovery.ApiGateway.csproj +++ b/samples/OcelotServiceDiscovery/ApiGateway/Ocelot.Samples.ServiceDiscovery.ApiGateway.csproj @@ -1,11 +1,8 @@ - - net7.0 + net6.0;net7.0;net8.0 - - diff --git a/samples/OcelotServiceFabric/src/OcelotApplicationApiGateway/OcelotApplicationApiGateway.csproj b/samples/OcelotServiceFabric/src/OcelotApplicationApiGateway/OcelotApplicationApiGateway.csproj index 07284008b..c97238c53 100644 --- a/samples/OcelotServiceFabric/src/OcelotApplicationApiGateway/OcelotApplicationApiGateway.csproj +++ b/samples/OcelotServiceFabric/src/OcelotApplicationApiGateway/OcelotApplicationApiGateway.csproj @@ -1,23 +1,23 @@ - - - Stateless Web Service for Stateful OcelotApplicationApiGateway App - net7.0 - disable - disable - OcelotApplicationApiGateway - OcelotApplicationApiGateway - x64 - - - - PreserveNewest - - - - - - - - - + + + Stateless Web Service for Stateful OcelotApplicationApiGateway App + net6.0;net7.0;net8.0 + disable + disable + OcelotApplicationApiGateway + OcelotApplicationApiGateway + x64 + + + + PreserveNewest + + + + + + + + + diff --git a/samples/OcelotServiceFabric/src/OcelotApplicationService/OcelotApplicationService.csproj b/samples/OcelotServiceFabric/src/OcelotApplicationService/OcelotApplicationService.csproj index 4bde15efc..6dc51c893 100644 --- a/samples/OcelotServiceFabric/src/OcelotApplicationService/OcelotApplicationService.csproj +++ b/samples/OcelotServiceFabric/src/OcelotApplicationService/OcelotApplicationService.csproj @@ -1,7 +1,7 @@  Stateless Service Application - net7.0 + net6.0;net7.0;net8.0 disable disable OcelotApplicationService @@ -13,8 +13,8 @@ - - - + + + diff --git a/src/Ocelot.Administration/Ocelot.Administration.csproj b/src/Ocelot.Administration/Ocelot.Administration.csproj index 4b075c29d..4bb397ab3 100644 --- a/src/Ocelot.Administration/Ocelot.Administration.csproj +++ b/src/Ocelot.Administration/Ocelot.Administration.csproj @@ -1,6 +1,6 @@  - net7.0 + net6.0;net7.0;net8.0 disable disable true @@ -12,7 +12,7 @@ API Gateway;.NET core https://github.com/ThreeMammals/Ocelot.Administration https://raw.githubusercontent.com/ThreeMammals/Ocelot/develop/images/ocelot_logo.png - win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64 + win-x64;osx-x64 false false True @@ -26,11 +26,12 @@ full True + - + all @@ -39,4 +40,19 @@ + + + + + + + + + + + + + + + diff --git a/src/Ocelot.Cache.CacheManager/Ocelot.Cache.CacheManager.csproj b/src/Ocelot.Cache.CacheManager/Ocelot.Cache.CacheManager.csproj index f4f40691a..4636540bc 100644 --- a/src/Ocelot.Cache.CacheManager/Ocelot.Cache.CacheManager.csproj +++ b/src/Ocelot.Cache.CacheManager/Ocelot.Cache.CacheManager.csproj @@ -1,6 +1,6 @@  - net7.0 + net6.0;net7.0;net8.0 disable disable true @@ -12,7 +12,7 @@ API Gateway;.NET core https://github.com/ThreeMammals/Ocelot.Cache.CacheManager https://raw.githubusercontent.com/ThreeMammals/Ocelot/develop/images/ocelot_logo.png - win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64 + win-x64;osx-x64 false false True @@ -26,11 +26,12 @@ full True + - + all @@ -40,4 +41,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ocelot.Provider.Consul/Ocelot.Provider.Consul.csproj b/src/Ocelot.Provider.Consul/Ocelot.Provider.Consul.csproj index b9cdb1127..f8149b859 100644 --- a/src/Ocelot.Provider.Consul/Ocelot.Provider.Consul.csproj +++ b/src/Ocelot.Provider.Consul/Ocelot.Provider.Consul.csproj @@ -1,6 +1,6 @@  - net7.0 + net6.0;net7.0;net8.0 disable disable true @@ -12,7 +12,7 @@ API Gateway;.NET core https://github.com/ThreeMammals/Ocelot.Provider.Consul https://raw.githubusercontent.com/ThreeMammals/Ocelot/develop/images/ocelot_logo.png - win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64 + win-x64;osx-x64 false false True @@ -30,8 +30,8 @@ - - + + all diff --git a/src/Ocelot.Provider.Eureka/Ocelot.Provider.Eureka.csproj b/src/Ocelot.Provider.Eureka/Ocelot.Provider.Eureka.csproj index 92b1ba985..b7d578440 100644 --- a/src/Ocelot.Provider.Eureka/Ocelot.Provider.Eureka.csproj +++ b/src/Ocelot.Provider.Eureka/Ocelot.Provider.Eureka.csproj @@ -1,43 +1,43 @@ - - - net7.0 - disable - disable - true - Provides Ocelot extensions to use Eureka - Ocelot.Provider.Eureka - 0.0.0-dev - Ocelot.Provider.Eureka - Ocelot.Provider.Eureka - API Gateway;.NET core - https://github.com/ThreeMammals/Ocelot.Provider.Eureka - https://github.com/ThreeMammals/Ocelot.Provider.Eureka - https://raw.githubusercontent.com/ThreeMammals/Ocelot/develop/images/ocelot_logo.png - win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64 - false - false - True - false - Tom Pallister - ..\..\codeanalysis.ruleset - True - 1591 - - - full - True - - - - - - - - - all - - - - - - + + + net6.0;net7.0;net8.0 + disable + disable + true + Provides Ocelot extensions to use Eureka + Ocelot.Provider.Eureka + 0.0.0-dev + Ocelot.Provider.Eureka + Ocelot.Provider.Eureka + API Gateway;.NET core + https://github.com/ThreeMammals/Ocelot.Provider.Eureka + https://github.com/ThreeMammals/Ocelot.Provider.Eureka + https://raw.githubusercontent.com/ThreeMammals/Ocelot/develop/images/ocelot_logo.png + win-x64;osx-x64 + false + false + True + false + Tom Pallister + ..\..\codeanalysis.ruleset + True + 1591 + + + full + True + + + + + + + + + all + + + + + + diff --git a/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj b/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj index 92afba3aa..375b89535 100644 --- a/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj +++ b/src/Ocelot.Provider.Kubernetes/Ocelot.Provider.Kubernetes.csproj @@ -1,7 +1,6 @@  - - net7.0 + net6.0;net7.0;net8.0 disable disable true @@ -13,7 +12,7 @@ Ocelot.Provider.Kubernetes Ocelot.Provider.Kubernetes API Gateway;.NET core - win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64 + win-x64;osx-x64 false false true @@ -25,26 +24,21 @@ True 1591 - - - + all - - - diff --git a/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj b/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj index 4ffcb9eb6..a75db00e8 100644 --- a/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj +++ b/src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj @@ -1,6 +1,6 @@  - net7.0 + net6.0;net7.0;net8.0 disable disable true @@ -13,7 +13,7 @@ https://github.com/ThreeMammals/Ocelot.Provider.Polly https://github.com/ThreeMammals/Ocelot.Provider.Polly https://raw.githubusercontent.com/ThreeMammals/Ocelot/develop/images/ocelot_logo.png - win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64 + win-x64;osx-x64 false false True @@ -31,10 +31,10 @@ - + all - + diff --git a/src/Ocelot.Tracing.Butterfly/Ocelot.Tracing.Butterfly.csproj b/src/Ocelot.Tracing.Butterfly/Ocelot.Tracing.Butterfly.csproj index a955c6f0c..68b90652f 100644 --- a/src/Ocelot.Tracing.Butterfly/Ocelot.Tracing.Butterfly.csproj +++ b/src/Ocelot.Tracing.Butterfly/Ocelot.Tracing.Butterfly.csproj @@ -1,45 +1,43 @@ - - - - net7.0 - disable - disable - true - This package provides methods to integrate Butterfly tracing with Ocelot. - Ocelot.Tracing.Butterfly - 0.0.0-dev - Ocelot.Tracing.Butterfly - Ocelot.Tracing.Butterfly - API Gateway;.NET core; Butterfly; ButterflyAPM - https://github.com/ThreeMammals/Ocelot - https://raw.githubusercontent.com/ThreeMammals/Ocelot/develop/images/ocelot_logo.png - win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64 - false - false - True - false - Tom Pallister - ..\..\codeanalysis.ruleset - Ocelot.Tracing.Butterfly - True - 1591 - - - full - True - - - - - - - - - all - - - - - - - + + + net6.0;net7.0;net8.0 + disable + disable + true + This package provides methods to integrate Butterfly tracing with Ocelot. + Ocelot.Tracing.Butterfly + 0.0.0-dev + Ocelot.Tracing.Butterfly + Ocelot.Tracing.Butterfly + API Gateway;.NET core; Butterfly; ButterflyAPM + https://github.com/ThreeMammals/Ocelot + https://raw.githubusercontent.com/ThreeMammals/Ocelot/develop/images/ocelot_logo.png + win-x64;osx-x64 + false + false + True + false + Tom Pallister + ..\..\codeanalysis.ruleset + Ocelot.Tracing.Butterfly + True + 1591 + + + full + True + + + + + + + + + all + + + + + + diff --git a/src/Ocelot.Tracing.OpenTracing/Ocelot.Tracing.OpenTracing.csproj b/src/Ocelot.Tracing.OpenTracing/Ocelot.Tracing.OpenTracing.csproj index e3b7336bf..635e3c77d 100644 --- a/src/Ocelot.Tracing.OpenTracing/Ocelot.Tracing.OpenTracing.csproj +++ b/src/Ocelot.Tracing.OpenTracing/Ocelot.Tracing.OpenTracing.csproj @@ -1,7 +1,6 @@ - - net7.0 + net6.0;net7.0;net8.0 disable disable 0.0.0-dev @@ -15,21 +14,17 @@ ..\..\codeanalysis.ruleset 1591 - - - + all - - diff --git a/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs b/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs index 6e8c79308..4649ecd0b 100644 --- a/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs +++ b/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs @@ -14,8 +14,16 @@ public static partial class ConfigurationBuilderExtensions public const string PrimaryConfigFile = "ocelot.json"; public const string GlobalConfigFile = "ocelot.global.json"; - [GeneratedRegex("^ocelot\\.(.*?)\\.json$", RegexOptions.IgnoreCase | RegexOptions.Singleline, "en-US")] +#if NET7_0_OR_GREATER + [GeneratedRegex(@"^ocelot\.(.*?)\.json$", RegexOptions.IgnoreCase | RegexOptions.Singleline, "en-US")] private static partial Regex SubConfigRegex(); +#else + private static readonly Regex SubConfigRegexVar = new(@"^ocelot\.(.*?)\.json$", RegexOptions.IgnoreCase | RegexOptions.Singleline, TimeSpan.FromMilliseconds(1000)); + private static Regex SubConfigRegex() + { + return SubConfigRegexVar; + } +#endif [Obsolete("Please set BaseUrl in ocelot.json GlobalConfiguration.BaseUrl")] public static IConfigurationBuilder AddOcelotBaseUrl(this IConfigurationBuilder builder, string baseUrl) diff --git a/src/Ocelot/Headers/AddHeadersToRequest.cs b/src/Ocelot/Headers/AddHeadersToRequest.cs index f33f36c73..d5a8c0629 100644 --- a/src/Ocelot/Headers/AddHeadersToRequest.cs +++ b/src/Ocelot/Headers/AddHeadersToRequest.cs @@ -68,11 +68,11 @@ public void SetHeadersOnDownstreamRequest(IEnumerable headers, HttpCo continue; } - requestHeader.Add(header.Key, new StringValues(value.Data)); + requestHeader.Append(header.Key, new StringValues(value.Data)); } else { - requestHeader.Add(header.Key, header.Value); + requestHeader.Append(header.Key, header.Value); } } } diff --git a/src/Ocelot/Headers/HttpContextRequestHeaderReplacer.cs b/src/Ocelot/Headers/HttpContextRequestHeaderReplacer.cs index 85c6ad7d8..ec0a8c0da 100644 --- a/src/Ocelot/Headers/HttpContextRequestHeaderReplacer.cs +++ b/src/Ocelot/Headers/HttpContextRequestHeaderReplacer.cs @@ -14,7 +14,7 @@ public Response Replace(HttpContext context, List fAndRs) { var replaced = values[f.Index].Replace(f.Find, f.Replace); context.Request.Headers.Remove(f.Key); - context.Request.Headers.Add(f.Key, replaced); + context.Request.Headers.Append(f.Key, replaced); } } diff --git a/src/Ocelot/Ocelot.csproj b/src/Ocelot/Ocelot.csproj index bc71e34ac..19f0a5bdc 100644 --- a/src/Ocelot/Ocelot.csproj +++ b/src/Ocelot/Ocelot.csproj @@ -1,46 +1,58 @@ - - - net7.0 - disable - disable - true - Ocelot is an API Gateway. The project is aimed at people using .NET running a micro services / service orientated architecture that need a unified point of entry into their system. In particular I want easy integration with IdentityServer reference and bearer tokens. reference tokens. Ocelot is a bunch of middlewares in a specific order. Ocelot manipulates the HttpRequest object into a state specified by its configuration until it reaches a request builder middleware where it creates a HttpRequestMessage object which is used to make a request to a downstream service. The middleware that makes the request is the last thing in the Ocelot pipeline. It does not call the next middleware. The response from the downstream service is stored in a per request scoped repository and retrived as the requests goes back up the Ocelot pipeline. There is a piece of middleware that maps the HttpResponseMessage onto the HttpResponse object and that is returned to the client. That is basically it with a bunch of other features. - Ocelot - 0.0.0-dev - Ocelot - Ocelot - API Gateway;.NET core - https://github.com/ThreeMammals/Ocelot - https://raw.githubusercontent.com/ThreeMammals/Ocelot/develop/images/ocelot_logo.png - win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64 - false - false - True - false - Tom Pallister - ..\..\codeanalysis.ruleset + + + net6.0;net7.0;net8.0 + disable + disable + true + Ocelot is an API Gateway. The project is aimed at people using .NET running a micro services / service orientated architecture that need a unified point of entry into their system. In particular I want easy integration with IdentityServer reference and bearer tokens. reference tokens. Ocelot is a bunch of middlewares in a specific order. Ocelot manipulates the HttpRequest object into a state specified by its configuration until it reaches a request builder middleware where it creates a HttpRequestMessage object which is used to make a request to a downstream service. The middleware that makes the request is the last thing in the Ocelot pipeline. It does not call the next middleware. The response from the downstream service is stored in a per request scoped repository and retrived as the requests goes back up the Ocelot pipeline. There is a piece of middleware that maps the HttpResponseMessage onto the HttpResponse object and that is returned to the client. That is basically it with a bunch of other features. + Ocelot + 0.0.0-dev + Ocelot + Ocelot + API Gateway;.NET core + https://github.com/ThreeMammals/Ocelot + https://raw.githubusercontent.com/ThreeMammals/Ocelot/develop/images/ocelot_logo.png + win-x64;osx-x64 + false + false + True + false + Tom Pallister + ..\..\codeanalysis.ruleset True - 1591 - - - full - True - - - - - - - - NU1701 - - - - all - - - - - - - + 1591 + + + full + True + + + + + + + NU1701 + + + all + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ocelot/Responder/HttpContextResponder.cs b/src/Ocelot/Responder/HttpContextResponder.cs index 4e4fb6ba5..2c21e0c9e 100644 --- a/src/Ocelot/Responder/HttpContextResponder.cs +++ b/src/Ocelot/Responder/HttpContextResponder.cs @@ -93,7 +93,7 @@ private static void AddHeaderIfDoesntExist(HttpContext context, Header httpRespo { if (!context.Response.Headers.ContainsKey(httpResponseHeader.Key)) { - context.Response.Headers.Add(httpResponseHeader.Key, new StringValues(httpResponseHeader.Values.ToArray())); + context.Response.Headers.Append(httpResponseHeader.Key, new StringValues(httpResponseHeader.Values.ToArray())); } } } diff --git a/src/Ocelot/WebSockets/ClientWebSocketOptionsProxy.cs b/src/Ocelot/WebSockets/ClientWebSocketOptionsProxy.cs index fea55c146..bf336b54f 100644 --- a/src/Ocelot/WebSockets/ClientWebSocketOptionsProxy.cs +++ b/src/Ocelot/WebSockets/ClientWebSocketOptionsProxy.cs @@ -13,8 +13,17 @@ public ClientWebSocketOptionsProxy(ClientWebSocketOptions options) _real = options; } + // .NET 6 and lower doesn't support the properties below. + // Instead of throwing a NotSupportedException, we just implement the getter/setter. + // This way, we can use the same code for .NET 6 and .NET 7+. + // TODO The design should be reviewed since we are hiding the ClientWebSocketOptions properties. +#if NET7_0_OR_GREATER public Version HttpVersion { get => _real.HttpVersion; set => _real.HttpVersion = value; } public HttpVersionPolicy HttpVersionPolicy { get => _real.HttpVersionPolicy; set => _real.HttpVersionPolicy = value; } +#else + public Version HttpVersion { get; set; } + public HttpVersionPolicy HttpVersionPolicy { get; set; } +#endif public bool UseDefaultCredentials { get => _real.UseDefaultCredentials; set => _real.UseDefaultCredentials = value; } public ICredentials Credentials { get => _real.Credentials; set => _real.Credentials = value; } public IWebProxy Proxy { get => _real.Proxy; set => _real.Proxy = value; } @@ -23,8 +32,11 @@ public ClientWebSocketOptionsProxy(ClientWebSocketOptions options) public CookieContainer Cookies { get => _real.Cookies; set => _real.Cookies = value; } public TimeSpan KeepAliveInterval { get => _real.KeepAliveInterval; set => _real.KeepAliveInterval = value; } public WebSocketDeflateOptions DangerousDeflateOptions { get => _real.DangerousDeflateOptions; set => _real.DangerousDeflateOptions = value; } +#if NET7_0_OR_GREATER public bool CollectHttpResponseDetails { get => _real.CollectHttpResponseDetails; set => _real.CollectHttpResponseDetails = value; } - +#else + public bool CollectHttpResponseDetails { get; set; } +#endif public void AddSubProtocol(string subProtocol) => _real.AddSubProtocol(subProtocol); public void SetBuffer(int receiveBufferSize, int sendBufferSize) => _real.SetBuffer(receiveBufferSize, sendBufferSize); diff --git a/test/Ocelot.AcceptanceTests/CachingTests.cs b/test/Ocelot.AcceptanceTests/CachingTests.cs index 95f6f5166..b2ef34d6c 100644 --- a/test/Ocelot.AcceptanceTests/CachingTests.cs +++ b/test/Ocelot.AcceptanceTests/CachingTests.cs @@ -211,7 +211,7 @@ private void GivenThereIsAServiceRunningOn(string url, int statusCode, string re { if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(key)) { - context.Response.Headers.Add(key, value); + context.Response.Headers.Append(key, value); } context.Response.StatusCode = statusCode; diff --git a/test/Ocelot.AcceptanceTests/ConsulConfigurationInConsulTests.cs b/test/Ocelot.AcceptanceTests/ConsulConfigurationInConsulTests.cs index f138675b9..6d0c31a3a 100644 --- a/test/Ocelot.AcceptanceTests/ConsulConfigurationInConsulTests.cs +++ b/test/Ocelot.AcceptanceTests/ConsulConfigurationInConsulTests.cs @@ -370,7 +370,7 @@ private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string var kvp = new FakeConsulGetResponse(base64); json = JsonConvert.SerializeObject(new[] { kvp }); - context.Response.Headers.Add("Content-Type", "application/json"); + context.Response.Headers.Append("Content-Type", "application/json"); await context.Response.WriteAsync(json); } else if (context.Request.Method.ToLower() == "put" && context.Request.Path.Value == "/v1/kv/InternalConfiguration") @@ -398,7 +398,7 @@ private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string else if (context.Request.Path.Value == $"/v1/health/service/{serviceName}") { var json = JsonConvert.SerializeObject(_consulServices); - context.Response.Headers.Add("Content-Type", "application/json"); + context.Response.Headers.Append("Content-Type", "application/json"); await context.Response.WriteAsync(json); } }); diff --git a/test/Ocelot.AcceptanceTests/ConsulWebSocketTests.cs b/test/Ocelot.AcceptanceTests/ConsulWebSocketTests.cs index d03d7e6b9..38e4e18c8 100644 --- a/test/Ocelot.AcceptanceTests/ConsulWebSocketTests.cs +++ b/test/Ocelot.AcceptanceTests/ConsulWebSocketTests.cs @@ -126,7 +126,7 @@ private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string if (context.Request.Path.Value == $"/v1/health/service/{serviceName}") { var json = JsonConvert.SerializeObject(_serviceEntries); - context.Response.Headers.Add("Content-Type", "application/json"); + context.Response.Headers.Append("Content-Type", "application/json"); await context.Response.WriteAsync(json); } }); diff --git a/test/Ocelot.AcceptanceTests/EurekaServiceDiscoveryTests.cs b/test/Ocelot.AcceptanceTests/EurekaServiceDiscoveryTests.cs index 8def02990..1be8c7798 100644 --- a/test/Ocelot.AcceptanceTests/EurekaServiceDiscoveryTests.cs +++ b/test/Ocelot.AcceptanceTests/EurekaServiceDiscoveryTests.cs @@ -141,7 +141,7 @@ private void GivenThereIsAFakeEurekaServiceDiscoveryProvider(string url, string }; var json = JsonConvert.SerializeObject(applications); - context.Response.Headers.Add("Content-Type", "application/json"); + context.Response.Headers.Append("Content-Type", "application/json"); await context.Response.WriteAsync(json); } }); diff --git a/test/Ocelot.AcceptanceTests/HeaderTests.cs b/test/Ocelot.AcceptanceTests/HeaderTests.cs index 5a28e1753..1a7979a1d 100644 --- a/test/Ocelot.AcceptanceTests/HeaderTests.cs +++ b/test/Ocelot.AcceptanceTests/HeaderTests.cs @@ -448,7 +448,7 @@ private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int { context.Response.OnStarting(() => { - context.Response.Headers.Add(headerKey, headerValue); + context.Response.Headers.Append(headerKey, headerValue); context.Response.StatusCode = statusCode; return Task.CompletedTask; }); diff --git a/test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj b/test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj index c54810e36..760b03bae 100644 --- a/test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj +++ b/test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj @@ -1,53 +1,51 @@  - - 0.0.0-dev - net7.0 + + 0.0.0-dev + net6.0;net7.0;net8.0 disable disable false true Ocelot.AcceptanceTests - Exe - Ocelot.AcceptanceTests - true - osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64 - false - false - false - ..\..\codeanalysis.ruleset - True + Exe + Ocelot.AcceptanceTests + true + win-x64;osx-x64 + false + false + false + ..\..\codeanalysis.ruleset + True 1591 - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - - - - - - - - - - - - - - - - + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -55,31 +53,58 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - - all - - - - - - - - - - - - - - - - - - - - - - + + + + all + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Ocelot.AcceptanceTests/PollyQoSTests.cs b/test/Ocelot.AcceptanceTests/PollyQoSTests.cs index c182721ad..9d8f3ec39 100644 --- a/test/Ocelot.AcceptanceTests/PollyQoSTests.cs +++ b/test/Ocelot.AcceptanceTests/PollyQoSTests.cs @@ -6,7 +6,6 @@ namespace Ocelot.AcceptanceTests public class PollyQoSTests : IDisposable { private readonly Steps _steps; - private int _requestCount; private readonly ServiceHandler _serviceHandler; public PollyQoSTests() @@ -227,32 +226,17 @@ private static void GivenIWaitMilliseconds(int ms) private void GivenThereIsAPossiblyBrokenServiceRunningOn(string url, string responseBody) { + var requestCount = 0; _serviceHandler.GivenThereIsAServiceRunningOn(url, async context => { - //circuit starts closed - if (_requestCount == 0) + if (requestCount == 1) { - _requestCount++; - context.Response.StatusCode = 200; - await context.Response.WriteAsync(responseBody); - return; - } - - //request one times out and polly throws exception, circuit opens - if (_requestCount == 1) - { - _requestCount++; await Task.Delay(1000); - context.Response.StatusCode = 200; - return; } - //after break closes we return 200 OK - if (_requestCount == 2) - { - context.Response.StatusCode = 200; - await context.Response.WriteAsync(responseBody); - } + requestCount++; + context.Response.StatusCode = 200; + await context.Response.WriteAsync(responseBody); }); } diff --git a/test/Ocelot.AcceptanceTests/RequestIdTests.cs b/test/Ocelot.AcceptanceTests/RequestIdTests.cs index 2e7987846..e1de4f313 100644 --- a/test/Ocelot.AcceptanceTests/RequestIdTests.cs +++ b/test/Ocelot.AcceptanceTests/RequestIdTests.cs @@ -171,7 +171,7 @@ private void GivenThereIsAServiceRunningOn(string url) _serviceHandler.GivenThereIsAServiceRunningOn(url, context => { context.Request.Headers.TryGetValue(_steps.RequestIdKey, out var requestId); - context.Response.Headers.Add(_steps.RequestIdKey, requestId.First()); + context.Response.Headers[_steps.RequestIdKey] = requestId.First(); return Task.CompletedTask; }); } diff --git a/test/Ocelot.AcceptanceTests/ServiceDiscoveryTests.cs b/test/Ocelot.AcceptanceTests/ServiceDiscoveryTests.cs index 1814db1e8..c9f093bf0 100644 --- a/test/Ocelot.AcceptanceTests/ServiceDiscoveryTests.cs +++ b/test/Ocelot.AcceptanceTests/ServiceDiscoveryTests.cs @@ -516,7 +516,7 @@ private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string } var json = JsonConvert.SerializeObject(_consulServices); - context.Response.Headers.Add("Content-Type", "application/json"); + context.Response.Headers.Append("Content-Type", "application/json"); await context.Response.WriteAsync(json); } }); diff --git a/test/Ocelot.AcceptanceTests/TwoDownstreamServicesTests.cs b/test/Ocelot.AcceptanceTests/TwoDownstreamServicesTests.cs index 30b3d7235..3a695bb9c 100644 --- a/test/Ocelot.AcceptanceTests/TwoDownstreamServicesTests.cs +++ b/test/Ocelot.AcceptanceTests/TwoDownstreamServicesTests.cs @@ -97,7 +97,7 @@ private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url) if (context.Request.Path.Value == "/v1/health/service/product") { var json = JsonConvert.SerializeObject(_serviceEntries); - context.Response.Headers.Add("Content-Type", "application/json"); + context.Response.Headers.Append("Content-Type", "application/json"); await context.Response.WriteAsync(json); } }); diff --git a/test/Ocelot.Benchmarks/DownstreamRouteFinderMiddlewareBenchmarks.cs b/test/Ocelot.Benchmarks/DownstreamRouteFinderMiddlewareBenchmarks.cs index cdf0002c7..4e99d1fe0 100644 --- a/test/Ocelot.Benchmarks/DownstreamRouteFinderMiddlewareBenchmarks.cs +++ b/test/Ocelot.Benchmarks/DownstreamRouteFinderMiddlewareBenchmarks.cs @@ -10,7 +10,7 @@ namespace Ocelot.Benchmarks { - [SimpleJob(launchCount: 1, warmupCount: 2, targetCount: 5)] + [SimpleJob(launchCount: 1, warmupCount: 2, iterationCount: 5)] [Config(typeof(DownstreamRouteFinderMiddlewareBenchmarks))] public class DownstreamRouteFinderMiddlewareBenchmarks : ManualConfig { @@ -51,7 +51,7 @@ public void SetUp() QueryString = new QueryString("?a=b"), }, }; - httpContext.Request.Headers.Add("Host", "most"); + httpContext.Request.Headers.Append("Host", "most"); httpContext.Items.SetIInternalConfiguration(new InternalConfiguration(new List(), null, null, null, null, null, null, null, null)); _httpContext = httpContext; diff --git a/test/Ocelot.Benchmarks/ExceptionHandlerMiddlewareBenchmarks.cs b/test/Ocelot.Benchmarks/ExceptionHandlerMiddlewareBenchmarks.cs index 0dde79085..35e0f25b0 100644 --- a/test/Ocelot.Benchmarks/ExceptionHandlerMiddlewareBenchmarks.cs +++ b/test/Ocelot.Benchmarks/ExceptionHandlerMiddlewareBenchmarks.cs @@ -8,7 +8,7 @@ namespace Ocelot.Benchmarks { - [SimpleJob(launchCount: 1, warmupCount: 2, targetCount: 5)] + [SimpleJob(launchCount: 1, warmupCount: 2, iterationCount: 5)] [Config(typeof(ExceptionHandlerMiddlewareBenchmarks))] public class ExceptionHandlerMiddlewareBenchmarks : ManualConfig { diff --git a/test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj b/test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj index 12081074d..ffbd2d8a4 100644 --- a/test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj +++ b/test/Ocelot.Benchmarks/Ocelot.Benchmarks.csproj @@ -1,8 +1,7 @@  - 0.0.0-dev - net7.0 + net6.0;net7.0;net8.0 disable disable false @@ -10,7 +9,7 @@ Ocelot.Benchmarks Exe Ocelot.Benchmarks - osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64 + win-x64;osx-x64 false false false @@ -18,18 +17,15 @@ True 1591 - - - - + + all - diff --git a/test/Ocelot.IntegrationTests/Ocelot.IntegrationTests.csproj b/test/Ocelot.IntegrationTests/Ocelot.IntegrationTests.csproj index c78949e19..dbd821b49 100644 --- a/test/Ocelot.IntegrationTests/Ocelot.IntegrationTests.csproj +++ b/test/Ocelot.IntegrationTests/Ocelot.IntegrationTests.csproj @@ -1,44 +1,43 @@  - - 0.0.0-dev - net7.0 + + 0.0.0-dev + net6.0;net7.0;net8.0 disable disable false true Ocelot.IntegrationTests - Exe - Ocelot.IntegrationTests - true - win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64 - false - false - false - ..\..\codeanalysis.ruleset - True + Exe + Ocelot.IntegrationTests + true + win-x64;osx-x64 + false + false + false + ..\..\codeanalysis.ruleset + True 1591 - - - PreserveNewest - - - - - - - - - - - - - - - - - - + + + PreserveNewest + + + + + + + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -46,23 +45,48 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - all - - - - - - - - - - - - - - - - - + + all + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Ocelot.ManualTest/Ocelot.ManualTest.csproj b/test/Ocelot.ManualTest/Ocelot.ManualTest.csproj index 18601b7f0..81aabb2f1 100644 --- a/test/Ocelot.ManualTest/Ocelot.ManualTest.csproj +++ b/test/Ocelot.ManualTest/Ocelot.ManualTest.csproj @@ -1,14 +1,14 @@  0.0.0-dev - net7.0 + net6.0;net7.0;net8.0 disable disable true Ocelot.ManualTest Exe Ocelot.ManualTest - osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64 + win-x64;osx-x64 ..\..\codeanalysis.ruleset True 1591 @@ -32,6 +32,22 @@ + + all + + + + + + + + + + + + + + @@ -39,9 +55,16 @@ - - all - + + + + + + + + + + diff --git a/test/Ocelot.UnitTests/Configuration/Validation/FileConfigurationFluentValidatorTests.cs b/test/Ocelot.UnitTests/Configuration/Validation/FileConfigurationFluentValidatorTests.cs index 98bfd1ea0..b36029232 100644 --- a/test/Ocelot.UnitTests/Configuration/Validation/FileConfigurationFluentValidatorTests.cs +++ b/test/Ocelot.UnitTests/Configuration/Validation/FileConfigurationFluentValidatorTests.cs @@ -1564,11 +1564,20 @@ private class TestOptions : AuthenticationSchemeOptions } private class TestHandler : AuthenticationHandler - { + { + // https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/8.0/isystemclock-obsolete + // .NET 8.0: TimeProvider is now a settable property on the Options classes for the authentication and identity components. + // It can be set directly or by registering a provider in the dependency injection container. +#if NET8_0_OR_GREATER + public TestHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder) : base(options, logger, encoder) + { + } +#else public TestHandler(IOptionsMonitor options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) { - } - + } +#endif + protected override Task HandleAuthenticateAsync() { var principal = new ClaimsPrincipal(); diff --git a/test/Ocelot.UnitTests/Consul/ConsulServiceDiscoveryProviderTests.cs b/test/Ocelot.UnitTests/Consul/ConsulServiceDiscoveryProviderTests.cs index 115727676..e00c8a0af 100644 --- a/test/Ocelot.UnitTests/Consul/ConsulServiceDiscoveryProviderTests.cs +++ b/test/Ocelot.UnitTests/Consul/ConsulServiceDiscoveryProviderTests.cs @@ -205,7 +205,7 @@ private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string } var json = JsonConvert.SerializeObject(_serviceEntries); - context.Response.Headers.Add("Content-Type", "application/json"); + context.Response.Headers.Append("Content-Type", "application/json"); await context.Response.WriteAsync(json); } }); diff --git a/test/Ocelot.UnitTests/Errors/ExceptionHandlerMiddlewareTests.cs b/test/Ocelot.UnitTests/Errors/ExceptionHandlerMiddlewareTests.cs index 2b8827c6a..b59c0bb68 100644 --- a/test/Ocelot.UnitTests/Errors/ExceptionHandlerMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/Errors/ExceptionHandlerMiddlewareTests.cs @@ -102,7 +102,7 @@ public void should_throw_exception_if_config_provider_throws() private void WhenICallTheMiddlewareWithTheRequestIdKey(string key, string value) { - _httpContext.Request.Headers.Add(key, value); + _httpContext.Request.Headers.Append(key, value); /* _httpContext.Setup(x => x.Request.Headers).Returns(new HeaderDictionary() { { key, value } }); */ diff --git a/test/Ocelot.UnitTests/Headers/AddHeadersToRequestPlainTests.cs b/test/Ocelot.UnitTests/Headers/AddHeadersToRequestPlainTests.cs index d0236ad61..86eec01f0 100644 --- a/test/Ocelot.UnitTests/Headers/AddHeadersToRequestPlainTests.cs +++ b/test/Ocelot.UnitTests/Headers/AddHeadersToRequestPlainTests.cs @@ -79,17 +79,10 @@ private void GivenHttpRequestWithoutHeaders() } private void GivenHttpRequestWithHeader(string headerKey, string headerValue) - { - _context = new DefaultHttpContext - { - Request = - { - Headers = - { - { headerKey, headerValue }, - }, - }, - }; + { + var context = new DefaultHttpContext(); + context.Request.Headers.Append(headerKey, headerValue); + _context = context; } private void WhenAddingHeader(string headerKey, string headerValue) diff --git a/test/Ocelot.UnitTests/Headers/HttpContextRequestHeaderReplacerTests.cs b/test/Ocelot.UnitTests/Headers/HttpContextRequestHeaderReplacerTests.cs index 6bc8d6c40..51fe342b1 100644 --- a/test/Ocelot.UnitTests/Headers/HttpContextRequestHeaderReplacerTests.cs +++ b/test/Ocelot.UnitTests/Headers/HttpContextRequestHeaderReplacerTests.cs @@ -21,7 +21,7 @@ public HttpContextRequestHeaderReplacerTests() public void should_replace_headers() { var context = new DefaultHttpContext(); - context.Request.Headers.Add("test", "test"); + context.Request.Headers.Append("test", "test"); var fAndRs = new List { new("test", "test", "chiken", 0) }; @@ -36,7 +36,7 @@ public void should_replace_headers() public void should_not_replace_headers() { var context = new DefaultHttpContext(); - context.Request.Headers.Add("test", "test"); + context.Request.Headers.Append("test", "test"); var fAndRs = new List(); diff --git a/test/Ocelot.UnitTests/Headers/HttpHeadersTransformationMiddlewareTests.cs b/test/Ocelot.UnitTests/Headers/HttpHeadersTransformationMiddlewareTests.cs index 41433df78..d9441462b 100644 --- a/test/Ocelot.UnitTests/Headers/HttpHeadersTransformationMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/Headers/HttpHeadersTransformationMiddlewareTests.cs @@ -106,7 +106,7 @@ private void ThenTheIHttpResponseHeaderReplacerIsCalledCorrectly() private void GivenTheFollowingRequest() { - _httpContext.Request.Headers.Add("test", "test"); + _httpContext.Request.Headers.Append("test", "test"); } } } diff --git a/test/Ocelot.UnitTests/Infrastructure/PlaceholdersTests.cs b/test/Ocelot.UnitTests/Infrastructure/PlaceholdersTests.cs index c7f71723a..0b6dd1832 100644 --- a/test/Ocelot.UnitTests/Infrastructure/PlaceholdersTests.cs +++ b/test/Ocelot.UnitTests/Infrastructure/PlaceholdersTests.cs @@ -123,7 +123,7 @@ public void should_return_upstreamHost() { var upstreamHost = "UpstreamHostA"; var httpContext = new DefaultHttpContext(); - httpContext.Request.Headers.Add("Host", upstreamHost); + httpContext.Request.Headers.Append("Host", upstreamHost); _accessor.Setup(x => x.HttpContext).Returns(httpContext); var result = _placeholders.Get("{UpstreamHost}"); result.Data.ShouldBe(upstreamHost); diff --git a/test/Ocelot.UnitTests/Kubernetes/KubeServiceDiscoveryProviderTests.cs b/test/Ocelot.UnitTests/Kubernetes/KubeServiceDiscoveryProviderTests.cs index 2e9fe7ab5..272128a95 100644 --- a/test/Ocelot.UnitTests/Kubernetes/KubeServiceDiscoveryProviderTests.cs +++ b/test/Ocelot.UnitTests/Kubernetes/KubeServiceDiscoveryProviderTests.cs @@ -128,7 +128,7 @@ private void GivenThereIsAFakeKubeServiceDiscoveryProvider(string url, string se } var json = JsonConvert.SerializeObject(_endpointEntries); - context.Response.Headers.Add("Content-Type", "application/json"); + context.Response.Headers.Append("Content-Type", "application/json"); await context.Response.WriteAsync(json); } }); diff --git a/test/Ocelot.UnitTests/LoadBalancer/LeastConnectionTests.cs b/test/Ocelot.UnitTests/LoadBalancer/LeastConnectionTests.cs index be5d367b2..2766f58ab 100644 --- a/test/Ocelot.UnitTests/LoadBalancer/LeastConnectionTests.cs +++ b/test/Ocelot.UnitTests/LoadBalancer/LeastConnectionTests.cs @@ -21,7 +21,7 @@ public LeastConnectionTests() } [Fact] - public void should_be_able_to_lease_and_release_concurrently() + public async Task should_be_able_to_lease_and_release_concurrently() { var serviceName = "products"; @@ -41,11 +41,11 @@ public void should_be_able_to_lease_and_release_concurrently() tasks[i] = LeaseDelayAndRelease(); } - Task.WaitAll(tasks); + await Task.WhenAll(tasks); } [Fact] - public void should_handle_service_returning_to_available() + public async Task should_handle_service_returning_to_available() { var serviceName = "products"; @@ -57,9 +57,9 @@ public void should_handle_service_returning_to_available() _leastConnection = new LeastConnection(() => Task.FromResult(availableServices), serviceName); - var hostAndPortOne = _leastConnection.Lease(_httpContext).Result; + var hostAndPortOne = await _leastConnection.Lease(_httpContext); hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1"); - var hostAndPortTwo = _leastConnection.Lease(_httpContext).Result; + var hostAndPortTwo = await _leastConnection.Lease(_httpContext); hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.2"); _leastConnection.Release(hostAndPortOne.Data); _leastConnection.Release(hostAndPortTwo.Data); @@ -69,9 +69,9 @@ public void should_handle_service_returning_to_available() new(serviceName, new ServiceHostAndPort("127.0.0.1", 80), string.Empty, string.Empty, Array.Empty()), }; - hostAndPortOne = _leastConnection.Lease(_httpContext).Result; + hostAndPortOne = await _leastConnection.Lease(_httpContext); hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1"); - hostAndPortTwo = _leastConnection.Lease(_httpContext).Result; + hostAndPortTwo = await _leastConnection.Lease(_httpContext); hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.1"); _leastConnection.Release(hostAndPortOne.Data); _leastConnection.Release(hostAndPortTwo.Data); @@ -82,9 +82,9 @@ public void should_handle_service_returning_to_available() new(serviceName, new ServiceHostAndPort("127.0.0.2", 80), string.Empty, string.Empty, Array.Empty()), }; - hostAndPortOne = _leastConnection.Lease(_httpContext).Result; + hostAndPortOne = await _leastConnection.Lease(_httpContext); hostAndPortOne.Data.DownstreamHost.ShouldBe("127.0.0.1"); - hostAndPortTwo = _leastConnection.Lease(_httpContext).Result; + hostAndPortTwo = await _leastConnection.Lease(_httpContext); hostAndPortTwo.Data.DownstreamHost.ShouldBe("127.0.0.2"); _leastConnection.Release(hostAndPortOne.Data); _leastConnection.Release(hostAndPortTwo.Data); @@ -117,7 +117,7 @@ public void should_get_next_url() } [Fact] - public void should_serve_from_service_with_least_connections() + public async Task should_serve_from_service_with_least_connections() { var serviceName = "products"; @@ -131,21 +131,21 @@ public void should_serve_from_service_with_least_connections() _services = availableServices; _leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName); - var response = _leastConnection.Lease(_httpContext).Result; + var response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost); - response = _leastConnection.Lease(_httpContext).Result; + response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost); - response = _leastConnection.Lease(_httpContext).Result; + response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[2].HostAndPort.DownstreamHost); } [Fact] - public void should_build_connections_per_service() + public async Task should_build_connections_per_service() { var serviceName = "products"; @@ -158,25 +158,25 @@ public void should_build_connections_per_service() _services = availableServices; _leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName); - var response = _leastConnection.Lease(_httpContext).Result; + var response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost); - response = _leastConnection.Lease(_httpContext).Result; + response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost); - response = _leastConnection.Lease(_httpContext).Result; + response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost); - response = _leastConnection.Lease(_httpContext).Result; + response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost); } [Fact] - public void should_release_connection() + public async Task should_release_connection() { var serviceName = "products"; @@ -189,26 +189,26 @@ public void should_release_connection() _services = availableServices; _leastConnection = new LeastConnection(() => Task.FromResult(_services), serviceName); - var response = _leastConnection.Lease(_httpContext).Result; + var response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost); - response = _leastConnection.Lease(_httpContext).Result; + response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost); - response = _leastConnection.Lease(_httpContext).Result; + response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost); - response = _leastConnection.Lease(_httpContext).Result; + response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost); //release this so 2 should have 1 connection and we should get 2 back as our next host and port _leastConnection.Release(availableServices[1].HostAndPort); - response = _leastConnection.Lease(_httpContext).Result; + response = await _leastConnection.Lease(_httpContext); response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost); } diff --git a/test/Ocelot.UnitTests/LoadBalancer/RoundRobinTests.cs b/test/Ocelot.UnitTests/LoadBalancer/RoundRobinTests.cs index a981467c2..78196c13e 100644 --- a/test/Ocelot.UnitTests/LoadBalancer/RoundRobinTests.cs +++ b/test/Ocelot.UnitTests/LoadBalancer/RoundRobinTests.cs @@ -39,17 +39,17 @@ public void should_get_next_address() } [Fact] - public void should_go_back_to_first_address_after_finished_last() + public async Task should_go_back_to_first_address_after_finished_last() { var stopWatch = Stopwatch.StartNew(); while (stopWatch.ElapsedMilliseconds < 1000) { - var address = _roundRobin.Lease(_httpContext).Result; + var address = await _roundRobin.Lease(_httpContext); address.Data.ShouldBe(_services[0].HostAndPort); - address = _roundRobin.Lease(_httpContext).Result; + address = await _roundRobin.Lease(_httpContext); address.Data.ShouldBe(_services[1].HostAndPort); - address = _roundRobin.Lease(_httpContext).Result; + address = await _roundRobin.Lease(_httpContext); address.Data.ShouldBe(_services[2].HostAndPort); } } diff --git a/test/Ocelot.UnitTests/Multiplexing/MultiplexingMiddlewareTests.cs b/test/Ocelot.UnitTests/Multiplexing/MultiplexingMiddlewareTests.cs index 6c844ccd9..a7e6d2cb2 100644 --- a/test/Ocelot.UnitTests/Multiplexing/MultiplexingMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/Multiplexing/MultiplexingMiddlewareTests.cs @@ -13,24 +13,19 @@ public class MultiplexingMiddlewareTests private readonly MultiplexingMiddleware _middleware; private Ocelot.DownstreamRouteFinder.DownstreamRouteHolder _downstreamRoute; private int _count; - private readonly Mock _aggregator; - private readonly Mock _factory; private readonly HttpContext _httpContext; - private readonly RequestDelegate _next; - private readonly Mock _loggerFactory; - private readonly Mock _logger; public MultiplexingMiddlewareTests() { _httpContext = new DefaultHttpContext(); - _factory = new Mock(); - _aggregator = new Mock(); - _factory.Setup(x => x.Get(It.IsAny())).Returns(_aggregator.Object); - _loggerFactory = new Mock(); - _logger = new Mock(); - _loggerFactory.Setup(x => x.CreateLogger()).Returns(_logger.Object); - _next = context => Task.FromResult(_count++); - _middleware = new MultiplexingMiddleware(_next, _loggerFactory.Object, _factory.Object); + var factory = new Mock(); + var aggregator = new Mock(); + factory.Setup(x => x.Get(It.IsAny())).Returns(aggregator.Object); + var loggerFactory = new Mock(); + var logger = new Mock(); + loggerFactory.Setup(x => x.CreateLogger()).Returns(logger.Object); + Task Next(HttpContext context) => Task.FromResult(_count++); + _middleware = new MultiplexingMiddleware(Next, loggerFactory.Object, factory.Object); } [Fact] diff --git a/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj b/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj index 0c9fe46f7..c54b547a4 100644 --- a/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj +++ b/test/Ocelot.UnitTests/Ocelot.UnitTests.csproj @@ -1,63 +1,56 @@  - - - 0.0.0-dev - net7.0 + + 0.0.0-dev + net6.0;net7.0;net8.0 disable disable false true Ocelot.UnitTests - Ocelot.UnitTests - Exe - true - osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64 - false - false - false - ..\..\codeanalysis.ruleset - True + Ocelot.UnitTests + Exe + true + win-x64;osx-x64 + false + false + false + ..\..\codeanalysis.ruleset + True 1591 - - - full - True - - - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - - - + + full + True + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -65,30 +58,57 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - all - - - - - - - - - - - - - - - - - - - - - - + + all + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Ocelot.UnitTests/Request/Mapper/RequestMapperTests.cs b/test/Ocelot.UnitTests/Request/Mapper/RequestMapperTests.cs index ad93c9d4e..bd6c5a736 100644 --- a/test/Ocelot.UnitTests/Request/Mapper/RequestMapperTests.cs +++ b/test/Ocelot.UnitTests/Request/Mapper/RequestMapperTests.cs @@ -274,7 +274,7 @@ private void ThenTheMappedRequestHasContentDispositionHeader(string expected) private void GivenTheContentDispositionIs(string input) { - _inputRequest.Headers.Add("Content-Disposition", input); + _inputRequest.Headers.Append("Content-Disposition", input); } private void ThenTheMappedRequestHasContentMD5Header(byte[] expected) @@ -285,7 +285,7 @@ private void ThenTheMappedRequestHasContentMD5Header(byte[] expected) private void GivenTheContentMD5Is(byte[] input) { var base64 = Convert.ToBase64String(input); - _inputRequest.Headers.Add("Content-MD5", base64); + _inputRequest.Headers.Append("Content-MD5", base64); } private void ThenTheMappedRequestHasContentRangeHeader() @@ -296,7 +296,7 @@ private void ThenTheMappedRequestHasContentRangeHeader() private void GivenTheContentRangeIs(string input) { - _inputRequest.Headers.Add("Content-Range", input); + _inputRequest.Headers.Append("Content-Range", input); } private void ThenTheMappedRequestHasContentLocationHeader(string expected) @@ -306,7 +306,7 @@ private void ThenTheMappedRequestHasContentLocationHeader(string expected) private void GivenTheContentLocationIs(string input) { - _inputRequest.Headers.Add("Content-Location", input); + _inputRequest.Headers.Append("Content-Location", input); } private void ThenTheMappedRequestHasContentLanguageHeader(string expected) @@ -316,7 +316,7 @@ private void ThenTheMappedRequestHasContentLanguageHeader(string expected) private void GivenTheContentLanguageIs(string input) { - _inputRequest.Headers.Add("Content-Language", input); + _inputRequest.Headers.Append("Content-Language", input); } private void ThenTheMappedRequestHasContentEncodingHeader(string expected, string expectedTwo) @@ -327,7 +327,7 @@ private void ThenTheMappedRequestHasContentEncodingHeader(string expected, strin private void GivenTheContentEncodingIs(string input) { - _inputRequest.Headers.Add("Content-Encoding", input); + _inputRequest.Headers.Append("Content-Encoding", input); } private void GivenTheContentTypeIs(string contentType) diff --git a/test/Ocelot.UnitTests/RequestId/RequestIdMiddlewareTests.cs b/test/Ocelot.UnitTests/RequestId/RequestIdMiddlewareTests.cs index 54b223c2c..641f9c9cc 100644 --- a/test/Ocelot.UnitTests/RequestId/RequestIdMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/RequestId/RequestIdMiddlewareTests.cs @@ -32,7 +32,7 @@ public RequestIdMiddlewareTests() _loggerFactory.Setup(x => x.CreateLogger()).Returns(_logger.Object); _next = context => { - _httpContext.Response.Headers.Add("LSRequestId", _httpContext.TraceIdentifier); + _httpContext.Response.Headers.Append("LSRequestId", _httpContext.TraceIdentifier); return Task.CompletedTask; }; _middleware = new RequestIdMiddleware(_next, _loggerFactory.Object, _repo.Object); diff --git a/test/Ocelot.UnitTests/Responder/HttpContextResponderTests.cs b/test/Ocelot.UnitTests/Responder/HttpContextResponderTests.cs index 523e1a483..3e273bf85 100644 --- a/test/Ocelot.UnitTests/Responder/HttpContextResponderTests.cs +++ b/test/Ocelot.UnitTests/Responder/HttpContextResponderTests.cs @@ -9,16 +9,15 @@ namespace Ocelot.UnitTests.Responder public class HttpContextResponderTests { private readonly HttpContextResponder _responder; - private readonly RemoveOutputHeaders _removeOutputHeaders; public HttpContextResponderTests() { - _removeOutputHeaders = new RemoveOutputHeaders(); - _responder = new HttpContextResponder(_removeOutputHeaders); + var removeOutputHeaders = new RemoveOutputHeaders(); + _responder = new HttpContextResponder(removeOutputHeaders); } [Fact] - public void should_remove_transfer_encoding_header() + public async Task should_remove_transfer_encoding_header() { var httpContext = new DefaultHttpContext(); var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.OK, @@ -27,42 +26,38 @@ public void should_remove_transfer_encoding_header() new("Transfer-Encoding", new List {"woop"}), }, "some reason"); - _responder.SetResponseOnHttpContext(httpContext, response).GetAwaiter().GetResult(); + await _responder.SetResponseOnHttpContext(httpContext, response); var header = httpContext.Response.Headers["Transfer-Encoding"]; header.ShouldBeEmpty(); } [Fact] - public void should_ignore_content_if_null() + public async Task should_ignore_content_if_null() { var httpContext = new DefaultHttpContext(); var response = new DownstreamResponse(null, HttpStatusCode.OK, new List>>(), "some reason"); - Should.NotThrow(() => + await Should.NotThrowAsync(async () => { - _responder - .SetResponseOnHttpContext(httpContext, response) - .GetAwaiter() - .GetResult() - ; + await _responder.SetResponseOnHttpContext(httpContext, response); }); } [Fact] - public void should_have_content_length() + public async Task should_have_content_length() { var httpContext = new DefaultHttpContext(); var response = new DownstreamResponse(new StringContent("test"), HttpStatusCode.OK, new List>>(), "some reason"); - _responder.SetResponseOnHttpContext(httpContext, response).GetAwaiter().GetResult(); + await _responder.SetResponseOnHttpContext(httpContext, response); var header = httpContext.Response.Headers["Content-Length"]; header.First().ShouldBe("4"); } [Fact] - public void should_add_header() + public async Task should_add_header() { var httpContext = new DefaultHttpContext(); var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.OK, @@ -71,13 +66,13 @@ public void should_add_header() new("test", new List {"test"}), }, "some reason"); - _responder.SetResponseOnHttpContext(httpContext, response).GetAwaiter().GetResult(); + await _responder.SetResponseOnHttpContext(httpContext, response); var header = httpContext.Response.Headers["test"]; header.First().ShouldBe("test"); } [Fact] - public void should_add_reason_phrase() + public async Task should_add_reason_phrase() { var httpContext = new DefaultHttpContext(); var response = new DownstreamResponse(new StringContent(string.Empty), HttpStatusCode.OK, @@ -86,7 +81,7 @@ public void should_add_reason_phrase() new("test", new List {"test"}), }, "some reason"); - _responder.SetResponseOnHttpContext(httpContext, response).GetAwaiter().GetResult(); + await _responder.SetResponseOnHttpContext(httpContext, response); httpContext.Response.HttpContext.Features.Get().ReasonPhrase.ShouldBe(response.ReasonPhrase); }