From 270892f9268bc8e5824a0104f968126aa96d5fa2 Mon Sep 17 00:00:00 2001 From: Koji Kawamura Date: Tue, 6 Feb 2018 16:36:15 +0900 Subject: [PATCH] NIFI-4846: AvroTypeUtil to support more input types for logical decimal conversion Signed-off-by: Matthew Burgess This closes #2451 --- .../org/apache/nifi/avro/AvroTypeUtil.java | 11 +++++++ .../apache/nifi/avro/TestAvroTypeUtil.java | 30 +++++++++++++++++-- 2 files changed, 39 insertions(+), 2 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 f7b8d9bd15..c4f69d4cb0 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 @@ -533,8 +533,19 @@ public class AvroTypeUtil { final BigDecimal rawDecimal; if (rawValue instanceof BigDecimal) { rawDecimal = (BigDecimal) rawValue; + } else if (rawValue instanceof Double) { 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 { throw new IllegalTypeConversionException("Cannot convert value " + rawValue + " of type " + rawValue.getClass() + " to a logical decimal"); } 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 d644f7c723..d24488e7d1 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 @@ -19,6 +19,7 @@ package org.apache.nifi.avro; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.IOException; import java.math.BigDecimal; @@ -291,14 +292,39 @@ public class TestAvroTypeUtil { 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) -> { - 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); final ByteBuffer serializedBytes = (ByteBuffer) convertedValue; 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()); }); }