This is an automated email from the ASF dual-hosted git repository.

mattyb149 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 2126dbbe29 NIFI-10660: When converting Avro GenericRecord to a java 
Map, check GenericRecord's schema to see if field exists before calling 
Record.get().
2126dbbe29 is described below

commit 2126dbbe29858eb00e88d27efcd668431ff185c9
Author: Mark Payne <[email protected]>
AuthorDate: Sun Nov 20 18:26:16 2022 -0500

    NIFI-10660: When converting Avro GenericRecord to a java Map, check 
GenericRecord's schema to see if field exists before calling Record.get().
    
    NIFI-10660: Added unit tests; fixed bug to ensure that we use the desired 
field name when checking if it exists in schema
    
    Signed-off-by: Matthew Burgess <[email protected]>
    
    This closes #6688
---
 .../nifi-avro-record-utils/pom.xml                 |  6 ++-
 .../java/org/apache/nifi/avro/AvroTypeUtil.java    | 49 +++++++++++++---------
 .../org/apache/nifi/avro/TestAvroTypeUtil.java     | 42 +++++++++++++++++--
 .../src/test/resources/person-old-schema.avsc      | 10 +++++
 .../src/test/resources/person.avsc                 | 10 +++++
 5 files changed, 91 insertions(+), 26 deletions(-)

diff --git 
a/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/pom.xml
 
b/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/pom.xml
index 10210a7653..48d60eea5d 100755
--- 
a/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/pom.xml
+++ 
b/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/pom.xml
@@ -20,7 +20,7 @@
         <artifactId>nifi-record-utils</artifactId>
         <version>1.19.0-SNAPSHOT</version>
     </parent>
-    
+
     <artifactId>nifi-avro-record-utils</artifactId>
 
     <dependencies>
@@ -75,7 +75,9 @@
                         
<exclude>src/test/resources/org/apache/nifi/avro/defaultArrayValue1.json</exclude>
                         
<exclude>src/test/resources/org/apache/nifi/avro/defaultArrayValue2.json</exclude>
                         
<exclude>src/test/resources/org/apache/nifi/avro/defaultArrayInRecords1.json</exclude>
-                        
<exclude>src/test/resources/org/apache/nifi/avro/defaultArrayInRecords2.json</exclude>
                       
+                        
<exclude>src/test/resources/org/apache/nifi/avro/defaultArrayInRecords2.json</exclude>
+                        <exclude>src/test/resources/person.avsc</exclude>
+                        
<exclude>src/test/resources/person-old-schema.avsc</exclude>
                     </excludes>
                 </configuration>
             </plugin>
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 ac82e812ea..f9b8b6f115 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
@@ -905,36 +905,45 @@ public class AvroTypeUtil {
         return convertAvroRecordToMap(avroRecord, recordSchema, 
StandardCharsets.UTF_8);
     }
 
