Skip to content

Commit 0e4765b

Browse files
authored
Add config for validating payloads against JSON Schema (#2350)
1 parent b2e4bfd commit 0e4765b

File tree

4 files changed

+52
-5
lines changed

4 files changed

+52
-5
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ public class JsonDeserializer<T> : AsyncDeserializer<T, JsonSchema> where T : cl
6363

6464
private JsonSchema schema = null;
6565

66+
private bool validate = true;
67+
6668
private JsonSerializerSettings jsonSchemaGeneratorSettingsSerializerSettings {
6769
get =>
6870
#if NET8_0_OR_GREATER
@@ -110,6 +112,7 @@ public JsonDeserializer(ISchemaRegistryClient schemaRegistryClient, JsonDeserial
110112
if (config.UseLatestVersion != null) { this.useLatestVersion = config.UseLatestVersion.Value; }
111113
if (config.UseLatestWithMetadata != null) { this.useLatestWithMetadata = config.UseLatestWithMetadata; }
112114
if (config.SubjectNameStrategy != null) { this.subjectNameStrategy = config.SubjectNameStrategy.Value.ToDelegate(); }
115+
if (config.Validate!= null) { this.validate= config.Validate.Value; }
113116
}
114117

115118
/// <summary>
@@ -228,10 +231,9 @@ public override async Task<T> DeserializeAsync(ReadOnlyMemory<byte> data, bool i
228231
.ContinueWith(t => (JToken)t.Result)
229232
.ConfigureAwait(continueOnCapturedContext: false);
230233

231-
if (schema != null)
234+
if (schema != null && validate)
232235
{
233236
var validationResult = validator.Validate(json, schema);
234-
235237
if (validationResult.Count > 0)
236238
{
237239
throw new InvalidDataException("Schema validation failed for properties: [" +

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ public static class PropertyNames
5353
/// Possible values: <see cref="Confluent.SchemaRegistry.SubjectNameStrategy" />
5454
/// </summary>
5555
public const string SubjectNameStrategy = "json.deserializer.subject.name.strategy";
56+
57+
/// <summary>
58+
/// Specifies whether to validate payloads against the schema.
59+
///
60+
/// default: true
61+
/// </summary>
62+
public const string Validate= "json.serializer.validate";
5663
}
5764

5865

@@ -124,5 +131,18 @@ public SubjectNameStrategy? SubjectNameStrategy
124131
else { this.properties[PropertyNames.SubjectNameStrategy] = value.ToString(); }
125132
}
126133
}
134+
135+
136+
/// <summary>
137+
/// Specifies whether or not the JSON serializer should attempt to
138+
/// validate the payload against the schema.
139+
///
140+
/// default: true
141+
/// </summary>
142+
public bool? Validate
143+
{
144+
get { return GetBool(PropertyNames.Validate); }
145+
set { SetObject(PropertyNames.Validate, value); }
146+
}
127147
}
128148
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ public class JsonSerializer<T> : AsyncSerializer<T, JsonSchema> where T : class
7575
private string schemaText;
7676
private string schemaFullname;
7777

78+
private bool validate = true;
79+
7880
private JsonSerializerSettings jsonSchemaGeneratorSettingsSerializerSettings {
7981
get =>
8082
#if NET8_0_OR_GREATER
@@ -129,6 +131,7 @@ public JsonSerializer(ISchemaRegistryClient schemaRegistryClient, JsonSerializer
129131
if (config.LatestCompatibilityStrict != null) { this.latestCompatibilityStrict = config.LatestCompatibilityStrict.Value; }
130132
if (config.UseLatestWithMetadata != null) { this.useLatestWithMetadata = config.UseLatestWithMetadata; }
131133
if (config.SubjectNameStrategy != null) { this.subjectNameStrategy = config.SubjectNameStrategy.Value.ToDelegate(); }
134+
if (config.Validate!= null) { this.validate= config.Validate.Value; }
132135

133136
if (this.useLatestVersion && this.autoRegisterSchema)
134137
{
@@ -245,10 +248,13 @@ public override async Task<byte[]> SerializeAsync(T value, SerializationContext
245248
}
246249

247250
var serializedString = Newtonsoft.Json.JsonConvert.SerializeObject(value, jsonSchemaGeneratorSettingsSerializerSettings);
248-
var validationResult = validator.Validate(serializedString, this.schema);
249-
if (validationResult.Count > 0)
251+
if (validate)
250252
{
251-
throw new InvalidDataException("Schema validation failed for properties: [" + string.Join(", ", validationResult.Select(r => r.Path)) + "]");
253+
var validationResult = validator.Validate(serializedString, this.schema);
254+
if (validationResult.Count > 0)
255+
{
256+
throw new InvalidDataException("Schema validation failed for properties: [" + string.Join(", ", validationResult.Select(r => r.Path)) + "]");
257+
}
252258
}
253259

254260
using (var stream = new MemoryStream(initialBufferSize))

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ public static class PropertyNames
9292
/// Possible values: <see cref="Confluent.SchemaRegistry.SubjectNameStrategy" />
9393
/// </summary>
9494
public const string SubjectNameStrategy = "json.serializer.subject.name.strategy";
95+
96+
/// <summary>
97+
/// Specifies whether to validate payloads against the schema.
98+
///
99+
/// default: true
100+
/// </summary>
101+
public const string Validate= "json.serializer.validate";
95102
}
96103

97104

@@ -220,5 +227,17 @@ public SubjectNameStrategy? SubjectNameStrategy
220227
}
221228
}
222229

230+
231+
/// <summary>
232+
/// Specifies whether or not the JSON serializer should attempt to
233+
/// validate the payload against the schema.
234+
///
235+
/// default: true
236+
/// </summary>
237+
public bool? Validate
238+
{
239+
get { return GetBool(PropertyNames.Validate); }
240+
set { SetObject(PropertyNames.Validate, value); }
241+
}
223242
}
224243
}

0 commit comments

Comments
 (0)