From 5eadc90d262bbe3f8c8696aef17f86e372e42ccd Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 18 Dec 2023 10:00:47 +0100 Subject: [PATCH] added custome serializer for device profile --- .../server/common/data/DeviceProfile.java | 4 + .../server/common/util/ProtoUtils.java | 125 +++++++++++++----- common/proto/src/main/proto/queue.proto | 61 ++++++--- .../dao/device/DeviceProfileRedisCache.java | 22 ++- 4 files changed, 164 insertions(+), 48 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java index be4426a1d4..020836d31a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java @@ -21,6 +21,8 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; @@ -78,6 +80,8 @@ public class DeviceProfile extends BaseData implements HasName, @Valid private transient DeviceProfileData profileData; @JsonIgnore + @Getter + @Setter private byte[] profileDataBytes; @NoXss @ApiModelProperty(position = 13, value = "Unique provisioning key used by 'Device Provisioning' feature.") diff --git a/common/proto/src/main/java/org/thingsboard/server/common/util/ProtoUtils.java b/common/proto/src/main/java/org/thingsboard/server/common/util/ProtoUtils.java index 86678db00a..95dac5d4ee 100644 --- a/common/proto/src/main/java/org/thingsboard/server/common/util/ProtoUtils.java +++ b/common/proto/src/main/java/org/thingsboard/server/common/util/ProtoUtils.java @@ -19,18 +19,25 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.google.protobuf.ByteString; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.DeviceProfileProvisionType; +import org.thingsboard.server.common.data.DeviceProfileType; +import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.data.CoapDeviceTransportConfiguration; import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration; import org.thingsboard.server.common.data.device.data.PowerMode; import org.thingsboard.server.common.data.device.data.PowerSavingConfiguration; import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.OtaPackageId; +import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.AttributeKey; import org.thingsboard.server.common.data.kv.AttributeKvEntry; @@ -68,6 +75,7 @@ import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.UUID; +import java.util.function.Function; import java.util.stream.Collectors; public class ProtoUtils { @@ -517,7 +525,9 @@ public class ProtoUtils { .setCustomerIdLSB(getLsb(device.getCustomerId())) .setDeviceIdMSB(device.getId().getId().getMostSignificantBits()) .setDeviceIdLSB(device.getId().getId().getLeastSignificantBits()) + .setCreatedTime(device.getCreatedTime()) .setDeviceName(device.getName()) + .setDeviceLabel(toProtoString(device.getLabel())) .setDeviceType(device.getType()) .setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits()) .setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits()) @@ -529,10 +539,6 @@ public class ProtoUtils { .setExternalIdMSB(getMsb(device.getExternalId())) .setExternalIdLSB(getLsb(device.getExternalId())); - if (device.getLabel() != null) { - builder.setDeviceLabel(device.getLabel()); - } - if (device.getDeviceDataBytes() != null) { builder.setDeviceData(ByteString.copyFrom(device.getDeviceDataBytes())); } @@ -540,34 +546,76 @@ public class ProtoUtils { return builder.build(); } - public static Device fromDeviceProto(TransportProtos.DeviceProto deviceProto) { - Device device = new Device(new DeviceId(new UUID(deviceProto.getDeviceIdMSB(), deviceProto.getDeviceIdLSB()))); - device.setTenantId(new TenantId(new UUID(deviceProto.getTenantIdMSB(), deviceProto.getTenantIdLSB()))); - device.setCustomerId(new CustomerId(new UUID(deviceProto.getCustomerIdMSB(), deviceProto.getCustomerIdLSB()))); - device.setName(deviceProto.getDeviceName()); - device.setLabel(deviceProto.getDeviceLabel()); - device.setType(deviceProto.getDeviceType()); - device.setDeviceProfileId(new DeviceProfileId(new UUID(deviceProto.getDeviceProfileIdMSB(), deviceProto.getDeviceProfileIdLSB()))); - device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceProto.getAdditionalInfo())); - device.setFirmwareId(createOtaPackageId(deviceProto.getFirmwareIdMSB(), deviceProto.getFirmwareIdLSB())); - device.setSoftwareId(createOtaPackageId(deviceProto.getSoftwareIdMSB(), deviceProto.getSoftwareIdLSB())); - device.setExternalId(createDeviceId(deviceProto.getExternalIdMSB(), deviceProto.getExternalIdLSB())); - device.setDeviceDataBytes(deviceProto.getDeviceData().toByteArray()); + public static Device fromDeviceProto(TransportProtos.DeviceProto proto) { + Device device = new Device(getEntityId(proto.getDeviceIdMSB(), proto.getDeviceIdLSB(), DeviceId::new)); + device.setCreatedTime(proto.getCreatedTime()); + device.setTenantId(getEntityId(proto.getTenantIdMSB(), proto.getTenantIdLSB(), TenantId::new)); + device.setCustomerId(getEntityId(proto.getCustomerIdMSB(), proto.getCustomerIdLSB(), CustomerId::new)); + device.setName(proto.getDeviceName()); + device.setLabel(fromProtoString(proto.getDeviceLabel())); + device.setType(proto.getDeviceType()); + device.setDeviceProfileId(getEntityId(proto.getDeviceProfileIdMSB(), proto.getDeviceProfileIdLSB(), DeviceProfileId::new)); + device.setAdditionalInfo(JacksonUtil.toJsonNode(proto.getAdditionalInfo())); + device.setFirmwareId(getEntityId(proto.getFirmwareIdMSB(), proto.getFirmwareIdLSB(), OtaPackageId::new)); + device.setSoftwareId(getEntityId(proto.getSoftwareIdMSB(), proto.getSoftwareIdLSB(), OtaPackageId::new)); + device.setExternalId(getEntityId(proto.getExternalIdMSB(), proto.getExternalIdLSB(), DeviceId::new)); + device.setDeviceDataBytes(proto.getDeviceData().toByteArray()); return device; } - private static OtaPackageId createOtaPackageId(long msb, long lsb) { - if (msb != 0 || lsb != 0) { - return new OtaPackageId(new UUID(msb, lsb)); - } - return null; - } - - private static DeviceId createDeviceId(long msb, long lsb) { - if (msb != 0 || lsb != 0) { - return new DeviceId(new UUID(msb, lsb)); - } - return null; + public static TransportProtos.DeviceProfileProto toDeviceProfileProto(DeviceProfile deviceProfile) { + return TransportProtos.DeviceProfileProto.newBuilder() + .setTenantIdMSB(getMsb(deviceProfile.getTenantId())) + .setTenantIdLSB(getLsb(deviceProfile.getTenantId())) + .setDeviceProfileIdMSB(getMsb(deviceProfile.getId())) + .setDeviceProfileIdLSB(getLsb(deviceProfile.getId())) + .setCreatedTime(deviceProfile.getCreatedTime()) + .setName(deviceProfile.getName()) + .setIsDefault(deviceProfile.isDefault()) + .setType(deviceProfile.getType().name()) + .setTransportType(deviceProfile.getTransportType().name()) + .setProvisionType(deviceProfile.getProvisionType().name()) + .setDeviceProfileData(ByteString.copyFrom(deviceProfile.getProfileDataBytes())) + .setDescription(toProtoString(deviceProfile.getDescription())) + .setImage(toProtoString(deviceProfile.getImage())) + .setDefaultRuleChainIdMSB(getMsb(deviceProfile.getDefaultRuleChainId())) + .setDefaultRuleChainIdLSB(getMsb(deviceProfile.getDefaultRuleChainId())) + .setDefaultDashboardIdMSB(getMsb(deviceProfile.getDefaultDashboardId())) + .setDefaultDashboardIdLSB(getLsb(deviceProfile.getDefaultDashboardId())) + .setDefaultQueueName(toProtoString(deviceProfile.getDefaultQueueName())) + .setProvisionDeviceKey(toProtoString(deviceProfile.getProvisionDeviceKey())) + .setFirmwareIdMSB(getMsb(deviceProfile.getFirmwareId())) + .setFirmwareIdLSB(getLsb(deviceProfile.getFirmwareId())) + .setSoftwareIdMSB(getMsb(deviceProfile.getSoftwareId())) + .setSoftwareIdLSB(getLsb(deviceProfile.getSoftwareId())) + .setDefaultEdgeRuleChainIdMSB(getMsb(deviceProfile.getDefaultEdgeRuleChainId())) + .setDefaultEdgeRuleChainIdLSB(getLsb(deviceProfile.getDefaultEdgeRuleChainId())) + .setExternalIdMSB(getMsb(deviceProfile.getExternalId())) + .setExternalIdLSB(getLsb(deviceProfile.getExternalId())).build(); + } + + public static DeviceProfile fromDeviceProfileProto(TransportProtos.DeviceProfileProto proto) { + DeviceProfile deviceProfile = new DeviceProfile(getEntityId(proto.getDeviceProfileIdMSB(), proto.getDeviceProfileIdLSB(), DeviceProfileId::new)); + deviceProfile.setCreatedTime(proto.getCreatedTime()); + deviceProfile.setTenantId(getEntityId(proto.getTenantIdMSB(), proto.getTenantIdLSB(), TenantId::new)); + deviceProfile.setName(proto.getName()); + deviceProfile.setDefault(proto.getIsDefault()); + deviceProfile.setType(DeviceProfileType.valueOf(proto.getType())); + deviceProfile.setTransportType(DeviceTransportType.valueOf(proto.getTransportType())); + deviceProfile.setProvisionType(DeviceProfileProvisionType.valueOf(proto.getProvisionType())); + deviceProfile.setProfileDataBytes(proto.getDeviceProfileData().toByteArray()); + deviceProfile.setDescription(fromProtoString(proto.getDescription())); + deviceProfile.setImage(fromProtoString(proto.getImage())); + deviceProfile.setDefaultRuleChainId(getEntityId(proto.getDefaultRuleChainIdMSB(), proto.getDefaultRuleChainIdLSB(), RuleChainId::new)); + deviceProfile.setDefaultDashboardId(getEntityId(proto.getDefaultDashboardIdMSB(), proto.getDefaultDashboardIdLSB(), DashboardId::new)); + deviceProfile.setDefaultQueueName(fromProtoString(proto.getDefaultQueueName())); + deviceProfile.setProvisionDeviceKey(fromProtoString(proto.getProvisionDeviceKey())); + deviceProfile.setFirmwareId(getEntityId(proto.getFirmwareIdMSB(), proto.getFirmwareIdLSB(), OtaPackageId::new)); + deviceProfile.setSoftwareId(getEntityId(proto.getSoftwareIdMSB(), proto.getSoftwareIdLSB(), OtaPackageId::new)); + deviceProfile.setDefaultEdgeRuleChainId(getEntityId(proto.getDefaultEdgeRuleChainIdMSB(), proto.getDefaultEdgeRuleChainIdLSB(), RuleChainId::new)); + deviceProfile.setExternalId(getEntityId(proto.getExternalIdMSB(), proto.getExternalIdLSB(), DeviceProfileId::new)); + + return deviceProfile; } public static TransportProtos.DeviceInfoProto toDeviceInfoProto(Device device) throws JsonProcessingException { @@ -609,14 +657,29 @@ public class ProtoUtils { return builder.build(); } - public static Long getMsb(EntityId entityId) { + private static T getEntityId(long msb, long lsb, Function entityId) { + if (msb != 0 || lsb != 0) { + return entityId.apply(new UUID(msb, lsb)); + } + return null; + } + + private static String toProtoString(String str) { + return str != null ? str : ""; + } + + private static String fromProtoString(String str) { + return StringUtils.isNotEmpty(str) ? str : null; + } + + private static Long getMsb(EntityId entityId) { if (entityId != null) { return entityId.getId().getMostSignificantBits(); } return 0L; } - public static Long getLsb(EntityId entityId) { + private static Long getLsb(EntityId entityId) { if (entityId != null) { return entityId.getId().getLeastSignificantBits(); } diff --git a/common/proto/src/main/proto/queue.proto b/common/proto/src/main/proto/queue.proto index eaefb08952..d8f5517e38 100644 --- a/common/proto/src/main/proto/queue.proto +++ b/common/proto/src/main/proto/queue.proto @@ -188,21 +188,52 @@ message DeviceProto { int64 tenantIdLSB = 2; int64 deviceIdMSB = 3; int64 deviceIdLSB = 4; - string deviceName = 5; - string deviceLabel = 6; - string deviceType = 7; - string additionalInfo = 8; - int64 deviceProfileIdMSB = 9; - int64 deviceProfileIdLSB = 10; - int64 customerIdMSB = 11; - int64 customerIdLSB = 12; - bytes deviceData = 13; - int64 firmwareIdMSB = 14; - int64 firmwareIdLSB = 15; - int64 softwareIdMSB = 16; - int64 softwareIdLSB = 17; - int64 externalIdMSB = 18; - int64 externalIdLSB = 19; + int64 createdTime = 5; + string deviceName = 6; + string deviceLabel = 7; + string deviceType = 8; + string additionalInfo = 9; + int64 deviceProfileIdMSB = 10; + int64 deviceProfileIdLSB = 11; + int64 customerIdMSB = 12; + int64 customerIdLSB = 13; + bytes deviceData = 14; + int64 firmwareIdMSB = 15; + int64 firmwareIdLSB = 16; + int64 softwareIdMSB = 17; + int64 softwareIdLSB = 18; + int64 externalIdMSB = 19; + int64 externalIdLSB = 20; +} + +message DeviceProfileProto { + int64 tenantIdMSB = 1; + int64 tenantIdLSB = 2; + int64 deviceProfileIdMSB = 3; + int64 deviceProfileIdLSB = 4; + int64 createdTime = 5; + string name = 6; + string description = 7; + string image = 8; + bool isDefault = 9; + string type = 10; + string transportType = 11; + string provisionType = 12; + int64 defaultRuleChainIdMSB = 13; + int64 defaultRuleChainIdLSB = 14; + int64 defaultDashboardIdMSB = 15; + int64 defaultDashboardIdLSB = 16; + string defaultQueueName = 17; + bytes deviceProfileData = 18; + string provisionDeviceKey = 19; + int64 firmwareIdMSB = 20; + int64 firmwareIdLSB = 21; + int64 softwareIdMSB = 22; + int64 softwareIdLSB = 23; + int64 defaultEdgeRuleChainIdMSB = 24; + int64 defaultEdgeRuleChainIdLSB = 25; + int64 externalIdMSB = 26; + int64 externalIdLSB = 27; } /** diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileRedisCache.java index a68c169b49..a61762c9aa 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileRedisCache.java @@ -15,21 +15,39 @@ */ package org.thingsboard.server.dao.device; +import com.google.protobuf.InvalidProtocolBufferException; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.SerializationException; import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbJsonRedisSerializer; +import org.thingsboard.server.cache.TbRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.util.ProtoUtils; +import org.thingsboard.server.gen.transport.TransportProtos; @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") @Service("DeviceProfileCache") public class DeviceProfileRedisCache extends RedisTbTransactionalCache { public DeviceProfileRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.DEVICE_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(DeviceProfile.class)); + super(CacheConstants.DEVICE_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbRedisSerializer() { + @Override + public byte[] serialize(DeviceProfile deviceProfile) throws SerializationException { + return ProtoUtils.toDeviceProfileProto(deviceProfile).toByteArray(); + } + + @Override + public DeviceProfile deserialize(DeviceProfileCacheKey key, byte[] bytes) throws SerializationException { + try { + return ProtoUtils.fromDeviceProfileProto(TransportProtos.DeviceProfileProto.parseFrom(bytes)); + } catch (InvalidProtocolBufferException e) { + throw new SerializationException(e.getMessage()); + } + } + }); } }