Skip to content

Commit 10c4f7a

Browse files
authored
BE: Serde: Fix avro schema serde for nullable enums (#685)
1 parent 91f95f6 commit 10c4f7a

File tree

3 files changed

+84
-7
lines changed

3 files changed

+84
-7
lines changed

api/src/main/java/io/kafbat/ui/util/jsonschema/AvroJsonSchemaConverter.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,12 @@ private FieldSchema createUnionSchema(Schema schema, Map<String, FieldSchema> de
8080
final Map<String, FieldSchema> fields = schema.getTypes().stream()
8181
.filter(t -> !t.getType().equals(Schema.Type.NULL))
8282
.map(f -> {
83-
String oneOfFieldName;
84-
if (f.getType().equals(Schema.Type.RECORD)) {
85-
// for records using full record name
86-
oneOfFieldName = f.getFullName();
87-
} else {
83+
String oneOfFieldName = switch (f.getType()) {
84+
case RECORD -> f.getFullName();
85+
case ENUM -> f.getName();
8886
// for primitive types - using type name
89-
oneOfFieldName = f.getType().getName().toLowerCase();
90-
}
87+
default -> f.getType().getName().toLowerCase();
88+
};
9189
return Tuples.of(oneOfFieldName, convertSchema(f, definitions, false));
9290
}).collect(Collectors.toMap(
9391
Tuple2::getT1,

api/src/test/java/io/kafbat/ui/util/jsonschema/AvroJsonSchemaConverterTest.java

+42
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,48 @@ void testRecordReferences() {
244244
convertAndCompare(expectedJsonSchema, avroSchema);
245245
}
246246

247+
@Test
248+
void testNullableUnionEnum() {
249+
String avroSchema =
250+
" {"
251+
+ " \"type\": \"record\","
252+
+ " \"name\": \"Message\","
253+
+ " \"namespace\": \"com.provectus.kafka\","
254+
+ " \"fields\": ["
255+
+ " {"
256+
+ " \"name\": \"enum_nullable_union\","
257+
+ " \"type\": [\"null\", {"
258+
+ " \"type\": \"enum\","
259+
+ " \"name\": \"Suit\","
260+
+ " \"symbols\": [\"SPADES\",\"HEARTS\",\"DIAMONDS\",\"CLUBS\"]"
261+
+ " }]"
262+
+ " }"
263+
+ " ]"
264+
+ " }";
265+
266+
String expectedJsonSchema =
267+
"{\"$id\":\"http://example.com/Message\","
268+
+ "\"$schema\":\"https://json-schema.org/draft/2020-12/schema\","
269+
+ "\"type\":\"object\","
270+
+ "\"properties\":{"
271+
+ "\"enum_nullable_union\":{"
272+
+ "\"oneOf\":["
273+
+ "{\"type\":\"null\"},"
274+
+ "{\"type\":\"object\","
275+
+ "\"properties\":{"
276+
+ "\"Suit\":{"
277+
+ "\"type\":\"string\","
278+
+ "\"enum\":[\"SPADES\",\"HEARTS\",\"DIAMONDS\",\"CLUBS\"]"
279+
+ "}}}"
280+
+ "]"
281+
+ "}},"
282+
+ "\"definitions\":{"
283+
+ "\"com.provectus.kafka.Message\":{\"$ref\":\"#\"}"
284+
+ "}}";
285+
286+
convertAndCompare(expectedJsonSchema, avroSchema);
287+
}
288+
247289
@SneakyThrows
248290
private void convertAndCompare(String expectedJsonSchema, String sourceAvroSchema) {
249291
var parseAvroSchema = new Schema.Parser().parse(sourceAvroSchema);

api/src/test/java/io/kafbat/ui/util/jsonschema/JsonAvroConversionTest.java

+37
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,43 @@ void unionFieldWithInnerTypesNamesClash() {
700700

701701
}
702702

703+
@Test
704+
void unionNullableEnumField() {
705+
var schema = createSchema(
706+
"""
707+
{
708+
"type": "record",
709+
"namespace": "com.test",
710+
"name": "TestAvroRecord",
711+
"fields": [
712+
{
713+
"name": "enum_nullable_union",
714+
"type" : [ "null", {
715+
"type" : "enum",
716+
"name" : "Suit",
717+
"symbols" : ["SPADES", "HEARTS", "DIAMONDS", "CLUBS"]
718+
} ]
719+
}
720+
]
721+
}"""
722+
);
723+
724+
GenericData.Record inputRecord = new GenericData.Record(schema);
725+
inputRecord.put("enum_nullable_union",
726+
new GenericData.EnumSymbol(
727+
schema.getField("enum_nullable_union").schema().getTypes().get(1), "SPADES"));
728+
String expectedJsonWithEnum = """
729+
{
730+
"enum_nullable_union": { "Suit": "SPADES"}\s
731+
}
732+
\s""";
733+
assertJsonsEqual(expectedJsonWithEnum, convertAvroToJson(inputRecord, schema));
734+
735+
GenericData.Record inputNullRecord = new GenericData.Record(schema);
736+
inputNullRecord.put("enum_nullable_union", null);
737+
assertJsonsEqual("{}", convertAvroToJson(inputNullRecord, schema));
738+
}
739+
703740
private Schema createSchema(String schema) {
704741
return new AvroSchema(schema).rawSchema();
705742
}

0 commit comments

Comments
 (0)