+    private static String getMatchingFieldName(final GenericRecord record, 
final RecordField field) {
+        final Schema schema = record.getSchema();
+        Field avroField = schema.getField(field.getFieldName());
+        if (avroField != null) {
+            return field.getFieldName();
+        }
+
+        for (final String alias : field.getAliases()) {
+            avroField = schema.getField(alias);
+            if (avroField != null) {
+                return alias;
+            }
+        }
+
+        return null;
+    }
+
     public static Map<String, Object> convertAvroRecordToMap(final 
GenericRecord avroRecord, final RecordSchema recordSchema, final Charset 
charset) {
         final Map<String, Object> values = new 
HashMap<>(recordSchema.getFieldCount());
 
         for (final RecordField recordField : recordSchema.getFields()) {
-
-            Object value = avroRecord.get(recordField.getFieldName());
-            if (value == null) {
-                for (final String alias : recordField.getAliases()) {
-                    value = avroRecord.get(alias);
-                    if (value != null) {
-                        break;
-                    }
-                }
-            }
+            final String relevantFieldName = getMatchingFieldName(avroRecord, 
recordField);
+            final Object value = (relevantFieldName == null) ? null : 
avroRecord.get(relevantFieldName);
 
             final String fieldName = recordField.getFieldName();
             try {
-            final Field avroField = avroRecord.getSchema().getField(fieldName);
-            if (avroField == null) {
-                values.put(fieldName, null);
-                continue;
-            }
+                final Field avroField = 
avroRecord.getSchema().getField(relevantFieldName);
+                if (avroField == null) {
+                    values.put(fieldName, null);
+                    continue;
+                }
 
-            final Schema fieldSchema = avroField.schema();
-            final Object rawValue = normalizeValue(value, fieldSchema, 
fieldName);
+                final Schema fieldSchema = avroField.schema();
+                final Object rawValue = normalizeValue(value, fieldSchema, 
fieldName);
 
-            final DataType desiredType = recordField.getDataType();
-            final Object coercedValue = DataTypeUtils.convertType(rawValue, 
desiredType, fieldName, charset);
+                final DataType desiredType = recordField.getDataType();
+                final Object coercedValue = 
DataTypeUtils.convertType(rawValue, desiredType, fieldName, charset);
 
-            values.put(fieldName, coercedValue);
+                values.put(fieldName, coercedValue);
             } catch (Exception ex) {
                 logger.debug("fail to convert field " + fieldName, ex );
                 throw ex;
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 938f0ebf3a..df3d57f672 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
@@ -42,6 +42,7 @@ import 
org.apache.nifi.serialization.record.type.RecordDataType;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
 
+import java.io.File;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.nio.ByteBuffer;
@@ -483,20 +484,53 @@ public class TestAvroTypeUtil {
 
     @Test
     public void testMapWithNullSchema() throws IOException {
-
         Schema recursiveSchema = new 
Schema.Parser().parse(getClass().getResourceAsStream("schema.json"));
 
         // Make sure the following doesn't throw an exception
         RecordSchema recordASchema = 
AvroTypeUtil.createSchema(recursiveSchema.getTypes().get(0));
 
         // check the fix with the proper file
-        try (DataFileStream<GenericRecord> r = new 
DataFileStream<>(getClass().getResourceAsStream("data.avro"),
+        try (DataFileStream<GenericRecord> dataFileStream = new 
DataFileStream<>(getClass().getResourceAsStream("data.avro"),
                 new GenericDatumReader<>())) {
-            GenericRecord n = r.next();
-            AvroTypeUtil.convertAvroRecordToMap(n, recordASchema, 
StandardCharsets.UTF_8);
+            GenericRecord record = dataFileStream.next();
+            AvroTypeUtil.convertAvroRecordToMap(record, recordASchema, 
StandardCharsets.UTF_8);
         }
     }
 
+    @Test
+    public void testConvertAvroRecordToMapWithAliasInSchema() throws 
IOException {
+        final Schema personSchema = new Schema.Parser().parse(new 
File("src/test/resources/person.avsc"));
+        final GenericRecord record = new GenericData.Record(personSchema);
+        record.put("name", "John Doe");
+        record.put("ssn", "111-11-1111");
+
+        final RecordSchema recordSchema = 
AvroTypeUtil.createSchema(personSchema);
+        final Map<String, Object> map = 
AvroTypeUtil.convertAvroRecordToMap(record, recordSchema);
+        assertEquals("John Doe", map.get("name"));
+        assertEquals("111-11-1111", map.get("ssn"));
+        assertNull(map.get("favoriteNumber"));
+        assertNull(map.get("favNum"));
+        assertNull(map.get("my favorite"));
+    }
+
+    @Test
+    public void testConvertAvroRecordToMapUsingAlias() throws IOException {
+        final Schema personOldSchema = new Schema.Parser().parse(new 
File("src/test/resources/person-old-schema.avsc"));
+        final GenericRecord record = new GenericData.Record(personOldSchema);
+        record.put("name", "John Doe");
+        record.put("id", "111-11-1111");
+        record.put("favNum", 48);
+
+        final Schema personUpdatedSchema = new Schema.Parser().parse(new 
File("src/test/resources/person.avsc"));
+        final RecordSchema recordSchema = 
AvroTypeUtil.createSchema(personUpdatedSchema);
+        final Map<String, Object> map = 
AvroTypeUtil.convertAvroRecordToMap(record, recordSchema);
+        assertEquals("John Doe", map.get("name"));
+        assertEquals("111-11-1111", map.get("ssn"));
+        assertEquals(48, map.get("favoriteNumber"));
+    }
+
+
+
     @Test
     public void testToDecimalConversion() {
         final LogicalTypes.Decimal decimalType = LogicalTypes.decimal(26, 8);
diff --git 
a/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/test/resources/person-old-schema.avsc
 
b/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/test/resources/person-old-schema.avsc
new file mode 100644
index 0000000000..8e16dbd7d8
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/test/resources/person-old-schema.avsc
@@ -0,0 +1,10 @@
+{
+    "name": "person",
+    "namespace": "nifi",
+    "type": "record",
+    "fields": [
+        { "name": "name", "type": "string" },
+        { "name": "favNum", "type": ["null", "int"]},
+        { "name": "id", "type": ["null", "string"]}
+    ]
+}
\ No newline at end of file
diff --git 
a/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/test/resources/person.avsc
 
b/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/test/resources/person.avsc
new file mode 100644
index 0000000000..997b72084a
--- /dev/null
+++ 
b/nifi-nar-bundles/nifi-extension-utils/nifi-record-utils/nifi-avro-record-utils/src/test/resources/person.avsc
@@ -0,0 +1,10 @@
+{
+    "name": "person",
+    "namespace": "nifi",
+    "type": "record",
+    "fields": [
+        { "name": "name", "type": "string" },
+        { "name": "favoriteNumber", "type": ["null", "int"], "aliases": 
["favNum", "my favorite"] },
+        { "name": "ssn", "type": ["null", "string"], "aliases": ["id"] }
+    ]
+}
\ No newline at end of file

Reply via email to