diff --git a/lib/jsonhelper/src/main/kotlin/insulator/jsonhelper/avrotojson/AvroToJsonConverter.kt b/lib/jsonhelper/src/main/kotlin/insulator/jsonhelper/avrotojson/AvroToJsonConverter.kt index f1d9570c..b38fb7c7 100644 --- a/lib/jsonhelper/src/main/kotlin/insulator/jsonhelper/avrotojson/AvroToJsonConverter.kt +++ b/lib/jsonhelper/src/main/kotlin/insulator/jsonhelper/avrotojson/AvroToJsonConverter.kt @@ -47,7 +47,7 @@ class AvroToJsonConverter(private val objectMapper: ObjectMapper) { } private fun parseRecord(field: Any?, schema: Schema, humanReadableLogicalType: Boolean): Either { - if (field !is GenericRecord) return AvroFieldParsingException(field, "Record").left() + if (field !is GenericRecord || field.schema != schema) return AvroFieldParsingException(field, "Record").left() val keySchema = schema.fields.map { it.name() to it.schema() } return keySchema .map { (name, schema) -> parseField(field[name], schema, humanReadableLogicalType) } diff --git a/lib/jsonhelper/src/test/kotlin/insulator/jsonhelper/avrotojson/AvroToJsonConverterTest.kt b/lib/jsonhelper/src/test/kotlin/insulator/jsonhelper/avrotojson/AvroToJsonConverterTest.kt index 2852e1c1..7bb421fd 100644 --- a/lib/jsonhelper/src/test/kotlin/insulator/jsonhelper/avrotojson/AvroToJsonConverterTest.kt +++ b/lib/jsonhelper/src/test/kotlin/insulator/jsonhelper/avrotojson/AvroToJsonConverterTest.kt @@ -61,7 +61,8 @@ class AvroToJsonConverterTest : StringSpec({ testCases.forAll { testType, _, result -> // arrange val testFieldName = "testField" - val schema = Schema.Parser().parse(schemaTemplate("""{"name":"$testFieldName", "type":$testType, "default": $result }""")) + val schema = Schema.Parser() + .parse(schemaTemplate("""{"name":"$testFieldName", "type":$testType, "default": $result }""")) val testRecord = GenericRecordBuilder(schema).build() // act val res = sut.parse(testRecord) @@ -86,9 +87,11 @@ class AvroToJsonConverterTest : StringSpec({ "byte array type - logical decimal" { // arrange val testFieldName = "testField" - val schema = Schema.Parser().parse(schemaTemplate("""{"name":"$testFieldName", "type": {"type":"bytes", "logicalType":"decimal", "precision":4, "scale":2} }""")) + val schema = Schema.Parser() + .parse(schemaTemplate("""{"name":"$testFieldName", "type": {"type":"bytes", "logicalType":"decimal", "precision":4, "scale":2} }""")) val fieldSchema = schema.fields[0].schema() - val testValue = Conversions.DecimalConversion().toBytes(BigDecimal.valueOf(1.23), fieldSchema, fieldSchema.logicalType) + val testValue = + Conversions.DecimalConversion().toBytes(BigDecimal.valueOf(1.23), fieldSchema, fieldSchema.logicalType) val testRecord = GenericRecordBuilder(schema) .also { it.set(testFieldName, testValue) } .build() @@ -101,7 +104,8 @@ class AvroToJsonConverterTest : StringSpec({ "parse array type" { // arrange val testFieldName = "testField" - val schema = Schema.Parser().parse(schemaTemplate("""{"name":"$testFieldName", "type":{"type":"array", "items":"string"}}""")) + val schema = Schema.Parser() + .parse(schemaTemplate("""{"name":"$testFieldName", "type":{"type":"array", "items":"string"}}""")) val testRecord = GenericRecordBuilder(schema).also { it.set(testFieldName, listOf("1", "2", "3")) }.build() // act val res = sut.parse(testRecord) @@ -112,7 +116,8 @@ class AvroToJsonConverterTest : StringSpec({ "parse nullable array type" { // arrange val testFieldName = "testField" - val schema = Schema.Parser().parse(schemaTemplate("""{"name":"$testFieldName", "type":[{"type":"array", "items":"string"}, "null"]}""")) + val schema = Schema.Parser() + .parse(schemaTemplate("""{"name":"$testFieldName", "type":[{"type":"array", "items":"string"}, "null"]}""")) val testRecord = GenericRecordBuilder(schema).also { it.set(testFieldName, null) }.build() // act val res = sut.parse(testRecord) @@ -245,6 +250,24 @@ class AvroToJsonConverterTest : StringSpec({ it.shouldBeInstanceOf() } } + + "parse union of records" { + // arrange + val schema = Schema.Parser().parse( + schemaTemplate( + """{"name":"union","type":[{"type":"record","name":"record1","fields":[{"name":"field1","type":"string"},{"name":"field2","type":"string"}]},{"type":"record","name":"record2","fields":[{"name":"field3","type":"string"}]}]}""" + ) + ) + val nestedRecord = GenericRecordBuilder(schema.fields[0].schema().types[0]).also { + it.set("field1", "value1") + it.set("field2", "value2") + }.build() + val testRecord = GenericRecordBuilder(schema).also { it.set("union", nestedRecord) }.build() + // act + val res = sut.parse(testRecord) + // assert + res shouldBeRight {} + } }) private fun schemaTemplate(vararg fieldDef: String) =