NIFI-3920: Remove unnecessary code from AvroTypeUtil

- Removed remaining duplicate lines of code left by NIFI-3861 refactoring.
- Added test case that writes Avro record having union field.

This closes #1813.
This commit is contained in:
Koji Kawamura 2017-05-17 11:23:54 +09:00 committed by Mark Payne
parent c50d516076
commit 33dc3e36fb
2 changed files with 17 additions and 19 deletions

View File

@ -386,24 +386,6 @@ public class AvroTypeUtil {
}
return avroRecord;
case UNION:
// Ignore null types in union
final List<Schema> nonNullFieldSchemas = getNonNullSubSchemas(fieldSchema);
// If at least one non-null type exists, find the first compatible type
if (nonNullFieldSchemas.size() >= 1) {
for (final Schema nonNullFieldSchema : nonNullFieldSchemas) {
final Object avroObject = convertToAvroObject(rawValue, nonNullFieldSchema, fieldName);
final DataType desiredDataType = AvroTypeUtil.determineDataType(nonNullFieldSchema);
if (DataTypeUtils.isCompatibleDataType(avroObject, desiredDataType)
// For logical types those store with different type (e.g. BigDecimal as ByteBuffer), check compatibility using the original rawValue
|| (nonNullFieldSchema.getLogicalType() != null && DataTypeUtils.isCompatibleDataType(rawValue, desiredDataType))) {
return avroObject;
}
}
throw new IllegalTypeConversionException("Cannot convert value " + rawValue + " of type " + rawValue.getClass()
+ " because no compatible types exist in the UNION");
}
return convertUnionFieldValue(rawValue, fieldSchema, schema -> convertToAvroObject(rawValue, schema, fieldName));
case ARRAY:
final Object[] objectArray = (Object[]) rawValue;

View File

@ -39,9 +39,11 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TimeZone;
import org.apache.avro.Conversions;
import org.apache.avro.LogicalType;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData.Array;
import org.apache.avro.generic.GenericRecord;
@ -68,6 +70,16 @@ public abstract class TestWriteAvroResult {
@Test
public void testLogicalTypes() throws IOException, ParseException {
final Schema schema = new Schema.Parser().parse(new File("src/test/resources/avro/logical-types.avsc"));
testLogicalTypes(schema);
}
@Test
public void testNullableLogicalTypes() throws IOException, ParseException {
final Schema schema = new Schema.Parser().parse(new File("src/test/resources/avro/logical-types-nullable.avsc"));
testLogicalTypes(schema);
}
private void testLogicalTypes(Schema schema) throws ParseException, IOException {
final WriteAvroResult writer = createWriter(schema);
final List<RecordField> fields = new ArrayList<>();
@ -114,7 +126,11 @@ public abstract class TestWriteAvroResult {
assertEquals(17260, avroRecord.get("date"));
// Double value will be converted into logical decimal if Avro schema is defined as logical decimal.
final Schema decimalSchema = schema.getField("decimal").schema();
final BigDecimal decimal = new Conversions.DecimalConversion().fromBytes((ByteBuffer) avroRecord.get("decimal"), decimalSchema, decimalSchema.getLogicalType());
final LogicalType logicalType = decimalSchema.getLogicalType() != null
? decimalSchema.getLogicalType()
// Union type doesn't return logical type. Find the first logical type defined within the union.
: decimalSchema.getTypes().stream().map(s -> s.getLogicalType()).filter(Objects::nonNull).findFirst().get();
final BigDecimal decimal = new Conversions.DecimalConversion().fromBytes((ByteBuffer) avroRecord.get("decimal"), decimalSchema, logicalType);
assertEquals(expectedDecimal, decimal);
}
}