NIFI-4846: AvroTypeUtil to support more input types for logical decimal conversion

Signed-off-by: Matthew Burgess <mattyb149@apache.org>

This closes #2451
This commit is contained in:
Koji Kawamura 2018-02-06 16:36:15 +09:00 committed by Matthew Burgess
parent f3013d0764
commit 270892f926
2 changed files with 39 additions and 2 deletions

View File

@ -533,8 +533,19 @@ public class AvroTypeUtil {
final BigDecimal rawDecimal; final BigDecimal rawDecimal;
if (rawValue instanceof BigDecimal) { if (rawValue instanceof BigDecimal) {
rawDecimal = (BigDecimal) rawValue; rawDecimal = (BigDecimal) rawValue;
} else if (rawValue instanceof Double) { } else if (rawValue instanceof Double) {
rawDecimal = BigDecimal.valueOf((Double) rawValue); rawDecimal = BigDecimal.valueOf((Double) rawValue);
} else if (rawValue instanceof String) {
rawDecimal = new BigDecimal((String) rawValue);
} else if (rawValue instanceof Integer) {
rawDecimal = new BigDecimal((Integer) rawValue);
} else if (rawValue instanceof Long) {
rawDecimal = new BigDecimal((Long) rawValue);
} else { } else {
throw new IllegalTypeConversionException("Cannot convert value " + rawValue + " of type " + rawValue.getClass() + " to a logical decimal"); throw new IllegalTypeConversionException("Cannot convert value " + rawValue + " of type " + rawValue.getClass() + " to a logical decimal");
} }

View File

@ -19,6 +19,7 @@ package org.apache.nifi.avro;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -291,14 +292,39 @@ public class TestAvroTypeUtil {
expects.put(new BigDecimal("0.123456789012345678"), "0.12345679"); expects.put(new BigDecimal("0.123456789012345678"), "0.12345679");
// String to BigDecimal
expects.put("123", "123.00000000");
expects.put("1234567890.12345678", "1234567890.12345678");
expects.put("123456789012345678", "123456789012345678.00000000");
expects.put("0.1234567890123456", "0.12345679");
expects.put("Not a number", "java.lang.NumberFormatException");
// Integer to BigDecimal
expects.put(123, "123.00000000");
expects.put(-1234567, "-1234567.00000000");
// Long to BigDecimal
expects.put(123L, "123.00000000");
expects.put(123456789012345678L, "123456789012345678.00000000");
expects.forEach((rawValue, expect) -> { expects.forEach((rawValue, expect) -> {
final Object convertedValue = AvroTypeUtil.convertToAvroObject(rawValue, fieldSchema); final Object convertedValue;
try {
convertedValue = AvroTypeUtil.convertToAvroObject(rawValue, fieldSchema);
} catch (Exception e) {
if (expect.equals(e.getClass().getCanonicalName())) {
// Expected behavior.
return;
}
fail(String.format("Unexpected exception, %s with %s %s while expecting %s", e, rawValue.getClass().getSimpleName(), rawValue, expect));
return;
}
assertTrue(convertedValue instanceof ByteBuffer); assertTrue(convertedValue instanceof ByteBuffer);
final ByteBuffer serializedBytes = (ByteBuffer) convertedValue; final ByteBuffer serializedBytes = (ByteBuffer) convertedValue;
final BigDecimal bigDecimal = new Conversions.DecimalConversion().fromBytes(serializedBytes, fieldSchema, decimalType); final BigDecimal bigDecimal = new Conversions.DecimalConversion().fromBytes(serializedBytes, fieldSchema, decimalType);
assertEquals(String.format("%s should be converted to %s", rawValue, expect), expect, bigDecimal.toString()); assertEquals(String.format("%s %s should be converted to %s", rawValue.getClass().getSimpleName(), rawValue, expect), expect, bigDecimal.toString());
}); });
} }