From 4d8c79d7f326da46755aef7ea9c1d74295ab7f2f Mon Sep 17 00:00:00 2001 From: Mark Payne Date: Wed, 16 Feb 2022 11:59:56 -0500 Subject: [PATCH] NIFI-9698: When creating an Avro schema, ensure that any default value is converted from what is returned by RecordField.getDefaultValue() to what Avro requires. Signed-off-by: Chris Sampson This closes #5776 --- .../org/apache/nifi/avro/AvroTypeUtil.java | 8 ++++--- .../apache/nifi/avro/TestAvroTypeUtil.java | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/main/java/org/apache/nifi/avro/AvroTypeUtil.java b/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/main/java/org/apache/nifi/avro/AvroTypeUtil.java index 36c62a5c1f..fb29f66222 100644 --- a/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/main/java/org/apache/nifi/avro/AvroTypeUtil.java +++ b/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/main/java/org/apache/nifi/avro/AvroTypeUtil.java @@ -124,16 +124,18 @@ public class AvroTypeUtil { return avroSchema; } - private static Field buildAvroField(final RecordField recordField, String fieldNamePrefix) { + private static Field buildAvroField(final RecordField recordField, final String fieldNamePrefix) { final Schema schema = buildAvroSchema(recordField.getDataType(), recordField.getFieldName(), fieldNamePrefix, recordField.isNullable()); final Field field; final String recordFieldName = recordField.getFieldName(); if (isValidAvroFieldName(recordFieldName)) { - field = new Field(recordField.getFieldName(), schema, null, recordField.getDefaultValue()); + final Object avroDefaultValue = convertToAvroObject(recordField.getDefaultValue(), schema); + field = new Field(recordField.getFieldName(), schema, null, avroDefaultValue); } else { final String validName = createValidAvroFieldName(recordField.getFieldName()); - field = new Field(validName, schema, null, recordField.getDefaultValue()); + final Object avroDefaultValue = convertToAvroObject(recordField.getDefaultValue(), schema); + field = new Field(validName, schema, null, avroDefaultValue); field.addAlias(recordField.getFieldName()); } diff --git a/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/test/java/org/apache/nifi/avro/TestAvroTypeUtil.java b/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/test/java/org/apache/nifi/avro/TestAvroTypeUtil.java index 5f2204bf46..42e914124f 100644 --- a/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/test/java/org/apache/nifi/avro/TestAvroTypeUtil.java +++ b/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/test/java/org/apache/nifi/avro/TestAvroTypeUtil.java @@ -122,6 +122,29 @@ public class TestAvroTypeUtil { assertEquals("blue", avroRecord.get("color")); } + @Test + public void testExtractAvroSchemaWithDefaults() { + final List fields = new ArrayList<>(); + fields.add(new RecordField("string", RecordFieldType.STRING.getDataType(), "hello")); + fields.add(new RecordField("int", RecordFieldType.INT.getDataType(), 17)); + fields.add(new RecordField("long", RecordFieldType.LONG.getDataType(), 42)); + fields.add(new RecordField("float", RecordFieldType.FLOAT.getDataType(), 2.4F)); + fields.add(new RecordField("double", RecordFieldType.DOUBLE.getDataType(), 28.1D)); + fields.add(new RecordField("stringArray", RecordFieldType.ARRAY.getArrayDataType(RecordFieldType.STRING.getDataType()), new String[0])); + fields.add(new RecordField("intArray", RecordFieldType.ARRAY.getArrayDataType(RecordFieldType.INT.getDataType()), new Integer[0])); + + final RecordSchema schema = new SimpleRecordSchema(fields); + final Schema avroSchema = AvroTypeUtil.extractAvroSchema(schema); + + assertEquals("hello", avroSchema.getField("string").defaultVal()); + assertEquals(17, avroSchema.getField("int").defaultVal()); + assertEquals(42L, avroSchema.getField("long").defaultVal()); + assertEquals(2.4D, (double) avroSchema.getField("float").defaultVal(), 0.002D); // Even though we provide a Float, avro converts it into a Double value. + assertEquals(28.1D, (double) avroSchema.getField("double").defaultVal(), 0.002D); + assertEquals(new ArrayList(), avroSchema.getField("stringArray").defaultVal()); + assertEquals(new ArrayList(), avroSchema.getField("intArray").defaultVal()); + } + @Test public void testAvroDefaultValueWithFieldInSchemaButNotRecord() throws IOException { final List fields = new ArrayList<>();