-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove the Newtonsoft.Json
package and migrate to System.Text.Json
#2125
base: develop
Are you sure you want to change the base?
Conversation
build - Skipped |
Mohsen, if you don't mind, I will rebase the branch once again... I hope to fix the build. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the moment, I would appreciate it if you could eliminate all non-substantive changes such as:
- End of line characters
- Fixes to whitespace issues
- Formatting corrections
If this cannot be done, please inform me, and I will assist you. Let's concentrate on the actual changes.
Very well❕ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the excellent benchmark testing with the new JsonSerializerBenchmark
class!
I'm concerned that a direct upgrade to the Microsoft native library might work, but it could cause issues or even breaking changes for our development consumers. Therefore, we need to seek a more advanced and gentle solution through redesign.
My suggestions are:
- Maintain the old
Newtonsoft.Json
reference indefinitely for backward compatibility. - Implement the new
System.Text.Json
functionality and set it as the default, as your PR suggests. - Create a new
Ocelot.Infrastructure.JsonUtil
helper to establish a concrete dependency on the consumed library (requires a new Core infrastructure interface). - Introduce a new global JSON setting in the
GlobalConfiguration
ofocelot.json
, such asJsonOptions
and aType
property, to choose between usingNewtonsoft.Json
orSystem.Text.Json
libraries. - Instantiate and delegate serialization operations to the actual parser instance.
- Inject the new interface object into all consuming classes through the DI mechanism.
This method is more adaptable: we maintain backward compatibility while gradually transitioning to Microsoft's implementations to enhance performance.
@@ -132,7 +132,14 @@ Current `implementation <https://github.com/search?q=repo%3AThreeMammals%2FOcelo | |||
.AddApplicationPart(assembly) | |||
.AddControllersAsServices() | |||
.AddAuthorization() | |||
.AddNewtonsoftJson(); | |||
.AddJsonOptions(op => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm hesitant to rewrite the documentation until all the code has been verified and approved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not believe we have the authority to change the default settings of the library. Providing recommendations in the documentation to the community should have reasonable goals!
I do not think all Ocelot solutions on the Internet should adhere to these JSON options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change does not change the library's behavior, so changing this method does not cause any problems.
@@ -154,74 +161,6 @@ The next section shows you an example of designing custom Ocelot pipeline by cus | |||
|
|||
.. _di-custom-builder: | |||
|
|||
Custom Builder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that this sample might contain outdated code, yet it's essential to convert it into something usable. The sample illustrates how to override the default services in the DI feature. We can demonstrate how to revert to the old NewtonSoft services using new package versions. However, the rewriting should be deferred until all C# code is approved. Ultimately, updating the documentation should be the final step in the PR process.
@@ -53,14 +54,14 @@ public async Task<Response<FileConfiguration>> Get() | |||
|
|||
var bytes = queryResult.Response.Value; | |||
var json = Encoding.UTF8.GetString(bytes); | |||
var consulConfig = JsonConvert.DeserializeObject<FileConfiguration>(json); | |||
var consulConfig = JsonSerializer.Deserialize<FileConfiguration>(json, JsonSerializerOptionsExtensions.Web); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well... The new JsonSerializer
is from the System.Text.Json
namespace.
But the package depends on Ocelot one and it consumes Ocelot interfaces.
Such hard changes constitute a major upgrade of the Ocelot Core and may introduce a breaking change, which will be detailed in the Release Notes.
I believe we need a more advanced solution.
Finally, the package should depend on Ocelot interfaces only!
@EngRajabi @MohammadAminPourmoradian Mohsen and Mohammad, congratulations! The PR has entered the official code review stage. The build is green and stable now. I've made some on-the-fly code review adjustments, including superficial changes. The pull request is now well-prepared for an easy review. @ggnaegi @RaynaldM Hello, I anticipate your thorough code review due to the significant and important upgrade in the Core involving the replacement of the JSON parsing library. I would value your consideration of my proposal to redesign the current draft solution, as I foresee potential issues. |
You gave a good suggestion, but is it really that much work? |
@raman-m let's check this... |
61baceb
to
93bea24
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JsonPath.Net
reference must be removed❗
By including this library reference, you are breaching our Development Process for the Ocelot core package! Refer to point 5:
The main Ocelot package must not have taken on any non MS dependencies.
The significant issue with this PR is the included reference. It is essential to eliminate this reference and begin utilizing the full capabilities of native Microsoft functionality: native .NET classes or native target lib.
@MohammadAminPourmoradian |
I replaced |
fdca813
to
9ae0cc4
Compare
../test/Ocelot.UnitTests/Requester/MessageInvokerPoolTests.cs
../test/Ocelot.IntegrationTests/ocelot.json
../test/Ocelot.AcceptanceTests/Steps.cs
../test/Ocelot.AcceptanceTests/Steps.cs
../src/Ocelot/Requester/MessageInvokerPool.cs
20e5411
to
6b67250
Compare
Now the build is green 🟢 Very well! @EngRajabi Please be aware that this is the final assistance I will provide. If you violate the Dev Process again, you will be banned due to multiple notifications last year. |
Ready for Review❕@ggnaegi @RaynaldM FYI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ggnaegi @RaynaldM Please note that Microsoft continues to support the Microsoft.AspNetCore.Mvc.NewtonsoftJson
package with the latest 9.0.0 version.
Ocelot/src/Ocelot/Ocelot.csproj
Line 50 in 9304dd2
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.0" /> |
However the
Newtonsoft.Json
package was not released .NET 7, 8, or 9, indicating that maintenance may have been discontinued. The last .NET 6 release was on March 8, 2023.Given that Microsoft supports the
Microsoft.AspNetCore.Mvc.NewtonsoftJson
package, which we utilize in Ocelot, I believe we should retain the reference for backward compatibility.
@@ -132,7 +132,14 @@ Current `implementation <https://github.com/search?q=repo%3AThreeMammals%2FOcelo | |||
.AddApplicationPart(assembly) | |||
.AddControllersAsServices() | |||
.AddAuthorization() | |||
.AddNewtonsoftJson(); | |||
.AddJsonOptions(op => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not believe we have the authority to change the default settings of the library. Providing recommendations in the documentation to the community should have reasonable goals!
I do not think all Ocelot solutions on the Internet should adhere to these JSON options.
op.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString; | ||
op.JsonSerializerOptions.WriteIndented = false; | ||
op.JsonSerializerOptions.PropertyNameCaseInsensitive = true; | ||
op.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain the final goal of these changes to me please?
What problem do these settings solve?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This setting prevents characters from being escaped when creating JSON. It causes problems in Arabic, Persian, etc. languages.
[JsonPropertyName("access_token")] | ||
public string AccessToken { get; set; } | ||
|
||
[JsonProperty("expires_in")] | ||
[JsonPropertyName("expires_in")] | ||
public int ExpiresIn { get; set; } | ||
|
||
[JsonProperty("token_type")] | ||
[JsonPropertyName("token_type")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the ultimate goal of transitioning from the Newtonsoft.Json
library to System.Text.Json
in all tests?
I am struggling to understand it.
The old Newtonsoft helpers are already performing the testing, so why should we change the lib in testing projects?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because I moved the entire library to System.Text.Json . It's better to do this complete migration.
@@ -25,8 +25,11 @@ | |||
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="8.0.0" /> | |||
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" /> | |||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0-dev-02301" /> | |||
<PackageReference Include="Bogus" Version="35.5.1" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the Bogus
library? Why did you include the reference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This library is used to generate data for tests. Data is required for json testing.
@@ -49,14 +50,14 @@ public Task<Response<FileConfiguration>> Get() | |||
jsonConfiguration = FileSys.ReadAllText(_environmentFile.FullName); | |||
} | |||
|
|||
var fileConfiguration = JsonConvert.DeserializeObject<FileConfiguration>(jsonConfiguration); | |||
var fileConfiguration = JsonSerializer.Deserialize<FileConfiguration>(jsonConfiguration, JsonSerializerOptionsFactory.Web); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not in favor of maintaining this direct dependency. It is time to decouple this logic. As I previously suggested, we should introduce a new utility service in the infrastructure, and its interface must be injected into all constructors in Ocelot. My concern is about utilizing only one utility, whereas the community desires more libs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separation is good but it has its problems.
For example, you separate the Json lib but use JsonPropertyName inside your classes. This makes separation meaningless.
In this request, we deleted the newtonsoft package and migrated to text json system.
The reason for the changes
The changes given include the removal of Newtonsoft. A benchmark has also been added for this
@MohammadAminPourmoradian helped me with this
BenchmarkDotNet v0.13.11, Windows 11 (10.0.22631.3880/23H2/2023Update/SunValley3)
Intel Core i7-10870H CPU 2.20GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK 8.0.303
[Host] : .NET 6.0.32 (6.0.3224.31407), X64 RyuJIT AVX2 [AttachedDebugger]
.NET 8.0 : .NET 8.0.7 (8.0.724.31311), X64 RyuJIT AVX2
Job=.NET 8.0 Runtime=.NET 8.0