Browse Source

Added support of BigDecimal to the JsonConverter

pull/4113/head
Andrii Shvaika 5 years ago
parent
commit
a15e991d23
  1. 41
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java
  2. 53
      common/transport/transport-api/src/test/java/JsonConverterTest.java
  3. 7
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/CalculateDeltaNode.java

41
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java

@ -51,6 +51,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCre
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -245,12 +246,25 @@ public class JsonConverter {
}
private static void parseNumericValue(List<KvEntry> result, Entry<String, JsonElement> valueEntry, JsonPrimitive value) {
if (value.getAsString().contains(".")) {
result.add(new DoubleDataEntry(valueEntry.getKey(), value.getAsDouble()));
String valueAsString = value.getAsString();
String key = valueEntry.getKey();
if (valueAsString.contains("e") || valueAsString.contains("E")) {
var bd = new BigDecimal(valueAsString);
if (bd.stripTrailingZeros().scale() <= 0) {
try {
result.add(new LongDataEntry(key, bd.longValueExact()));
} catch (ArithmeticException e) {
result.add(new DoubleDataEntry(key, bd.doubleValue()));
}
} else {
result.add(new DoubleDataEntry(key, bd.doubleValue()));
}
} else if (valueAsString.contains(".")) {
result.add(new DoubleDataEntry(key, value.getAsDouble()));
} else {
try {
long longValue = Long.parseLong(value.getAsString());
result.add(new LongDataEntry(valueEntry.getKey(), longValue));
result.add(new LongDataEntry(key, longValue));
} catch (NumberFormatException e) {
throw new JsonSyntaxException("Big integer values are not supported!");
}
@ -285,7 +299,8 @@ public class JsonConverter {
return result;
}
public static JsonObject getJsonObjectForGateway(String deviceName, TransportProtos.GetAttributeResponseMsg responseMsg) {
public static JsonObject getJsonObjectForGateway(String deviceName, TransportProtos.GetAttributeResponseMsg
responseMsg) {
JsonObject result = new JsonObject();
result.addProperty("id", responseMsg.getRequestId());
result.addProperty(DEVICE_PROPERTY, deviceName);
@ -298,7 +313,8 @@ public class JsonConverter {
return result;
}
public static JsonObject getJsonObjectForGateway(String deviceName, AttributeUpdateNotificationMsg notificationMsg) {
public static JsonObject getJsonObjectForGateway(String deviceName, AttributeUpdateNotificationMsg
notificationMsg) {
JsonObject result = new JsonObject();
result.addProperty(DEVICE_PROPERTY, deviceName);
result.add("data", toJson(notificationMsg));
@ -446,7 +462,8 @@ public class JsonConverter {
return result;
}
public static JsonElement toGatewayJson(String deviceName, TransportProtos.ProvisionDeviceResponseMsg responseRequest) {
public static JsonElement toGatewayJson(String deviceName, TransportProtos.ProvisionDeviceResponseMsg
responseRequest) {
JsonObject result = new JsonObject();
result.addProperty(DEVICE_PROPERTY, deviceName);
result.add("data", JsonConverter.toJson(responseRequest));
@ -496,15 +513,18 @@ public class JsonConverter {
return result;
}
public static Map<Long, List<KvEntry>> convertToTelemetry(JsonElement jsonElement, long systemTs) throws JsonSyntaxException {
public static Map<Long, List<KvEntry>> convertToTelemetry(JsonElement jsonElement, long systemTs) throws
JsonSyntaxException {
return convertToTelemetry(jsonElement, systemTs, false);
}
public static Map<Long, List<KvEntry>> convertToSortedTelemetry(JsonElement jsonElement, long systemTs) throws JsonSyntaxException {
public static Map<Long, List<KvEntry>> convertToSortedTelemetry(JsonElement jsonElement, long systemTs) throws
JsonSyntaxException {
return convertToTelemetry(jsonElement, systemTs, true);
}
public static Map<Long, List<KvEntry>> convertToTelemetry(JsonElement jsonElement, long systemTs, boolean sorted) throws JsonSyntaxException {
public static Map<Long, List<KvEntry>> convertToTelemetry(JsonElement jsonElement, long systemTs, boolean sorted) throws
JsonSyntaxException {
Map<Long, List<KvEntry>> result = sorted ? new TreeMap<>() : new HashMap<>();
convertToTelemetry(jsonElement, systemTs, result, null);
return result;
@ -574,7 +594,8 @@ public class JsonConverter {
.build();
}
private static TransportProtos.ProvisionDeviceCredentialsMsg buildProvisionDeviceCredentialsMsg(String provisionKey, String provisionSecret) {
private static TransportProtos.ProvisionDeviceCredentialsMsg buildProvisionDeviceCredentialsMsg(String
provisionKey, String provisionSecret) {
return TransportProtos.ProvisionDeviceCredentialsMsg.newBuilder()
.setProvisionDeviceKey(provisionKey)
.setProvisionDeviceSecret(provisionSecret)

53
common/transport/transport-api/src/test/java/JsonConverterTest.java

@ -0,0 +1,53 @@
/**
* Copyright © 2016-2021 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.google.gson.JsonParser;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
@RunWith(MockitoJUnitRunner.class)
public class JsonConverterTest {
private static final JsonParser JSON_PARSER = new JsonParser();
@Test
public void testParseBigDecimalAsLong() {
var result = JsonConverter.convertToTelemetry(JSON_PARSER.parse("{\"meterReadingDelta\": 1E+1}"), 0L);
Assert.assertEquals(10L, result.get(0L).get(0).getLongValue().get().longValue());
}
@Test
public void testParseBigDecimalAsDouble() {
var result = JsonConverter.convertToTelemetry(JSON_PARSER.parse("{\"meterReadingDelta\": 101E-1}"), 0L);
Assert.assertEquals(10.1, result.get(0L).get(0).getDoubleValue().get(), 0.0);
}
@Test
public void testParseAsDouble() {
var result = JsonConverter.convertToTelemetry(JSON_PARSER.parse("{\"meterReadingDelta\": 1.1}"), 0L);
Assert.assertEquals(1.1, result.get(0L).get(0).getDoubleValue().get(), 0.0);
}
@Test
public void testParseAsLong() {
var result = JsonConverter.convertToTelemetry(JSON_PARSER.parse("{\"meterReadingDelta\": 11}"), 0L);
Assert.assertEquals(11L, result.get(0L).get(0).getLongValue().get().longValue());
}
}

7
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/CalculateDeltaNode.java

@ -93,12 +93,17 @@ public class CalculateDeltaNode implements TbNode {
return;
}
if (config.getRound() != null) {
delta = delta.setScale(config.getRound(), RoundingMode.HALF_UP);
}
ObjectNode result = (ObjectNode) json;
result.put(config.getOutputValueKey(), delta);
if (delta.stripTrailingZeros().scale() > 0) {
result.put(config.getOutputValueKey(), delta.doubleValue());
} else {
result.put(config.getOutputValueKey(), delta.longValueExact());
}
if (config.isAddPeriodBetweenMsgs()) {
long period = previousData != null ? currentTs - previousData.ts : 0;

Loading…
Cancel
Save