package com.rtbhouse.utils.avro; import org.apache.avro.Schema; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericRecord; import org.apache.avro.generic.GenericRecordBuilder; import org.apache.avro.io.Decoder; import org.apache.avro.util.Utf8; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.io.File; import java.net.URL; import java.net.URLClassLoader; import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.addAliases; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.createArrayFieldSchema; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.createEnumSchema; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.createField; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.createFixedSchema; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.createMapFieldSchema; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.createPrimitiveFieldSchema; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.createPrimitiveUnionFieldSchema; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.createRecord; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.createUnionField; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.createUnionSchema; import static com.rtbhouse.utils.avro.FastSerdeTestsSupport.serializeGeneric; public class FastGenericDeserializerGeneratorTest { private File tempDir; private ClassLoader classLoader; @Before public void prepare() throws Exception { Path tempPath = Files.createTempDirectory("generated"); tempDir = tempPath.toFile(); classLoader = URLClassLoader.newInstance(new URL[]{tempDir.toURI().toURL()}, FastGenericDeserializerGeneratorTest.class.getClassLoader()); } @Test public void shouldReadPrimitives() { // given Schema javaLangStringSchema = Schema.create(Schema.Type.STRING); GenericData.setStringType(javaLangStringSchema, GenericData.StringType.String); Schema recordSchema = createRecord("testRecord", createField("testInt", Schema.create(Schema.Type.INT)), createPrimitiveUnionFieldSchema("testIntUnion", Schema.Type.INT), createField("testString", Schema.create(Schema.Type.STRING)), createPrimitiveUnionFieldSchema("testStringUnion", Schema.Type.STRING), createField("testJavaString", javaLangStringSchema), createUnionField("testJavaStringUnion", javaLangStringSchema), createField("testLong", Schema.create(Schema.Type.LONG)), createPrimitiveUnionFieldSchema("testLongUnion", Schema.Type.LONG), createField("testDouble", Schema.create(Schema.Type.DOUBLE)), createPrimitiveUnionFieldSchema("testDoubleUnion", Schema.Type.DOUBLE), createField("testFloat", Schema.create(Schema.Type.FLOAT)), createPrimitiveUnionFieldSchema("testFloatUnion", Schema.Type.FLOAT), createField("testBoolean", Schema.create(Schema.Type.BOOLEAN)), createPrimitiveUnionFieldSchema("testBooleanUnion", Schema.Type.BOOLEAN), createField("testBytes", Schema.create(Schema.Type.BYTES)), createPrimitiveUnionFieldSchema("testBytesUnion", Schema.Type.BYTES)); GenericRecordBuilder builder = new GenericRecordBuilder(recordSchema); builder.set("testInt", 1); builder.set("testIntUnion", 1); builder.set("testString", "aaa"); builder.set("testStringUnion", "aaa"); builder.set("testJavaString", "aaa"); builder.set("testJavaStringUnion", "aaa"); builder.set("testLong", 1L); builder.set("testLongUnion", 1L); builder.set("testDouble", 1.0); builder.set("testDoubleUnion", 1.0); builder.set("testFloat", 1.0f); builder.set("testFloatUnion", 1.0f); builder.set("testBoolean", true); builder.set("testBooleanUnion", true); builder.set("testBytes", ByteBuffer.wrap(new byte[]{0x01, 0x02})); builder.set("testBytesUnion", ByteBuffer.wrap(new byte[]{0x01, 0x02})); // when GenericRecord record = deserializeGenericFast(recordSchema, recordSchema, serializeGeneric(builder.build())); // then Assert.assertEquals(1, record.get("testInt")); Assert.assertEquals(1, record.get("testIntUnion")); Assert.assertEquals("aaa", record.get("testString").toString()); Assert.assertEquals("aaa", record.get("testStringUnion").toString()); Assert.assertEquals("aaa", record.get("testJavaString")); Assert.assertEquals("aaa", record.get("testJavaStringUnion")); Assert.assertEquals(1L, record.get("testLong")); Assert.assertEquals(1L, record.get("testLongUnion")); Assert.assertEquals(1.0, record.get("testDouble")); Assert.assertEquals(1.0, record.get("testDoubleUnion")); Assert.assertEquals(1.0f, record.get("testFloat")); Assert.assertEquals(1.0f, record.get("testFloatUnion")); Assert.assertEquals(true, record.get("testBoolean")); Assert.assertEquals(true, record.get("testBooleanUnion")); Assert.assertEquals(ByteBuffer.wrap(new byte[]{0x01, 0x02}), record.get("testBytes")); Assert.assertEquals(ByteBuffer.wrap(new byte[]{0x01, 0x02}), record.get("testBytesUnion")); } @Test @SuppressWarnings("unchecked") public void shouldReadFixed() { // given Schema fixedSchema = createFixedSchema("testFixed", 2); Schema recordSchema = createRecord("testRecord", createField("testFixed", fixedSchema), createUnionField("testFixedUnion", fixedSchema), createArrayFieldSchema("testFixedArray", fixedSchema), createArrayFieldSchema("testFixedUnionArray", createUnionSchema(fixedSchema))); GenericRecordBuilder builder = new GenericRecordBuilder(recordSchema); builder.set("testFixed", new GenericData.Fixed(fixedSchema, new byte[]{0x01, 0x02})); builder.set("testFixedUnion", new GenericData.Fixed(fixedSchema, new byte[]{0x03, 0x04})); builder.set("testFixedArray", Arrays.asList(new GenericData.Fixed(fixedSchema, new byte[]{0x05, 0x06}))); builder.set("testFixedUnionArray", Arrays.asList(new GenericData.Fixed(fixedSchema, new byte[]{0x07, 0x08}))); // when GenericRecord record = deserializeGenericFast(recordSchema, recordSchema, serializeGeneric(builder.build())); // then Assert.assertArrayEquals(new byte[]{0x01, 0x02}, ((GenericData.Fixed) record.get("testFixed")).bytes()); Assert.assertArrayEquals(new byte[]{0x03, 0x04}, ((GenericData.Fixed) record.get("testFixedUnion")).bytes()); Assert.assertArrayEquals(new byte[]{0x05, 0x06}, ((List<GenericData.Fixed>) record.get("testFixedArray")).get(0).bytes()); Assert.assertArrayEquals(new byte[]{0x07, 0x08}, ((List<GenericData.Fixed>) record.get("testFixedUnionArray")).get(0).bytes()); } @Test @SuppressWarnings("unchecked") public void shouldReadEnum() { // given Schema enumSchema = createEnumSchema("testEnum", new String[]{"A", "B"}); Schema recordSchema = createRecord("testRecord", createField("testEnum", enumSchema), createUnionField("testEnumUnion", enumSchema), createArrayFieldSchema("testEnumArray", enumSchema), createArrayFieldSchema("testEnumUnionArray", createUnionSchema(enumSchema))); GenericRecordBuilder builder = new GenericRecordBuilder(recordSchema); builder.set("testEnum", new GenericData.EnumSymbol(enumSchema, "A")); builder.set("testEnumUnion", new GenericData.EnumSymbol(enumSchema, "A")); builder.set("testEnumArray", Arrays.asList(new GenericData.EnumSymbol(enumSchema, "A"))); builder.set("testEnumUnionArray", Arrays.asList(new GenericData.EnumSymbol(enumSchema, "A"))); // when GenericRecord record = deserializeGenericFast(recordSchema, recordSchema, serializeGeneric(builder.build())); // then Assert.assertEquals("A", record.get("testEnum").toString()); Assert.assertEquals("A", record.get("testEnumUnion").toString()); Assert.assertEquals("A", ((List<GenericData.EnumSymbol>) record.get("testEnumArray")).get(0).toString()); Assert.assertEquals("A", ((List<GenericData.EnumSymbol>) record.get("testEnumUnionArray")).get(0).toString()); } @Test @SuppressWarnings("unchecked") public void shouldReadPermutatedEnum() { // given Schema enumSchema = createEnumSchema("testEnum", new String[]{"A", "B", "C", "D", "E"}); Schema recordSchema = createRecord("testRecord", createField("testEnum", enumSchema), createUnionField("testEnumUnion", enumSchema), createArrayFieldSchema("testEnumArray", enumSchema), createArrayFieldSchema("testEnumUnionArray", createUnionSchema(enumSchema))); GenericRecordBuilder builder = new GenericRecordBuilder(recordSchema); builder.set("testEnum", new GenericData.EnumSymbol(enumSchema, "A")); builder.set("testEnumUnion", new GenericData.EnumSymbol(enumSchema, "B")); builder.set("testEnumArray", Arrays.asList(new GenericData.EnumSymbol(enumSchema, "C"))); builder.set("testEnumUnionArray", Arrays.asList(new GenericData.EnumSymbol(enumSchema, "D"))); Schema enumSchema1 = createEnumSchema("testEnum", new String[]{"B", "A", "D", "E", "C"}); Schema recordSchema1 = createRecord("testRecord", createField("testEnum", enumSchema1), createUnionField("testEnumUnion", enumSchema1), createArrayFieldSchema("testEnumArray", enumSchema1), createArrayFieldSchema("testEnumUnionArray", createUnionSchema(enumSchema1))); // when GenericRecord record = deserializeGenericFast(recordSchema, recordSchema1, serializeGeneric(builder.build())); // then Assert.assertEquals("A", record.get("testEnum").toString()); Assert.assertEquals("B", record.get("testEnumUnion").toString()); Assert.assertEquals("C", ((List<GenericData.EnumSymbol>) record.get("testEnumArray")).get(0).toString()); Assert.assertEquals("D", ((List<GenericData.EnumSymbol>) record.get("testEnumUnionArray")).get(0).toString()); } @Test(expected = FastDeserializerGeneratorException.class) public void shouldNotReadStrippedEnum() { // given Schema enumSchema = createEnumSchema("testEnum", new String[]{"A", "B", "C"}); Schema recordSchema = createRecord("testRecord", createField("testEnum", enumSchema)); GenericRecordBuilder builder = new GenericRecordBuilder(recordSchema); builder.set("testEnum", new GenericData.EnumSymbol(enumSchema, "C")); Schema enumSchema1 = createEnumSchema("testEnum", new String[]{"A", "B"}); Schema recordSchema1 = createRecord("testRecord", createField("testEnum", enumSchema1)); // when GenericRecord record = deserializeGenericFast(recordSchema, recordSchema1, serializeGeneric(builder.build())); } @Test public void shouldReadSubRecordField() { // given Schema subRecordSchema = createRecord("subRecord", createPrimitiveUnionFieldSchema("subField", Schema.Type.STRING)); Schema recordSchema = createRecord("test", createUnionField("record", subRecordSchema), createField("record1", subRecordSchema), createPrimitiveUnionFieldSchema("field", Schema.Type.STRING)); GenericRecordBuilder subRecordBuilder = new GenericRecordBuilder(subRecordSchema); subRecordBuilder.set("subField", "abc"); GenericRecordBuilder builder = new GenericRecordBuilder(recordSchema); builder.set("record", subRecordBuilder.build()); builder.set("record1", subRecordBuilder.build()); builder.set("field", "abc"); // when GenericRecord record = deserializeGenericFast(recordSchema, recordSchema, serializeGeneric(builder.build())); // then Assert.assertEquals("abc", ((GenericRecord) record.get("record")).get("subField").toString()); Assert.assertEquals(subRecordSchema.hashCode(), ((GenericRecord) record.get("record")).getSchema().hashCode()); Assert.assertEquals("abc", ((GenericRecord) record.get("record1")).get("subField").toString()); Assert.assertEquals(subRecordSchema.hashCode(), ((GenericRecord) record.get("record1")).getSchema().hashCode()); Assert.assertEquals("abc", record.get("field").toString()); } @Test @SuppressWarnings("unchecked") public void shouldReadSubRecordCollectionsField() { // given Schema subRecordSchema = createRecord("subRecord", createPrimitiveUnionFieldSchema("subField", Schema.Type.STRING)); Schema recordSchema = createRecord("test", createArrayFieldSchema("recordsArray", subRecordSchema), createMapFieldSchema("recordsMap", subRecordSchema), createUnionField("recordsArrayUnion", Schema.createArray(createUnionSchema(subRecordSchema))), createUnionField("recordsMapUnion", Schema.createMap(createUnionSchema(subRecordSchema)))); GenericRecordBuilder subRecordBuilder = new GenericRecordBuilder(subRecordSchema); subRecordBuilder.set("subField", "abc"); GenericRecordBuilder builder = new GenericRecordBuilder(recordSchema); List<GenericData.Record> recordsArray = new ArrayList<>(); recordsArray.add(subRecordBuilder.build()); builder.set("recordsArray", recordsArray); builder.set("recordsArrayUnion", recordsArray); Map<String, GenericData.Record> recordsMap = new HashMap<>(); recordsMap.put("1", subRecordBuilder.build()); builder.set("recordsMap", recordsMap); builder.set("recordsMapUnion", recordsMap); // when GenericRecord record = deserializeGenericFast(recordSchema, recordSchema, serializeGeneric(builder.build())); // then Assert.assertEquals("abc", ((List<GenericData.Record>) record.get("recordsArray")).get(0).get("subField").toString()); Assert.assertEquals("abc", ((List<GenericData.Record>) record.get("recordsArrayUnion")).get(0).get("subField").toString()); Assert.assertEquals("abc", ((Map<Utf8, GenericData.Record>) record.get("recordsMap")).get(new Utf8("1")).get("subField").toString()); Assert.assertEquals("abc", ((Map<Utf8, GenericData.Record>) record.get("recordsMapUnion")).get(new Utf8("1")).get("subField").toString()); } @Test @SuppressWarnings("unchecked") public void shouldReadSubRecordComplexCollectionsField() { // given Schema subRecordSchema = createRecord("subRecord", createPrimitiveUnionFieldSchema("subField", Schema.Type.STRING)); Schema recordSchema = createRecord( "test", createArrayFieldSchema("recordsArrayMap", Schema.createMap(createUnionSchema(subRecordSchema))), createMapFieldSchema("recordsMapArray", Schema.createArray(createUnionSchema(subRecordSchema))), createUnionField("recordsArrayMapUnion", Schema.createArray(Schema.createMap(createUnionSchema(subRecordSchema)))), createUnionField("recordsMapArrayUnion", Schema.createMap(Schema.createArray(createUnionSchema(subRecordSchema))))); GenericRecordBuilder subRecordBuilder = new GenericRecordBuilder(subRecordSchema); subRecordBuilder.set("subField", "abc"); GenericRecordBuilder builder = new GenericRecordBuilder(recordSchema); List<Map<String, GenericRecord>> recordsArrayMap = new ArrayList<>(); Map<String, GenericRecord> recordMap = new HashMap<>(); recordMap.put("1", subRecordBuilder.build()); recordsArrayMap.add(recordMap); builder.set("recordsArrayMap", recordsArrayMap); builder.set("recordsArrayMapUnion", recordsArrayMap); Map<String, List<GenericRecord>> recordsMapArray = new HashMap<>(); List<GenericRecord> recordList = new ArrayList<>(); recordList.add(subRecordBuilder.build()); recordsMapArray.put("1", recordList); builder.set("recordsMapArray", recordsMapArray); builder.set("recordsMapArrayUnion", recordsMapArray); // when GenericRecord record = deserializeGenericFast(recordSchema, recordSchema, serializeGeneric(builder.build())); // then Assert.assertEquals("abc", ((List<Map<Utf8, GenericRecord>>) record.get("recordsArrayMap")).get(0).get(new Utf8("1")).get("subField").toString()); Assert.assertEquals("abc", ((Map<Utf8, List<GenericRecord>>) record.get("recordsMapArray")).get(new Utf8("1")).get(0).get("subField").toString()); Assert.assertEquals("abc", ((List<Map<Utf8, GenericRecord>>) record.get("recordsArrayMapUnion")).get(0).get(new Utf8("1")) .get("subField").toString()); Assert.assertEquals("abc", ((Map<Utf8, List<GenericRecord>>) record.get("recordsMapArrayUnion")).get(new Utf8("1")).get(0) .get("subField").toString()); } @Test public void shouldReadAliasedField() { // given Schema record1Schema = createRecord("test", createPrimitiveUnionFieldSchema("testString", Schema.Type.STRING), createPrimitiveUnionFieldSchema("testStringUnion", Schema.Type.STRING)); Schema record2Schema = createRecord( "test", createPrimitiveUnionFieldSchema("testString", Schema.Type.STRING), addAliases(createPrimitiveUnionFieldSchema("testStringUnionAlias", Schema.Type.STRING), "testStringUnion")); GenericRecordBuilder builder = new GenericRecordBuilder(record1Schema); builder.set("testString", "abc"); builder.set("testStringUnion", "def"); // when GenericRecord record = deserializeGenericFast(record1Schema, record2Schema, serializeGeneric(builder.build())); // then Assert.assertEquals("abc", record.get("testString").toString()); Assert.assertEquals("def", record.get("testStringUnionAlias").toString()); } @Test @SuppressWarnings("unchecked") public void shouldSkipRemovedField() { // given Schema subRecord1Schema = createRecord("subRecord", createPrimitiveUnionFieldSchema("testNotRemoved", Schema.Type.STRING), createPrimitiveUnionFieldSchema("testRemoved", Schema.Type.STRING), createPrimitiveUnionFieldSchema("testNotRemoved2", Schema.Type.STRING)); Schema record1Schema = createRecord("test", createPrimitiveUnionFieldSchema("testNotRemoved", Schema.Type.STRING), createPrimitiveUnionFieldSchema("testRemoved", Schema.Type.STRING), createPrimitiveUnionFieldSchema("testNotRemoved2", Schema.Type.STRING), createUnionField("subRecord", subRecord1Schema), createMapFieldSchema("subRecordMap", subRecord1Schema), createArrayFieldSchema("subRecordArray", subRecord1Schema)); Schema subRecord2Schema = createRecord("subRecord", createPrimitiveUnionFieldSchema("testNotRemoved", Schema.Type.STRING), createPrimitiveUnionFieldSchema("testNotRemoved2", Schema.Type.STRING)); Schema record2Schema = createRecord("test", createPrimitiveUnionFieldSchema("testNotRemoved", Schema.Type.STRING), createPrimitiveUnionFieldSchema("testNotRemoved2", Schema.Type.STRING), createUnionField("subRecord", subRecord2Schema), createMapFieldSchema("subRecordMap", subRecord2Schema), createArrayFieldSchema("subRecordArray", subRecord2Schema)); GenericRecordBuilder subRecordBuilder = new GenericRecordBuilder(subRecord1Schema); subRecordBuilder.set("testNotRemoved", "abc"); subRecordBuilder.set("testRemoved", "def"); subRecordBuilder.set("testNotRemoved2", "ghi"); GenericRecordBuilder builder = new GenericRecordBuilder(record1Schema); builder.set("testNotRemoved", "abc"); builder.set("testRemoved", "def"); builder.set("testNotRemoved2", "ghi"); builder.set("subRecord", subRecordBuilder.build()); builder.set("subRecordArray", Arrays.asList(subRecordBuilder.build())); Map<String, GenericRecord> recordsMap = new HashMap<>(); recordsMap.put("1", subRecordBuilder.build()); builder.set("subRecordMap", recordsMap); // when GenericRecord record = deserializeGenericFast(record1Schema, record2Schema, serializeGeneric(builder.build())); // then Assert.assertEquals("abc", record.get("testNotRemoved").toString()); Assert.assertNull(record.get("testRemoved")); Assert.assertEquals("ghi", record.get("testNotRemoved2").toString()); Assert.assertEquals("ghi", ((GenericRecord) record.get("subRecord")).get("testNotRemoved2").toString()); Assert.assertEquals("ghi", ((List<GenericRecord>) record.get("subRecordArray")).get(0).get("testNotRemoved2").toString()); Assert.assertEquals("ghi", ((Map<Utf8, GenericRecord>) record.get("subRecordMap")).get(new Utf8("1")).get("testNotRemoved2").toString()); } @Test public void shouldSkipRemovedRecord() { // given Schema subRecord1Schema = createRecord("subRecord", createPrimitiveFieldSchema("test1", Schema.Type.STRING), createPrimitiveFieldSchema("test2", Schema.Type.STRING)); Schema subRecord2Schema = createRecord("subRecord2", createPrimitiveFieldSchema("test1", Schema.Type.STRING), createPrimitiveFieldSchema("test2", Schema.Type.STRING)); Schema record1Schema = createRecord("test", createField("subRecord1", subRecord1Schema), createField("subRecord2", subRecord2Schema), createUnionField("subRecord3", subRecord2Schema), createField("subRecord4", subRecord1Schema)); Schema record2Schema = createRecord("test", createField("subRecord1", subRecord1Schema), createField("subRecord4", subRecord1Schema)); GenericRecordBuilder subRecordBuilder = new GenericRecordBuilder(subRecord1Schema); subRecordBuilder.set("test1", "abc"); subRecordBuilder.set("test2", "def"); GenericRecordBuilder subRecordBuilder2 = new GenericRecordBuilder(subRecord2Schema); subRecordBuilder2.set("test1", "ghi"); subRecordBuilder2.set("test2", "jkl"); GenericRecordBuilder builder = new GenericRecordBuilder(record1Schema); builder.set("subRecord1", subRecordBuilder.build()); builder.set("subRecord2", subRecordBuilder2.build()); builder.set("subRecord3", subRecordBuilder2.build()); builder.set("subRecord4", subRecordBuilder.build()); // when GenericRecord record = deserializeGenericFast(record1Schema, record2Schema, serializeGeneric(builder.build())); // then Assert.assertEquals("abc", ((GenericRecord) record.get("subRecord1")).get("test1").toString()); Assert.assertEquals("def", ((GenericRecord) record.get("subRecord1")).get("test2").toString()); Assert.assertEquals("abc", ((GenericRecord) record.get("subRecord4")).get("test1").toString()); Assert.assertEquals("def", ((GenericRecord) record.get("subRecord4")).get("test2").toString()); } @Test public void shouldSkipRemovedNestedRecord() { // given Schema subSubRecordSchema = createRecord("subSubRecord", createPrimitiveFieldSchema("test1", Schema.Type.STRING), createPrimitiveFieldSchema("test2", Schema.Type.STRING)); Schema subRecord1Schema = createRecord("subRecord", createPrimitiveFieldSchema("test1", Schema.Type.STRING), createField("test2", subSubRecordSchema), createUnionField("test3", subSubRecordSchema), createPrimitiveFieldSchema("test4", Schema.Type.STRING)); Schema subRecord2Schema = createRecord("subRecord", createPrimitiveFieldSchema("test1", Schema.Type.STRING), createPrimitiveFieldSchema("test4", Schema.Type.STRING)); Schema record1Schema = createRecord("test", createField("subRecord", subRecord1Schema)); Schema record2Schema = createRecord("test", createField("subRecord", subRecord2Schema)); GenericRecordBuilder subSubRecordBuilder = new GenericRecordBuilder(subSubRecordSchema); subSubRecordBuilder.set("test1", "abc"); subSubRecordBuilder.set("test2", "def"); GenericRecordBuilder subRecordBuilder = new GenericRecordBuilder(subRecord1Schema); subRecordBuilder.set("test1", "abc"); subRecordBuilder.set("test2", subSubRecordBuilder.build()); subRecordBuilder.set("test3", subSubRecordBuilder.build()); subRecordBuilder.set("test4", "def"); GenericRecordBuilder builder = new GenericRecordBuilder(record1Schema); builder.set("subRecord", subRecordBuilder.build()); // when GenericRecord record = deserializeGenericFast(record1Schema, record2Schema, serializeGeneric(builder.build())); // then Assert.assertEquals("abc", ((GenericRecord) record.get("subRecord")).get("test1").toString()); Assert.assertEquals("def", ((GenericRecord) record.get("subRecord")).get("test4").toString()); } @Test public void shouldReadMultipleChoiceUnion() { // given Schema subRecordSchema = createRecord("subRecord", createPrimitiveUnionFieldSchema("subField", Schema.Type.STRING)); Schema recordSchema = createRecord( "test", createUnionField("union", subRecordSchema, Schema.create(Schema.Type.STRING), Schema.create(Schema.Type.INT))); GenericRecordBuilder subRecordBuilder = new GenericRecordBuilder(subRecordSchema); subRecordBuilder.set("subField", "abc"); GenericRecordBuilder builder = new GenericRecordBuilder(recordSchema); builder.set("union", subRecordBuilder.build()); // when GenericRecord record = deserializeGenericFast(recordSchema, recordSchema, serializeGeneric(builder.build())); // then Assert.assertEquals("abc", ((GenericData.Record) record.get("union")).get("subField").toString()); // given builder = new GenericRecordBuilder(recordSchema); builder.set("union", "abc"); // when record = deserializeGenericFast(recordSchema, recordSchema, serializeGeneric(builder.build())); // then Assert.assertEquals("abc", record.get("union").toString()); // given builder = new GenericRecordBuilder(recordSchema); builder.set("union", 1); // when record = deserializeGenericFast(recordSchema, recordSchema, serializeGeneric(builder.build())); // then Assert.assertEquals(1, record.get("union")); } @Test public void shouldReadArrayOfRecords() { // given Schema recordSchema = createRecord("record", createPrimitiveUnionFieldSchema("field", Schema.Type.STRING)); Schema arrayRecordSchema = Schema.createArray(recordSchema); GenericRecordBuilder subRecordBuilder = new GenericRecordBuilder(recordSchema); subRecordBuilder.set("field", "abc"); GenericData.Array<GenericData.Record> recordsArray = new GenericData.Array<>(0, arrayRecordSchema); recordsArray.add(subRecordBuilder.build()); recordsArray.add(subRecordBuilder.build()); // when GenericData.Array<GenericRecord> array = deserializeGenericFast(arrayRecordSchema, arrayRecordSchema, serializeGeneric(recordsArray)); // then Assert.assertEquals(2, array.size()); Assert.assertEquals("abc", array.get(0).get("field").toString()); Assert.assertEquals("abc", array.get(1).get("field").toString()); // given arrayRecordSchema = Schema.createArray(createUnionSchema(recordSchema)); subRecordBuilder = new GenericRecordBuilder(recordSchema); subRecordBuilder.set("field", "abc"); recordsArray = new GenericData.Array<>(0, arrayRecordSchema); recordsArray.add(subRecordBuilder.build()); recordsArray.add(subRecordBuilder.build()); // when array = deserializeGenericFast(arrayRecordSchema, arrayRecordSchema, serializeGeneric(recordsArray)); // then Assert.assertEquals(2, array.size()); Assert.assertEquals("abc", array.get(0).get("field").toString()); Assert.assertEquals("abc", array.get(1).get("field").toString()); } @Test public void shouldReadArrayOfPrimitives() { // given Schema stringArraySchema = Schema.createArray(Schema.create(Schema.Type.STRING)); GenericData.Array<String> stringArray = new GenericData.Array<>(0, stringArraySchema); stringArray.add("aaa"); stringArray.add("abc"); Schema intArraySchema = Schema.createArray(Schema.create(Schema.Type.INT)); GenericData.Array<Integer> intArray = new GenericData.Array<>(0, intArraySchema); intArray.add(1); intArray.add(2); Schema longArraySchema = Schema.createArray(Schema.create(Schema.Type.LONG)); GenericData.Array<Long> longArray = new GenericData.Array<>(0, longArraySchema); longArray.add(1L); longArray.add(2L); Schema doubleArraySchema = Schema.createArray(Schema.create(Schema.Type.DOUBLE)); GenericData.Array<Double> doubleArray = new GenericData.Array<>(0, doubleArraySchema); doubleArray.add(1.0); doubleArray.add(2.0); Schema floatArraySchema = Schema.createArray(Schema.create(Schema.Type.FLOAT)); GenericData.Array<Float> floatArray = new GenericData.Array<>(0, floatArraySchema); floatArray.add(1.0f); floatArray.add(2.0f); Schema bytesArraySchema = Schema.createArray(Schema.create(Schema.Type.BYTES)); GenericData.Array<ByteBuffer> bytesArray = new GenericData.Array<>(0, bytesArraySchema); bytesArray.add(ByteBuffer.wrap(new byte[]{0x01})); bytesArray.add(ByteBuffer.wrap(new byte[]{0x02})); // when GenericData.Array<Utf8> resultStringArray = deserializeGenericFast(stringArraySchema, stringArraySchema, serializeGeneric(stringArray)); GenericData.Array<Integer> resultIntegerArray = deserializeGenericFast(intArraySchema, intArraySchema, serializeGeneric(intArray)); GenericData.Array<Long> resultLongArray = deserializeGenericFast(longArraySchema, longArraySchema, serializeGeneric(longArray)); GenericData.Array<Double> resultDoubleArray = deserializeGenericFast(doubleArraySchema, doubleArraySchema, serializeGeneric(doubleArray)); GenericData.Array<Float> resultFloatArray = deserializeGenericFast(floatArraySchema, floatArraySchema, serializeGeneric(floatArray)); GenericData.Array<ByteBuffer> resultBytesArray = deserializeGenericFast(bytesArraySchema, bytesArraySchema, serializeGeneric(bytesArray)); // then Assert.assertEquals(2, resultStringArray.size()); Assert.assertEquals("aaa", resultStringArray.get(0).toString()); Assert.assertEquals("abc", resultStringArray.get(1).toString()); Assert.assertEquals(2, resultIntegerArray.size()); Assert.assertEquals(Integer.valueOf(1), resultIntegerArray.get(0)); Assert.assertEquals(Integer.valueOf(2), resultIntegerArray.get(1)); Assert.assertEquals(2, resultLongArray.size()); Assert.assertEquals(Long.valueOf(1L), resultLongArray.get(0)); Assert.assertEquals(Long.valueOf(2L), resultLongArray.get(1)); Assert.assertEquals(2, resultDoubleArray.size()); Assert.assertEquals(Double.valueOf(1.0), resultDoubleArray.get(0)); Assert.assertEquals(Double.valueOf(2.0), resultDoubleArray.get(1)); Assert.assertEquals(2, resultFloatArray.size()); Assert.assertEquals(Float.valueOf(1f), resultFloatArray.get(0)); Assert.assertEquals(Float.valueOf(2f), resultFloatArray.get(1)); Assert.assertEquals(2, resultBytesArray.size()); Assert.assertEquals(0x01, resultBytesArray.get(0).get()); Assert.assertEquals(0x02, resultBytesArray.get(1).get()); } @Test public void shouldReadArrayOfJavaStrings() { // given Schema javaStringSchema = Schema.create(Schema.Type.STRING); GenericData.setStringType(javaStringSchema, GenericData.StringType.String); Schema javaStringArraySchema = Schema.createArray(javaStringSchema); GenericData.Array<String> javaStringArray = new GenericData.Array<>(0, javaStringArraySchema); javaStringArray.add("aaa"); javaStringArray.add("abc"); GenericData.Array<String> resultJavaStringArray = deserializeGenericFast(javaStringArraySchema, javaStringArraySchema, serializeGeneric(javaStringArray)); // then Assert.assertEquals(2, resultJavaStringArray.size()); Assert.assertEquals("aaa", resultJavaStringArray.get(0)); Assert.assertEquals("abc", resultJavaStringArray.get(1)); } @Test public void shouldReadMapOfRecords() { // given Schema recordSchema = createRecord("record", createPrimitiveUnionFieldSchema("field", Schema.Type.STRING)); Schema mapRecordSchema = Schema.createMap(recordSchema); GenericRecordBuilder subRecordBuilder = new GenericRecordBuilder(recordSchema); subRecordBuilder.set("field", "abc"); Map<String, GenericData.Record> recordsMap = new HashMap<>(); recordsMap.put("1", subRecordBuilder.build()); recordsMap.put("2", subRecordBuilder.build()); // when Map<Utf8, GenericRecord> map = deserializeGenericFast(mapRecordSchema, mapRecordSchema, serializeGeneric(recordsMap, mapRecordSchema)); // then Assert.assertEquals(2, map.size()); Assert.assertEquals("abc", map.get(new Utf8("1")).get("field").toString()); Assert.assertEquals("abc", map.get(new Utf8("2")).get("field").toString()); // given mapRecordSchema = Schema.createMap(createUnionSchema(recordSchema)); // when map = deserializeGenericFast(mapRecordSchema, mapRecordSchema, serializeGeneric(recordsMap, mapRecordSchema)); // then Assert.assertEquals(2, map.size()); Assert.assertEquals("abc", map.get(new Utf8("1")).get("field").toString()); Assert.assertEquals("abc", map.get(new Utf8("2")).get("field").toString()); } @Test public void shouldReadMapOfPrimitives() { // given Schema stringMapSchema = Schema.createMap(Schema.create(Schema.Type.STRING)); Map<String, String> stringMap = new HashMap<>(0); stringMap.put("1", "abc"); stringMap.put("2", "aaa"); Schema intMapSchema = Schema.createMap(Schema.create(Schema.Type.INT)); Map<String, Integer> intMap = new HashMap<>(0); intMap.put("1", 1); intMap.put("2", 2); Schema longMapSchema = Schema.createMap(Schema.create(Schema.Type.LONG)); Map<String, Long> longMap = new HashMap<>(0); longMap.put("1", 1L); longMap.put("2", 2L); Schema doubleMapSchema = Schema.createMap(Schema.create(Schema.Type.DOUBLE)); Map<String, Double> doubleMap = new HashMap<>(0); doubleMap.put("1", 1.0); doubleMap.put("2", 2.0); Schema floatMapSchema = Schema.createMap(Schema.create(Schema.Type.FLOAT)); Map<String, Float> floatMap = new HashMap<>(0); floatMap.put("1", 1.0f); floatMap.put("2", 2.0f); Schema bytesMapSchema = Schema.createMap(Schema.create(Schema.Type.BYTES)); Map<String, ByteBuffer> bytesMap = new HashMap<>(0); bytesMap.put("1", ByteBuffer.wrap(new byte[]{0x01})); bytesMap.put("2", ByteBuffer.wrap(new byte[]{0x02})); // when Map<Utf8, Utf8> resultStringMap = deserializeGenericFast(stringMapSchema, stringMapSchema, serializeGeneric(stringMap, stringMapSchema)); Map<Utf8, Integer> resultIntegerMap = deserializeGenericFast(intMapSchema, intMapSchema, serializeGeneric(intMap, intMapSchema)); Map<Utf8, Long> resultLongMap = deserializeGenericFast(longMapSchema, longMapSchema, serializeGeneric(longMap, longMapSchema)); Map<Utf8, Double> resultDoubleMap = deserializeGenericFast(doubleMapSchema, doubleMapSchema, serializeGeneric(doubleMap, doubleMapSchema)); Map<Utf8, Float> resultFloatMap = deserializeGenericFast(floatMapSchema, floatMapSchema, serializeGeneric(floatMap, floatMapSchema)); Map<Utf8, ByteBuffer> resultBytesMap = deserializeGenericFast(bytesMapSchema, bytesMapSchema, serializeGeneric(bytesMap, bytesMapSchema)); // then Assert.assertEquals(2, resultStringMap.size()); Assert.assertEquals("abc", resultStringMap.get(new Utf8("1")).toString()); Assert.assertEquals("aaa", resultStringMap.get(new Utf8("2")).toString()); Assert.assertEquals(2, resultIntegerMap.size()); Assert.assertEquals(Integer.valueOf(1), resultIntegerMap.get(new Utf8("1"))); Assert.assertEquals(Integer.valueOf(2), resultIntegerMap.get(new Utf8("2"))); Assert.assertEquals(2, resultLongMap.size()); Assert.assertEquals(Long.valueOf(1L), resultLongMap.get(new Utf8("1"))); Assert.assertEquals(Long.valueOf(2L), resultLongMap.get(new Utf8("2"))); Assert.assertEquals(2, resultDoubleMap.size()); Assert.assertEquals(Double.valueOf(1.0), resultDoubleMap.get(new Utf8("1"))); Assert.assertEquals(Double.valueOf(2.0), resultDoubleMap.get(new Utf8("2"))); Assert.assertEquals(2, resultFloatMap.size()); Assert.assertEquals(Float.valueOf(1f), resultFloatMap.get(new Utf8("1"))); Assert.assertEquals(Float.valueOf(2f), resultFloatMap.get(new Utf8("2"))); Assert.assertEquals(2, resultBytesMap.size()); Assert.assertEquals(0x01, resultBytesMap.get(new Utf8("1")).get()); Assert.assertEquals(0x02, resultBytesMap.get(new Utf8("2")).get()); } @Test public void shouldReadMapOfJavaStrings() { // given Schema stringMapSchema = Schema.createMap(Schema.create(Schema.Type.STRING)); Schema javaStringSchema = Schema.create(Schema.Type.STRING); GenericData.setStringType(javaStringSchema, GenericData.StringType.String); Schema javaStringMapSchema = Schema.createMap(javaStringSchema); Map<String, String> stringMap = new HashMap<>(0); stringMap.put("1", "abc"); stringMap.put("2", "aaa"); // when Map<Utf8, String> resultJavaStringMap = deserializeGenericFast(stringMapSchema, javaStringMapSchema, serializeGeneric(stringMap, javaStringMapSchema)); // then Assert.assertEquals(2, resultJavaStringMap.size()); Assert.assertEquals("abc", resultJavaStringMap.get(new Utf8("1"))); Assert.assertEquals("aaa", resultJavaStringMap.get(new Utf8("2"))); } @Test public void shouldReadJavaStringKeyedMapOfRecords() { // given Schema recordSchema = createRecord("record", createPrimitiveUnionFieldSchema("field", Schema.Type.STRING)); Schema mapRecordSchema = Schema.createMap(recordSchema); GenericData.setStringType(mapRecordSchema, GenericData.StringType.String); GenericRecordBuilder subRecordBuilder = new GenericRecordBuilder(recordSchema); subRecordBuilder.set("field", "abc"); Map<String, GenericData.Record> recordsMap = new HashMap<>(); recordsMap.put("1", subRecordBuilder.build()); recordsMap.put("2", subRecordBuilder.build()); // when Map<String, GenericRecord> mapWithStringKeys = deserializeGenericFast(mapRecordSchema, mapRecordSchema, serializeGeneric(recordsMap, mapRecordSchema)); // then Assert.assertEquals(2, mapWithStringKeys.size()); Assert.assertEquals("abc", mapWithStringKeys.get("1").get("field").toString()); Assert.assertEquals("abc", mapWithStringKeys.get("2").get("field").toString()); } @Test public void shouldDeserializeNullElementInMap() { // given Schema mapRecordSchema = Schema.createMap(Schema.createUnion( Schema.create(Schema.Type.STRING), Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.INT))); Map<String, Object> records = new HashMap<>(); records.put("0", "0"); records.put("1", null); records.put("2", 2); // when Map<Utf8, Object> map = deserializeGenericFast(mapRecordSchema, mapRecordSchema, serializeGeneric(records, mapRecordSchema)); // then Assert.assertEquals(3, map.size()); Assert.assertEquals("0", map.get(new Utf8("0")).toString()); Assert.assertNull(map.get(new Utf8("1"))); Assert.assertEquals(2, map.get(new Utf8("2"))); } @Test public void shouldDeserializeNullElementInArray() { // given Schema arrayRecordSchema = Schema.createArray(Schema.createUnion( Schema.create(Schema.Type.STRING), Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.INT))); List<Object> records = new ArrayList<>(); records.add("0"); records.add(null); records.add(2); // when List<Object> array = deserializeGenericFast(arrayRecordSchema, arrayRecordSchema, serializeGeneric(records, arrayRecordSchema)); // then Assert.assertEquals(3, array.size()); Assert.assertEquals("0", array.get(0).toString()); Assert.assertNull(array.get(1)); Assert.assertEquals(2, array.get(2)); } private <T> T deserializeGenericFast(Schema writerSchema, Schema readerSchema, Decoder decoder) { FastDeserializer<T> deserializer = new FastGenericDeserializerGenerator<T>(writerSchema, readerSchema, tempDir, classLoader, null).generateDeserializer(); try { return deserializer.deserialize(decoder); } catch (Exception e) { throw new RuntimeException(e); } } }