Browse Source

Added support of BigDecimal to the JsonConverter

pull/4113/head
Andrii Shvaika 6 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.ValidateDeviceTokenRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg;
import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -245,12 +246,25 @@ public class JsonConverter {
} }
private static void parseNumericValue(List<KvEntry> result, Entry<String, JsonElement> valueEntry, JsonPrimitive value) { private static void parseNumericValue(List<KvEntry> result, Entry<String, JsonElement> valueEntry, JsonPrimitive value) {
if (value.getAsString().contains(".")) { String valueAsString = value.getAsString();
result.add(new DoubleDataEntry(valueEntry.getKey(), value.getAsDouble())); 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 { } else {
try { try {
long longValue = Long.parseLong(value.getAsString()); long longValue = Long.parseLong(value.getAsString());
result.add(new LongDataEntry(valueEntry.getKey(), longValue)); result.add(new LongDataEntry(key, longValue));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new JsonSyntaxException("Big integer values are not supported!"); throw new JsonSyntaxException("Big integer values are not supported!");
} }
@ -285,7 +299,8 @@ public class JsonConverter {
return result; return result;
} }
public static JsonObject getJsonObjectForGateway(String deviceName, TransportProtos.GetAttributeResponseMsg responseMsg) { public static JsonObject getJsonObjectForGateway(String deviceName, TransportProtos.GetAttributeResponseMsg
responseMsg) {
JsonObject result = new JsonObject(); JsonObject result = new JsonObject();
result.addProperty("id", responseMsg.getRequestId()); result.addProperty("id", responseMsg.getRequestId());
result.addProperty(DEVICE_PROPERTY, deviceName); result.addProperty(DEVICE_PROPERTY, deviceName);
@ -298,7 +313,8 @@ public class JsonConverter {
return result; return result;
} }
public static JsonObject getJsonObjectForGateway(String deviceName, AttributeUpdateNotificationMsg notificationMsg) { public static JsonObject getJsonObjectForGateway(String deviceName, AttributeUpdateNotificationMsg
notificationMsg) {
JsonObject result = new JsonObject(); JsonObject result = new JsonObject();
result.addProperty(DEVICE_PROPERTY, deviceName); result.addProperty(DEVICE_PROPERTY, deviceName);
result.add("data", toJson(notificationMsg)); result.add("data", toJson(notificationMsg));
@ -446,7 +462,8 @@ public class JsonConverter {
return result; return result;
} }
public static JsonElement toGatewayJson(String deviceName, TransportProtos.ProvisionDeviceResponseMsg responseRequest) { public static JsonElement toGatewayJson(String deviceName, TransportProtos.ProvisionDeviceResponseMsg
responseRequest) {
JsonObject result = new JsonObject(); JsonObject result = new JsonObject();
result.addProperty(DEVICE_PROPERTY, deviceName); result.addProperty(DEVICE_PROPERTY, deviceName);
result.add("data", JsonConverter.toJson(responseRequest)); result.add("data", JsonConverter.toJson(responseRequest));
@ -496,15 +513,18 @@ public class JsonConverter {
return result; 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); 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); 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<>(); Map<Long, List<KvEntry>> result = sorted ? new TreeMap<>() : new HashMap<>();
convertToTelemetry(jsonElement, systemTs, result, null); convertToTelemetry(jsonElement, systemTs, result, null);
return result; return result;
@ -574,7 +594,8 @@ public class JsonConverter {
.build(); .build();
} }
private static TransportProtos.ProvisionDeviceCredentialsMsg buildProvisionDeviceCredentialsMsg(String provisionKey, String provisionSecret) { private static TransportProtos.ProvisionDeviceCredentialsMsg buildProvisionDeviceCredentialsMsg(String
provisionKey, String provisionSecret) {
return TransportProtos.ProvisionDeviceCredentialsMsg.newBuilder() return TransportProtos.ProvisionDeviceCredentialsMsg.newBuilder()
.setProvisionDeviceKey(provisionKey) .setProvisionDeviceKey(provisionKey)
.setProvisionDeviceSecret(provisionSecret) .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; return;
} }
if (config.getRound() != null) { if (config.getRound() != null) {
delta = delta.setScale(config.getRound(), RoundingMode.HALF_UP); delta = delta.setScale(config.getRound(), RoundingMode.HALF_UP);
} }
ObjectNode result = (ObjectNode) json; 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()) { if (config.isAddPeriodBetweenMsgs()) {
long period = previousData != null ? currentTs - previousData.ts : 0; long period = previousData != null ? currentTs - previousData.ts : 0;

Loading…
Cancel
Save