diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java index a4e8c60841..4db4aa9bd8 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java @@ -226,19 +226,29 @@ public class JsonConverter { } private static KeyValueProto buildNumericKeyValueProto(JsonPrimitive value, String key) { - if (value.getAsString().contains(".")) { - return KeyValueProto.newBuilder() - .setKey(key) - .setType(KeyValueType.DOUBLE_V) - .setDoubleV(value.getAsDouble()) - .build(); + String valueAsString = value.getAsString(); + KeyValueProto.Builder builder = KeyValueProto.newBuilder().setKey(key); + if (valueAsString.contains("e") || valueAsString.contains("E")) { + //TODO: correct value conversion. We should make sure that if the value can't fit into Long or Double, we should send String + var bd = new BigDecimal(valueAsString); + if (bd.stripTrailingZeros().scale() <= 0) { + try { + return builder.setType(KeyValueType.LONG_V).setLongV(bd.longValueExact()).build(); + } catch (ArithmeticException e) { + return builder.setType(KeyValueType.DOUBLE_V).setDoubleV(bd.doubleValue()).build(); + } + } else { + return builder.setType(KeyValueType.DOUBLE_V).setDoubleV(bd.doubleValue()).build(); + } + } else if (valueAsString.contains(".")) { + return builder.setType(KeyValueType.DOUBLE_V).setDoubleV(value.getAsDouble()).build(); } else { try { long longValue = Long.parseLong(value.getAsString()); - return KeyValueProto.newBuilder().setKey(key).setType(KeyValueType.LONG_V) - .setLongV(longValue).build(); + return builder.setType(KeyValueType.LONG_V).setLongV(longValue).build(); } catch (NumberFormatException e) { - throw new JsonSyntaxException("Big integer values are not supported!"); + //TODO: correct value conversion. We should make sure that if the value can't fit into Long or Double, we should send String + return builder.setType(KeyValueType.DOUBLE_V).setDoubleV(new BigDecimal(valueAsString).doubleValue()).build(); } } } @@ -252,6 +262,7 @@ public class JsonConverter { String valueAsString = value.getAsString(); String key = valueEntry.getKey(); if (valueAsString.contains("e") || valueAsString.contains("E")) { + //TODO: correct value conversion. We should make sure that if the value can't fit into Long or Double, we should send String var bd = new BigDecimal(valueAsString); if (bd.stripTrailingZeros().scale() <= 0) { try { @@ -269,7 +280,8 @@ public class JsonConverter { long longValue = Long.parseLong(value.getAsString()); result.add(new LongDataEntry(key, longValue)); } catch (NumberFormatException e) { - throw new JsonSyntaxException("Big integer values are not supported!"); + //TODO: correct value conversion. We should make sure that if the value can't fit into Long or Double, we should send String + result.add(new DoubleDataEntry(key, new BigDecimal(valueAsString).doubleValue())); } } } diff --git a/common/transport/transport-api/src/test/java/JsonConverterTest.java b/common/transport/transport-api/src/test/java/JsonConverterTest.java index cedbef50c9..dc28b268f5 100644 --- a/common/transport/transport-api/src/test/java/JsonConverterTest.java +++ b/common/transport/transport-api/src/test/java/JsonConverterTest.java @@ -21,6 +21,8 @@ import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import java.util.ArrayList; + @RunWith(MockitoJUnitRunner.class) public class JsonConverterTest { @@ -38,6 +40,12 @@ public class JsonConverterTest { Assert.assertEquals(10.1, result.get(0L).get(0).getDoubleValue().get(), 0.0); } + @Test + public void testParseAttributesBigDecimalAsLong() { + var result = new ArrayList<>(JsonConverter.convertToAttributes(JSON_PARSER.parse("{\"meterReadingDelta\": 1E1}"))); + Assert.assertEquals(10L, result.get(0).getLongValue().get().longValue()); + } + @Test public void testParseAsDouble() { var result = JsonConverter.convertToTelemetry(JSON_PARSER.parse("{\"meterReadingDelta\": 1.1}"), 0L);