Skip to content

Commit ef89a01

Browse files
NoahStolkrayokota
andauthored
Update NJsonSchema to v11 (#2263)
* Update NJsonSchema to v11 * Only compile with NJsonSchema v11 on .NET 8 * Multi-target Confluent.SchemaRegistry.Serdes.UnitTests --------- Co-authored-by: Robert Yokota <[email protected]>
1 parent 15e5ddd commit ef89a01

File tree

10 files changed

+132
-16
lines changed

10 files changed

+132
-16
lines changed

examples/JsonWithReferences/JsonWithReferences.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
55
<AssemblyName>JsonWithReferences</AssemblyName>
66
<OutputType>Exe</OutputType>
7-
<TargetFramework>net6.0</TargetFramework>
7+
<TargetFramework>net8.0</TargetFramework>
88
<LangVersion>7.1</LangVersion>
99
</PropertyGroup>
1010

examples/JsonWithReferences/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
using System.Collections.Generic;
2323
using System.Threading;
2424
using System.Threading.Tasks;
25-
using NJsonSchema.Generation;
2625
using Newtonsoft.Json;
2726
using Newtonsoft.Json.Serialization;
27+
using NJsonSchema.NewtonsoftJson.Generation;
2828

2929

3030
/// <summary>
@@ -150,7 +150,7 @@ static async Task Main(string[] args)
150150
// from default one to camelCase.
151151
// It's also possible to add JsonProperty attributes to customize
152152
// serialization mapping and all available NJson attributes.
153-
var jsonSchemaGeneratorSettings = new JsonSchemaGeneratorSettings
153+
var jsonSchemaGeneratorSettings = new NewtonsoftJsonSchemaGeneratorSettings
154154
{
155155
SerializerSettings = new JsonSerializerSettings
156156
{

src/Confluent.SchemaRegistry.Serdes.Json/Confluent.SchemaRegistry.Serdes.Json.csproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@
1616
<Title>Confluent.SchemaRegistry.Serdes.Json</Title>
1717
<AssemblyName>Confluent.SchemaRegistry.Serdes.Json</AssemblyName>
1818
<VersionPrefix>2.5.2</VersionPrefix>
19-
<TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
19+
<TargetFrameworks>netstandard2.0;net6.0;net8.0</TargetFrameworks>
2020
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
2121
<GenerateDocumentationFile>true</GenerateDocumentationFile>
2222
<SignAssembly>true</SignAssembly>
2323
<AssemblyOriginatorKeyFile>Confluent.SchemaRegistry.Serdes.Json.snk</AssemblyOriginatorKeyFile>
2424
</PropertyGroup>
2525

26-
<ItemGroup>
26+
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
27+
<PackageReference Include="NJsonSchema.NewtonsoftJson" Version="11.0.1" />
28+
</ItemGroup>
29+
30+
<ItemGroup Condition=" '$(TargetFramework)' != 'net8.0' ">
2731
<PackageReference Include="NJsonSchema" Version="10.9.0" />
2832
</ItemGroup>
2933

src/Confluent.SchemaRegistry.Serdes.Json/JsonDeserializer.cs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
using Newtonsoft.Json;
2626
using Newtonsoft.Json.Linq;
2727
using NJsonSchema;
28+
#if NET8_0_OR_GREATER
29+
using NJsonSchema.NewtonsoftJson.Generation;
30+
#else
2831
using NJsonSchema.Generation;
32+
#endif
2933
using NJsonSchema.Validation;
3034

3135

@@ -53,7 +57,11 @@ namespace Confluent.SchemaRegistry.Serdes
5357
/// </remarks>
5458
public class JsonDeserializer<T> : AsyncDeserializer<T, JsonSchema> where T : class
5559
{
60+
#if NET8_0_OR_GREATER
61+
private readonly NewtonsoftJsonSchemaGeneratorSettings jsonSchemaGeneratorSettings;
62+
#else
5663
private readonly JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings;
64+
#endif
5765

5866
private JsonSchemaValidator validator = new JsonSchemaValidator();
5967

@@ -69,18 +77,30 @@ public class JsonDeserializer<T> : AsyncDeserializer<T, JsonSchema> where T : cl
6977
/// <param name="jsonSchemaGeneratorSettings">
7078
/// JSON schema generator settings.
7179
/// </param>
80+
#if NET8_0_OR_GREATER
81+
public JsonDeserializer(IEnumerable<KeyValuePair<string, string>> config = null, NewtonsoftJsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null) :
82+
#else
7283
public JsonDeserializer(IEnumerable<KeyValuePair<string, string>> config = null, JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null) :
84+
#endif
7385
this(null, config, jsonSchemaGeneratorSettings)
7486
{
7587
}
7688

77-
public JsonDeserializer(ISchemaRegistryClient schemaRegistryClient, IEnumerable<KeyValuePair<string, string>> config = null, JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null)
89+
#if NET8_0_OR_GREATER
90+
public JsonDeserializer(ISchemaRegistryClient schemaRegistryClient, IEnumerable<KeyValuePair<string, string>> config = null, NewtonsoftJsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null)
91+
#else
92+
public JsonDeserializer(ISchemaRegistryClient schemaRegistryClient, IEnumerable<KeyValuePair<string, string>> config = null, JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null)
93+
#endif
7894
: this(schemaRegistryClient, config != null ? new JsonDeserializerConfig(config) : null, jsonSchemaGeneratorSettings)
7995
{
8096
}
8197

8298
public JsonDeserializer(ISchemaRegistryClient schemaRegistryClient, JsonDeserializerConfig config,
99+
#if NET8_0_OR_GREATER
100+
NewtonsoftJsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null, IList<IRuleExecutor> ruleExecutors = null)
101+
#else
83102
JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null, IList<IRuleExecutor> ruleExecutors = null)
103+
#endif
84104
: base(schemaRegistryClient, config, ruleExecutors)
85105
{
86106
this.jsonSchemaGeneratorSettings = jsonSchemaGeneratorSettings;
@@ -121,7 +141,12 @@ public JsonDeserializer(ISchemaRegistryClient schemaRegistryClient, JsonDeserial
121141
/// JSON schema generator settings.
122142
/// </param>
123143
public JsonDeserializer(ISchemaRegistryClient schemaRegistryClient, Schema schema, IEnumerable<KeyValuePair<string, string>> config = null,
124-
JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null) : this(schemaRegistryClient, config, jsonSchemaGeneratorSettings)
144+
#if NET8_0_OR_GREATER
145+
NewtonsoftJsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null)
146+
#else
147+
JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null)
148+
#endif
149+
: this(schemaRegistryClient, config, jsonSchemaGeneratorSettings)
125150
{
126151
JsonSchemaResolver utils = new JsonSchemaResolver(
127152
schemaRegistryClient, schema, this.jsonSchemaGeneratorSettings);
@@ -206,7 +231,11 @@ public override async Task<T> DeserializeAsync(ReadOnlyMemory<byte> data, bool i
206231
using (var jsonStream = new MemoryStream(array, headerSize, array.Length - headerSize))
207232
using (var jsonReader = new StreamReader(jsonStream, Encoding.UTF8))
208233
{
234+
#if NET8_0_OR_GREATER
235+
JToken json = Newtonsoft.Json.JsonConvert.DeserializeObject<JToken>(jsonReader.ReadToEnd(), this.jsonSchemaGeneratorSettings?.SerializerSettings);
236+
#else
209237
JToken json = Newtonsoft.Json.JsonConvert.DeserializeObject<JToken>(jsonReader.ReadToEnd(), this.jsonSchemaGeneratorSettings?.ActualSerializerSettings);
238+
#endif
210239
json = await ExecuteMigrations(migrations, isKey, subject, topic, context.Headers, json)
211240
.ContinueWith(t => (JToken)t.Result)
212241
.ConfigureAwait(continueOnCapturedContext: false);
@@ -243,7 +272,11 @@ public override async Task<T> DeserializeAsync(ReadOnlyMemory<byte> data, bool i
243272
}
244273
}
245274

275+
#if NET8_0_OR_GREATER
276+
value = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(serializedString, this.jsonSchemaGeneratorSettings?.SerializerSettings);
277+
#else
246278
value = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(serializedString, this.jsonSchemaGeneratorSettings?.ActualSerializerSettings);
279+
#endif
247280
}
248281
}
249282

src/Confluent.SchemaRegistry.Serdes.Json/JsonSchemaResolver.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
using NJsonSchema;
2121
using NJsonSchema.Generation;
2222
using Newtonsoft.Json.Linq;
23+
#if NET8_0_OR_GREATER
24+
using NJsonSchema.NewtonsoftJson.Generation;
25+
#endif
2326

2427

2528
namespace Confluent.SchemaRegistry.Serdes
@@ -112,7 +115,11 @@ private async Task<JsonSchema> GetSchemaUtil(Schema root)
112115
{
113116
NJsonSchema.Generation.JsonSchemaResolver schemaResolver =
114117
new NJsonSchema.Generation.JsonSchemaResolver(rootObject, this.jsonSchemaGeneratorSettings ??
118+
#if NET8_0_OR_GREATER
119+
new NewtonsoftJsonSchemaGeneratorSettings());
120+
#else
115121
new JsonSchemaGeneratorSettings());
122+
#endif
116123

117124
JsonReferenceResolver referenceResolver =
118125
new JsonReferenceResolver(schemaResolver);

src/Confluent.SchemaRegistry.Serdes.Json/JsonSerializer.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@
2424
using System.Net;
2525
using System.Threading.Tasks;
2626
using NJsonSchema;
27-
using NJsonSchema.Generation;
2827
using NJsonSchema.Validation;
2928
using Confluent.Kafka;
29+
#if NET8_0_OR_GREATER
30+
using NJsonSchema.NewtonsoftJson.Generation;
31+
#else
32+
using NJsonSchema.Generation;
33+
#endif
3034

3135

3236
namespace Confluent.SchemaRegistry.Serdes
@@ -54,7 +58,11 @@ namespace Confluent.SchemaRegistry.Serdes
5458
/// </remarks>
5559
public class JsonSerializer<T> : AsyncSerializer<T, JsonSchema> where T : class
5660
{
61+
#if NET8_0_OR_GREATER
62+
private readonly NewtonsoftJsonSchemaGeneratorSettings jsonSchemaGeneratorSettings;
63+
#else
5764
private readonly JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings;
65+
#endif
5866
private readonly List<SchemaReference> ReferenceList = new List<SchemaReference>();
5967

6068
private JsonSchemaValidator validator = new JsonSchemaValidator();
@@ -82,7 +90,11 @@ public class JsonSerializer<T> : AsyncSerializer<T, JsonSchema> where T : class
8290
/// JSON schema generator settings.
8391
/// </param>
8492
public JsonSerializer(ISchemaRegistryClient schemaRegistryClient, JsonSerializerConfig config = null,
93+
#if NET8_0_OR_GREATER
94+
NewtonsoftJsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null, IList<IRuleExecutor> ruleExecutors = null)
95+
#else
8596
JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null, IList<IRuleExecutor> ruleExecutors = null)
97+
#endif
8698
: base(schemaRegistryClient, config, ruleExecutors)
8799
{
88100
this.jsonSchemaGeneratorSettings = jsonSchemaGeneratorSettings;
@@ -136,7 +148,11 @@ public JsonSerializer(ISchemaRegistryClient schemaRegistryClient, JsonSerializer
136148
/// JSON schema generator settings.
137149
/// </param>
138150
public JsonSerializer(ISchemaRegistryClient schemaRegistryClient, Schema schema, JsonSerializerConfig config = null,
139-
JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null, IList<IRuleExecutor> ruleExecutors = null)
151+
#if NET8_0_OR_GREATER
152+
NewtonsoftJsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null, IList<IRuleExecutor> ruleExecutors = null)
153+
#else
154+
JsonSchemaGeneratorSettings jsonSchemaGeneratorSettings = null, IList<IRuleExecutor> ruleExecutors = null)
155+
#endif
140156
: this(schemaRegistryClient, config, jsonSchemaGeneratorSettings, ruleExecutors)
141157
{
142158
foreach (var reference in schema.References)
@@ -154,7 +170,7 @@ public JsonSerializer(ISchemaRegistryClient schemaRegistryClient, Schema schema,
154170

155171
/// <summary>
156172
/// Serialize an instance of type <typeparamref name="T"/> to a UTF8 encoded JSON
157-
/// represenation. The serialized data is preceeded by:
173+
/// representation. The serialized data is preceded by:
158174
/// 1. A "magic byte" (1 byte) that identifies this as a message with
159175
/// Confluent Platform framing.
160176
/// 2. The id of the schema as registered in Confluent's Schema Registry
@@ -233,7 +249,11 @@ public override async Task<byte[]> SerializeAsync(T value, SerializationContext
233249
.ConfigureAwait(continueOnCapturedContext: false);
234250
}
235251

252+
#if NET8_0_OR_GREATER
253+
var serializedString = Newtonsoft.Json.JsonConvert.SerializeObject(value, this.jsonSchemaGeneratorSettings?.SerializerSettings);
254+
#else
236255
var serializedString = Newtonsoft.Json.JsonConvert.SerializeObject(value, this.jsonSchemaGeneratorSettings?.ActualSerializerSettings);
256+
#endif
237257
var validationResult = validator.Validate(serializedString, this.schema);
238258
if (validationResult.Count > 0)
239259
{

test/Confluent.SchemaRegistry.Serdes.IntegrationTests/Confluent.SchemaRegistry.Serdes.IntegrationTests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
55
<TestProjectType>UnitTest</TestProjectType>
66
<AssemblyName>Confluent.SchemaRegistry.Serdes.IntegrationTests</AssemblyName>
7-
<TargetFramework>net6.0</TargetFramework>
7+
<TargetFramework>net8.0</TargetFramework>
88
</PropertyGroup>
99

1010
<ItemGroup>

test/Confluent.SchemaRegistry.Serdes.IntegrationTests/Tests_Json/UseReferences.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
using Newtonsoft.Json;
2323
using Newtonsoft.Json.Serialization;
2424
using Newtonsoft.Json.Linq;
25-
using NJsonSchema.Generation;
25+
using NJsonSchema.NewtonsoftJson.Generation;
2626

2727

2828
namespace Confluent.SchemaRegistry.Serdes.IntegrationTests
@@ -139,7 +139,7 @@ public static void UseReferences(string bootstrapServers, string schemaRegistryS
139139
var schemaRegistryConfig = new SchemaRegistryConfig { Url = schemaRegistryServers };
140140
var sr = new CachedSchemaRegistryClient(schemaRegistryConfig);
141141

142-
var jsonSchemaGeneratorSettings = new JsonSchemaGeneratorSettings
142+
var jsonSchemaGeneratorSettings = new NewtonsoftJsonSchemaGeneratorSettings
143143
{
144144
SerializerSettings = new JsonSerializerSettings
145145
{
@@ -209,7 +209,7 @@ public static void UseReferences(string bootstrapServers, string schemaRegistryS
209209

210210
// Test producing and consuming directly a JObject
211211
var serializedString = Newtonsoft.Json.JsonConvert.SerializeObject(order,
212-
jsonSchemaGeneratorSettings.ActualSerializerSettings);
212+
jsonSchemaGeneratorSettings.SerializerSettings);
213213
var jsonObject = JObject.Parse(serializedString);
214214

215215
using (var producer =

test/Confluent.SchemaRegistry.Serdes.UnitTests/Confluent.SchemaRegistry.Serdes.UnitTests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
55
<TestProjectType>UnitTest</TestProjectType>
66
<AssemblyName>Confluent.SchemaRegistry.Serdes.UnitTests</AssemblyName>
7-
<TargetFramework>net6.0</TargetFramework>
7+
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
88
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
99
</PropertyGroup>
1010

test/Confluent.SchemaRegistry.Serdes.UnitTests/JsonSerializeDeserialize.cs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,18 @@
2121
using Confluent.SchemaRegistry.Encryption;
2222
using Newtonsoft.Json;
2323
using Newtonsoft.Json.Serialization;
24-
using NJsonSchema.Generation;
2524
using System;
2625
using System.Collections.Generic;
2726
using System.IO;
2827
using System.Text;
2928
using System.Threading.Tasks;
3029
using Xunit;
30+
#if NET8_0_OR_GREATER
31+
using Newtonsoft.Json.Converters;
32+
using NJsonSchema.NewtonsoftJson.Generation;
33+
#else
34+
using NJsonSchema.Generation;
35+
#endif
3136

3237

3338
namespace Confluent.SchemaRegistry.Serdes.UnitTests
@@ -176,7 +181,11 @@ public async Task WithJsonSerializerSettingsSerDe()
176181
{
177182
const int value = 1234;
178183
var expectedJson = $"{{\"Value\":{value * 2}}}";
184+
#if NET8_0_OR_GREATER
185+
var jsonSchemaGeneratorSettings = new NewtonsoftJsonSchemaGeneratorSettings
186+
#else
179187
var jsonSchemaGeneratorSettings = new JsonSchemaGeneratorSettings
188+
#endif
180189
{
181190
SerializerSettings = new JsonSerializerSettings
182191
{
@@ -227,7 +236,11 @@ public async Task WithJsonSchemaExternalReferencesAsync()
227236
SubjectNameStrategy = SubjectNameStrategy.TopicRecord
228237
};
229238

239+
#if NET8_0_OR_GREATER
240+
var jsonSchemaGeneratorSettings = new NewtonsoftJsonSchemaGeneratorSettings
241+
#else
230242
var jsonSchemaGeneratorSettings = new JsonSchemaGeneratorSettings
243+
#endif
231244
{
232245
SerializerSettings = new JsonSerializerSettings
233246
{
@@ -256,6 +269,44 @@ public async Task WithJsonSchemaExternalReferencesAsync()
256269
Assert.Equal(v.Field3, actual.Field3);
257270
}
258271

272+
#if NET8_0_OR_GREATER
273+
[Theory]
274+
[InlineData("CamelCaseString", EnumType.EnumValue, "{\"Value\":\"enumValue\"}")]
275+
[InlineData("String", EnumType.None, "{\"Value\":\"None\"}")]
276+
[InlineData("Integer", EnumType.OtherValue, "{\"Value\":5678}")]
277+
public async Task WithJsonSchemaGeneratorSettingsSerDe(string enumHandling, EnumType value,
278+
string expectedJson)
279+
{
280+
var serializerSettings = enumHandling switch
281+
{
282+
"CamelCaseString" => new JsonSerializerSettings { Converters = { new StringEnumConverter(new CamelCaseNamingStrategy()) } },
283+
"String" => new JsonSerializerSettings { Converters = { new StringEnumConverter() } },
284+
"Integer" => new JsonSerializerSettings(),
285+
_ => throw new ArgumentException("Invalid enumHandling value", nameof(enumHandling)),
286+
};
287+
288+
var jsonSchemaGeneratorSettings = new NewtonsoftJsonSchemaGeneratorSettings
289+
{
290+
SerializerSettings = serializerSettings,
291+
};
292+
293+
var jsonSerializer = new JsonSerializer<EnumObject>(schemaRegistryClient,
294+
jsonSchemaGeneratorSettings: jsonSchemaGeneratorSettings);
295+
var jsonDeserializer =
296+
new JsonDeserializer<EnumObject>(jsonSchemaGeneratorSettings: jsonSchemaGeneratorSettings);
297+
298+
var v = new EnumObject { Value = value };
299+
var bytes = await jsonSerializer.SerializeAsync(v,
300+
new SerializationContext(MessageComponentType.Value, testTopic));
301+
Assert.NotNull(bytes);
302+
Assert.Equal(expectedJson, Encoding.UTF8.GetString(bytes.AsSpan().Slice(5)));
303+
304+
var actual = await jsonDeserializer.DeserializeAsync(bytes, false,
305+
new SerializationContext(MessageComponentType.Value, testTopic));
306+
Assert.NotNull(actual);
307+
Assert.Equal(actual.Value, value);
308+
}
309+
#else
259310
[Theory]
260311
[InlineData(EnumHandling.CamelCaseString, EnumType.EnumValue, "{\"Value\":\"enumValue\"}")]
261312
[InlineData(EnumHandling.String, EnumType.None, "{\"Value\":\"None\"}")]
@@ -284,6 +335,7 @@ public async Task WithJsonSchemaGeneratorSettingsSerDe(EnumHandling enumHandling
284335
Assert.NotNull(actual);
285336
Assert.Equal(actual.Value, value);
286337
}
338+
#endif
287339

288340
[Fact]
289341
public async Task ValidationFailureReturnsPath()

0 commit comments

Comments
 (0)