Skip to content
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

Refactor all tests that use LitJson to use System Text Json #3618

Merged
merged 2 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions sdk/src/Core/Amazon.Util/Internal/JsonSerializerHelper.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Text.Json;

#if NET8_0_OR_GREATER
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
#endif
Expand All @@ -12,6 +13,13 @@ namespace Amazon.Util.Internal
{
public static class JsonSerializerHelper
{
private static System.Text.Json.JsonSerializerOptions options = new System.Text.Json.JsonSerializerOptions
{
AllowTrailingCommas = true,
};

// compile regex once to avoid re-parsing every time
private static readonly System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"(""[^""]*""|\d+)(\s*""[^""]*""\s*:)", System.Text.RegularExpressions.RegexOptions.Compiled);
#if NET8_0_OR_GREATER
public static T Deserialize<T>(string json, JsonSerializerContext context)
{
Expand All @@ -25,21 +33,26 @@ public static string Serialize<T>(object obj, JsonSerializerContext context)
#else
public static T Deserialize<T>(string json, JsonSerializerContext typeInfo)
{
return ThirdParty.Json.LitJson.JsonMapper.ToObject<T>(json);
string sanitizedJson = SanitizeJson(json);
return JsonSerializer.Deserialize<T>(sanitizedJson, options);
}

public static string Serialize<T>(object obj, JsonSerializerContext typeInfo)
{
var json = new StringBuilder();
var writer = new ThirdParty.Json.LitJson.JsonWriter(json)
var jsonSerializerOptions = new System.Text.Json.JsonSerializerOptions
{
PrettyPrint = (typeInfo?.Options?.WriteIndented).GetValueOrDefault()
WriteIndented = (typeInfo?.Options?.WriteIndented).GetValueOrDefault()
};

ThirdParty.Json.LitJson.JsonMapper.ToJson(obj, writer);
return json.ToString();
return JsonSerializer.Serialize(obj, jsonSerializerOptions);
}
#endif
public static string SanitizeJson(string rawJson)
{
// Add a comma after numbers or strings if they're not followed by a closing brace/bracket or comma.
rawJson = regex.Replace(rawJson, "$1,$2");
return rawJson;
}
}

[JsonSerializable(typeof(IAMInstanceProfileMetadata))]
Expand Down Expand Up @@ -104,7 +117,7 @@ public class JsonSerializerContext
{
public JsonSerializerContext() { }

public JsonSerializerContext(JsonSerializerOptions defaultOptions)
public JsonSerializerContext(JsonSerializerOptions defaultOptions)
{
Options = defaultOptions;
}
Expand All @@ -118,12 +131,12 @@ public class JsonSerializerOptions
{
public bool PropertyNameCaseInsensitive { get; set; }

public bool WriteIndented {get;set;}
public bool WriteIndented { get; set; }
}

#pragma warning disable CA1019 // Since this is a dummy implementation of JsonSerializableAttribute for pre .NET 8 targets we don't need the accessor.
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public sealed class JsonSerializableAttribute : Attribute { public JsonSerializableAttribute(Type type) { } }
#pragma warning restore CA1019
#endif
}
}
22 changes: 13 additions & 9 deletions sdk/src/Services/SimpleNotificationService/Custom/Util/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
using Amazon.Runtime;
using Amazon.Util;

using ThirdParty.Json.LitJson;
using System.Text.Json;

using Amazon.Runtime.Internal.Util;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Amazon.Util.Internal;

