From d9669c9391146b402821f6fc872418ecbe0f3686 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Fri, 22 Mar 2024 14:05:25 +0200 Subject: [PATCH] Fix TbSubscriptionUtils order for matching KeyValueType and DataType --- .../subscription/TbSubscriptionUtils.java | 28 ++++++++++++---- .../server/utils/TbSubscriptionUtilsTest.java | 33 +++++++++++++++++++ .../server/common/data/EntityType.java | 3 +- .../server/common/data/kv/DataType.java | 15 ++++++++- 4 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 application/src/test/java/org/thingsboard/server/utils/TbSubscriptionUtilsTest.java diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbSubscriptionUtils.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbSubscriptionUtils.java index 24d54109be..4c3a1b2351 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbSubscriptionUtils.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbSubscriptionUtils.java @@ -36,7 +36,6 @@ import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.KeyValueProto; -import org.thingsboard.server.gen.transport.TransportProtos.KeyValueType; import org.thingsboard.server.gen.transport.TransportProtos.SubscriptionMgrMsgProto; import org.thingsboard.server.gen.transport.TransportProtos.TbAlarmDeleteProto; import org.thingsboard.server.gen.transport.TransportProtos.TbAlarmUpdateProto; @@ -54,6 +53,7 @@ import org.thingsboard.server.service.ws.notification.sub.NotificationsSubscript import org.thingsboard.server.service.ws.telemetry.sub.AlarmSubscriptionUpdate; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -62,6 +62,14 @@ import java.util.UUID; public class TbSubscriptionUtils { + private static final DataType[] dataTypeByProtoNumber; + + static { + int arraySize = Arrays.stream(DataType.values()).mapToInt(DataType::getProtoNumber).max().orElse(0); + dataTypeByProtoNumber = new DataType[arraySize + 1]; + Arrays.stream(DataType.values()).forEach(dataType -> dataTypeByProtoNumber[dataType.getProtoNumber()] = dataType); + } + public static ToCoreMsg toSubEventProto(String serviceId, TbEntitySubEvent event) { SubscriptionMgrMsgProto.Builder msgBuilder = SubscriptionMgrMsgProto.newBuilder(); var builder = TbEntitySubEventProto.newBuilder() @@ -235,7 +243,7 @@ public class TbSubscriptionUtils { private static TsKvProto.Builder toKeyValueProto(long ts, KvEntry attr) { KeyValueProto.Builder dataBuilder = KeyValueProto.newBuilder(); dataBuilder.setKey(attr.getKey()); - dataBuilder.setType(KeyValueType.forNumber(attr.getDataType().ordinal())); + dataBuilder.setType(toProto(attr.getDataType())); switch (attr.getDataType()) { case BOOLEAN: attr.getBooleanValue().ifPresent(dataBuilder::setBoolV); @@ -259,7 +267,7 @@ public class TbSubscriptionUtils { private static TransportProtos.TsValueProto toTsValueProto(long ts, KvEntry attr) { TransportProtos.TsValueProto.Builder dataBuilder = TransportProtos.TsValueProto.newBuilder(); dataBuilder.setTs(ts); - dataBuilder.setType(KeyValueType.forNumber(attr.getDataType().ordinal())); + dataBuilder.setType(toProto(attr.getDataType())); switch (attr.getDataType()) { case BOOLEAN: attr.getBooleanValue().ifPresent(dataBuilder::setBoolV); @@ -299,8 +307,7 @@ public class TbSubscriptionUtils { private static KvEntry getKvEntry(KeyValueProto proto) { KvEntry entry = null; - DataType type = DataType.values()[proto.getType().getNumber()]; - switch (type) { + switch (fromProto(proto.getType())) { case BOOLEAN: entry = new BooleanDataEntry(proto.getKey(), proto.getBoolV()); break; @@ -328,8 +335,7 @@ public class TbSubscriptionUtils { private static KvEntry getKvEntry(String key, TransportProtos.TsValueProto proto) { KvEntry entry = null; - DataType type = DataType.values()[proto.getType().getNumber()]; - switch (type) { + switch (fromProto(proto.getType())) { case BOOLEAN: entry = new BooleanDataEntry(key, proto.getBoolV()); break; @@ -448,4 +454,12 @@ public class TbSubscriptionUtils { return ToCoreNotificationMsg.newBuilder().setToLocalSubscriptionServiceMsg(result).build(); } + public static TransportProtos.KeyValueType toProto(DataType dataType) { + return TransportProtos.KeyValueType.forNumber(dataType.getProtoNumber()); + } + + public static DataType fromProto(TransportProtos.KeyValueType keyValueType) { + return dataTypeByProtoNumber[keyValueType.getNumber()]; + } + } diff --git a/application/src/test/java/org/thingsboard/server/utils/TbSubscriptionUtilsTest.java b/application/src/test/java/org/thingsboard/server/utils/TbSubscriptionUtilsTest.java new file mode 100644 index 0000000000..a3f1f0f0fa --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/utils/TbSubscriptionUtilsTest.java @@ -0,0 +1,33 @@ +/** + * Copyright © 2016-2024 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. + */ +package org.thingsboard.server.utils; + +import org.junit.Test; +import org.thingsboard.server.common.data.kv.DataType; +import org.thingsboard.server.service.subscription.TbSubscriptionUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TbSubscriptionUtilsTest { + + @Test + public void protoDataTypeSerialization() { + for (DataType dataType : DataType.values()) { + assertThat(TbSubscriptionUtils.fromProto(TbSubscriptionUtils.toProto(dataType))).as(dataType.name()).isEqualTo(dataType); + } + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java index fb4fe1011e..3580a86bcc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityType.java @@ -26,6 +26,7 @@ import java.util.stream.Collectors; * @author Andrew Shvayka */ public enum EntityType { + TENANT(1), CUSTOMER(2), USER(3), @@ -63,7 +64,7 @@ public enum EntityType { @Getter private final int protoNumber; // Corresponds to EntityTypeProto - private EntityType(int protoNumber) { + EntityType(int protoNumber) { this.protoNumber = protoNumber; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/DataType.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/DataType.java index a9d857ca9e..a8ad9b42c1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/DataType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/DataType.java @@ -15,8 +15,21 @@ */ package org.thingsboard.server.common.data.kv; +import lombok.Getter; + public enum DataType { - STRING, LONG, BOOLEAN, DOUBLE, JSON; + BOOLEAN(0), + LONG(1), + DOUBLE(2), + STRING(3), + JSON(4); + + @Getter + private final int protoNumber; // Corresponds to KeyValueType + + DataType(int protoNumber) { + this.protoNumber = protoNumber; + } }