Skip to content

Commit 34e8ccc

Browse files
committed
Fix JSON Schema validation
1 parent e3fbc00 commit 34e8ccc

File tree

2 files changed

+41
-23
lines changed

2 files changed

+41
-23
lines changed

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

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public class JsonDeserializer<T> : AsyncDeserializer<T, JsonSchema> where T : cl
6161

6262
private JsonSchemaValidator validator = new JsonSchemaValidator();
6363

64+
private Schema schemaJson = null;
65+
6466
private JsonSchema schema = null;
6567

6668
private bool validate = true;
@@ -142,6 +144,7 @@ public JsonDeserializer(ISchemaRegistryClient schemaRegistryClient, Schema schem
142144
JsonSchemaResolver utils = new JsonSchemaResolver(
143145
schemaRegistryClient, schema, this.jsonSchemaGeneratorSettings);
144146
JsonSchema jsonSchema = utils.GetResolvedSchema().Result;
147+
this.schemaJson = schema;
145148
this.schema = jsonSchema;
146149
}
147150

@@ -184,8 +187,10 @@ public override async Task<T> DeserializeAsync(ReadOnlyMemory<byte> data, bool i
184187

185188
try
186189
{
187-
Schema writerSchema = null;
188-
JsonSchema writerSchemaJson = null;
190+
Schema writerSchemaJson = null;
191+
JsonSchema writerSchema = null;
192+
Schema readerSchemaJson;
193+
JsonSchema readerSchema;
189194
T value;
190195
IList<Migration> migrations = new List<Migration>();
191196
using (var stream = new MemoryStream(array))
@@ -201,22 +206,34 @@ public override async Task<T> DeserializeAsync(ReadOnlyMemory<byte> data, bool i
201206

202207
if (schemaRegistryClient != null)
203208
{
204-
(writerSchema, writerSchemaJson) = await GetSchema(subject, writerId);
209+
(writerSchemaJson, writerSchema) = await GetSchema(subject, writerId);
205210
if (subject == null)
206211
{
207-
subject = GetSubjectName(topic, isKey, writerSchemaJson.Title);
212+
subject = GetSubjectName(topic, isKey, writerSchema.Title);
208213
if (subject != null)
209214
{
210215
latestSchema = await GetReaderSchema(subject)
211216
.ConfigureAwait(continueOnCapturedContext: false);
212217
}
213218
}
214219
}
215-
220+
216221
if (latestSchema != null)
217222
{
218-
migrations = await GetMigrations(subject, writerSchema, latestSchema)
223+
migrations = await GetMigrations(subject, writerSchemaJson, latestSchema)
219224
.ConfigureAwait(continueOnCapturedContext: false);
225+
readerSchemaJson = latestSchema;
226+
readerSchema = await GetParsedSchema(latestSchema);
227+
}
228+
else if (schema != null)
229+
{
230+
readerSchemaJson = schemaJson;
231+
readerSchema = schema;
232+
}
233+
else
234+
{
235+
readerSchemaJson = writerSchemaJson;
236+
readerSchema = writerSchema;
220237
}
221238

222239
if (migrations.Count > 0)
@@ -231,9 +248,9 @@ public override async Task<T> DeserializeAsync(ReadOnlyMemory<byte> data, bool i
231248
.ContinueWith(t => (JToken)t.Result)
232249
.ConfigureAwait(continueOnCapturedContext: false);
233250

234-
if (schema != null && validate)
251+
if (readerSchema != null && validate)
235252
{
236-
var validationResult = validator.Validate(json, schema);
253+
var validationResult = validator.Validate(json, readerSchema);
237254
if (validationResult.Count > 0)
238255
{
239256
throw new InvalidDataException("Schema validation failed for properties: [" +
@@ -250,10 +267,10 @@ public override async Task<T> DeserializeAsync(ReadOnlyMemory<byte> data, bool i
250267
using (var jsonReader = new StreamReader(jsonStream, Encoding.UTF8))
251268
{
252269
string serializedString = jsonReader.ReadToEnd();
253-
254-
if (schema != null && validate)
270+
271+
if (readerSchema != null && validate)
255272
{
256-
var validationResult = validator.Validate(serializedString, schema);
273+
var validationResult = validator.Validate(serializedString, readerSchema);
257274

258275
if (validationResult.Count > 0)
259276
{
@@ -266,14 +283,10 @@ public override async Task<T> DeserializeAsync(ReadOnlyMemory<byte> data, bool i
266283
jsonSchemaGeneratorSettingsSerializerSettings);
267284
}
268285
}
269-
270-
// A schema is not required to deserialize json messages.
271-
// TODO: add validation capability.
272286
}
273-
if (writerSchema != null)
287+
288+
if (readerSchema != null)
274289
{
275-
Schema readerSchemaJson = latestSchema ?? writerSchema;
276-
JsonSchema readerSchema = latestSchema != null ? await GetParsedSchema(latestSchema) : writerSchemaJson;
277290
FieldTransformer fieldTransformer = async (ctx, transform, message) =>
278291
{
279292
return await JsonUtils.Transform(ctx, readerSchema, "$", message, transform).ConfigureAwait(false);
@@ -283,8 +296,8 @@ public override async Task<T> DeserializeAsync(ReadOnlyMemory<byte> data, bool i
283296
readerSchemaJson, value, fieldTransformer)
284297
.ContinueWith(t => (T)t.Result)
285298
.ConfigureAwait(continueOnCapturedContext: false);
286-
}
287-
299+
}
300+
288301
return value;
289302
}
290303
catch (AggregateException e)

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,25 +232,30 @@ public override async Task<byte[]> SerializeAsync(T value, SerializationContext
232232
{
233233
serdeMutex.Release();
234234
}
235-
235+
236+
JsonSchema parsedSchema;
236237
if (latestSchema != null)
237238
{
238-
var latestSchemaJson = await GetParsedSchema(latestSchema).ConfigureAwait(false);
239+
parsedSchema = await GetParsedSchema(latestSchema).ConfigureAwait(false);
239240
FieldTransformer fieldTransformer = async (ctx, transform, message) =>
240241
{
241-
return await JsonUtils.Transform(ctx, latestSchemaJson, "$", message, transform).ConfigureAwait(false);
242+
return await JsonUtils.Transform(ctx, parsedSchema, "$", message, transform).ConfigureAwait(false);
242243
};
243244
value = await ExecuteRules(context.Component == MessageComponentType.Key, subject,
244245
context.Topic, context.Headers, RuleMode.Write, null,
245246
latestSchema, value, fieldTransformer)
246247
.ContinueWith(t => (T)t.Result)
247248
.ConfigureAwait(continueOnCapturedContext: false);
248249
}
250+
else
251+
{
252+
parsedSchema = schema;
253+
}
249254

250255
var serializedString = Newtonsoft.Json.JsonConvert.SerializeObject(value, jsonSchemaGeneratorSettingsSerializerSettings);
251256
if (validate)
252257
{
253-
var validationResult = validator.Validate(serializedString, this.schema);
258+
var validationResult = validator.Validate(serializedString, parsedSchema);
254259
if (validationResult.Count > 0)
255260
{
256261
throw new InvalidDataException("Schema validation failed for properties: [" + string.Join(", ", validationResult.Select(r => r.Path)) + "]");

0 commit comments

Comments
 (0)