namespace Amazon.SimpleNotificationService.Util
{
Expand Down Expand Up @@ -54,18 +55,21 @@ private Message()
public static Message ParseMessage(string messageText)
{
var message = new Message();

var jsonData = JsonMapper.ToObject(messageText);
JsonDocument jsonData;
jsonData = JsonDocument.Parse(messageText);

Func<string, string> extractField = ((fieldName) =>
{
if (jsonData[fieldName] != null && jsonData[fieldName].IsString)
return (string)jsonData[fieldName];

if (jsonData.RootElement.TryGetProperty(fieldName, out var value) && value.ValueKind == JsonValueKind.String)
{
return value.GetString();
}
var anyCaseKey = jsonData.RootElement.EnumerateObject().FirstOrDefault(x => string.Equals(x.Name, fieldName, StringComparison.OrdinalIgnoreCase));
// Check to see if the field can be found with a different case.
var anyCaseKey = jsonData.PropertyNames.FirstOrDefault(x => string.Equals(x, fieldName, StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrEmpty(anyCaseKey) && jsonData[anyCaseKey] != null && jsonData[anyCaseKey].IsString)
return (string)jsonData[anyCaseKey];
if (!string.IsNullOrEmpty(anyCaseKey.Value.ToString()) && anyCaseKey.Value.ValueKind == JsonValueKind.String)
{
return anyCaseKey.Value.GetString();
}

return null;
});
Expand Down
5 changes: 3 additions & 2 deletions sdk/test/IntegrationTests/Tests/General.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
using Amazon.DynamoDBv2;
using Amazon.ElasticTranscoder;
using System.Threading;
using System.Text.Json;
using AWSSDK_DotNet.CommonTest.Utils;

namespace AWSSDK_DotNet.IntegrationTests.Tests
Expand Down Expand Up @@ -460,12 +461,12 @@ private static void TestException(Exception e)
public void JsonCountSerializationBug()
{
var json = @"{""Data"":{""NotCount"":""42""}}";
var poco = ThirdParty.Json.LitJson.JsonMapper.ToObject<Poco>(json);
var poco = JsonSerializer.Deserialize<Poco>(json);
Assert.AreEqual(1, poco.Data.Count);
Assert.AreEqual("42", poco.Data["NotCount"]);

json = @"{""Data"":{""Count"":""Dracula""}}";
poco = ThirdParty.Json.LitJson.JsonMapper.ToObject<Poco>(json);
poco = JsonSerializer.Deserialize<Poco>(json);
Assert.AreEqual(1, poco.Data.Count);
Assert.AreEqual("Dracula", poco.Data["Count"]);
}
Expand Down
21 changes: 16 additions & 5 deletions sdk/test/IntegrationTests/Tests/NetFramework/TestNetFramework.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
using System.Configuration;
using System.Collections.Specialized;
using System.Xml;
using System.IO;
using System.Text.Json;
using System.Text;


namespace AWSSDK_DotNet.IntegrationTests.Tests
Expand Down Expand Up @@ -83,11 +86,19 @@ public void TestResponseMocking()
httpResponse.Headers.Remove("x-amz-crc32");

// modify body
var json = ThirdParty.Json.LitJson.JsonMapper.ToObject(httpResponse.Body);
var tableNames = json["TableNames"];
tableNames.Clear();
tableNames.Add("Logs");
httpResponse.Body = json.ToJson();
using (var memoryStream = new MemoryStream())
using (var writer = new Utf8JsonWriter(memoryStream))
{
writer.WriteStartObject();
writer.WritePropertyName("TableNames");
writer.WriteStartArray();
writer.WriteStringValue("Logs"); // Add a new table name
writer.WriteEndArray();
writer.WriteEndObject();
writer.Flush();
var newBody = Encoding.UTF8.GetString(memoryStream.ToArray());
httpResponse.Body = newBody;
}

return httpResponse;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Amazon.Glacier.Transfer;
using Amazon.Runtime;
using Xunit;
using ThirdParty.Json.LitJson;
using Amazon;
using System.Threading.Tasks;
using System.Security.Cryptography;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Amazon.DynamoDBv2.Model;
using Amazon.DynamoDBv2.DocumentModel;
using System.IO;
using ThirdParty.Json.LitJson;
using System.Xml;

using Xunit;
Expand Down
48 changes: 33 additions & 15 deletions sdk/test/NetStandard/IntegrationTests/IntegrationTests/SNS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

using System.Threading;
using System.Threading.Tasks;
using ThirdParty.Json.LitJson;

using System.Text.Json;
using Amazon.Runtime.SharedInterfaces;
using Amazon.SimpleNotificationService;
using Amazon.SimpleNotificationService.Model;
Expand Down Expand Up @@ -276,11 +275,30 @@ public async void IsMessageSignatureValidInvalidSignatureVersion()
var bodyJson = GetBodyJson(messages[0]);

// modify message to have invalid SignatureVersion
var jsonData = JsonMapper.ToObject(bodyJson);
jsonData["SignatureVersion"] = "3";
var jsonData = JsonDocument.Parse(bodyJson);
using var memoryStream = new MemoryStream();
using (var writer = new Utf8JsonWriter(memoryStream))
{
writer.WriteStartObject();
foreach (var property in jsonData.RootElement.EnumerateObject())
{
if (property.Name == "SignatureVersion")
{
writer.WriteString("SignatureVersion", "3");
}
else
{
property.WriteTo(writer);
}
}

var ex = Assert.Throws<AmazonClientException>(() => Amazon.SimpleNotificationService.Util.Message.ParseMessage(jsonData.ToJson()));
Assert.Equal("SignatureVersion is not a valid value", ex.Message);
writer.WriteEndObject();
writer.Flush();
string updatedJson = Encoding.UTF8.GetString(memoryStream.ToArray());

var ex = Assert.Throws<AmazonClientException>(() => Amazon.SimpleNotificationService.Util.Message.ParseMessage(updatedJson));
Assert.Equal("SignatureVersion is not a valid value", ex.Message);
}
}

[Fact]
Expand All @@ -298,21 +316,21 @@ public async void TestQueueSubscription()

string bodyJson = GetBodyJson(message);

var json = ThirdParty.Json.LitJson.JsonMapper.ToObject(bodyJson);
var messageText = json["Message"];
var messageSubject = json["Subject"];
var json = JsonDocument.Parse(bodyJson);
var messageText = json.RootElement.GetProperty("Message");
var messageSubject = json.RootElement.GetProperty("Subject");
Assert.Equal(publishRequest.Message, messageText.ToString());
Assert.Equal(publishRequest.Subject, messageSubject.ToString());
var messageAttributes = json["MessageAttributes"];
Assert.Equal(publishRequest.MessageAttributes.Count, messageAttributes.Count);
var messageAttributes = json.RootElement.GetProperty("MessageAttributes");
Assert.Equal(publishRequest.MessageAttributes.Count, messageAttributes.EnumerateObject().Count());
foreach (var ma in publishRequest.MessageAttributes)
{
var name = ma.Key;
var value = ma.Value;
Assert.Contains(name, messageAttributes.PropertyNames, StringComparer.Ordinal);
var jsonAttribute = messageAttributes[name];
var jsonType = jsonAttribute["Type"].ToString();
var jsonValue = jsonAttribute["Value"].ToString();
Assert.Contains(name, messageAttributes.EnumerateObject().Select(x => x.Name), StringComparer.Ordinal);
var jsonAttribute = messageAttributes.GetProperty(name);
var jsonType = jsonAttribute.GetProperty("Type").ToString();
var jsonValue = jsonAttribute.GetProperty("Value").ToString();
Assert.NotNull(jsonType);
Assert.NotNull(jsonValue);
Assert.Equal(value.DataType, jsonType);
Expand Down
Loading