Browse Source

Merge pull request #9851 from YevhenBondarenko/feature/serialization-improvements

serialization optimization
pull/9997/head
Andrew Shvayka 3 years ago
committed by GitHub
parent
commit
7e731dac85
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
  2. 8
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/device/DeviceMsgConstructorV1.java
  3. 7
      application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/tenant/TenantMsgConstructorV1.java
  4. 10
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessorV1.java
  5. 11
      application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/profile/DeviceProfileEdgeProcessorV1.java
  6. 2
      application/src/main/java/org/thingsboard/server/service/install/update/DefaultCacheCleanupService.java
  7. 11
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java
  8. 37
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java
  9. 8
      application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java
  10. 11
      application/src/main/java/org/thingsboard/server/service/queue/TbCoreConsumerStats.java
  11. 29
      application/src/main/java/org/thingsboard/server/service/queue/processing/AbstractConsumerService.java
  12. 8
      application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitVersionControlQueueService.java
  13. 4
      application/src/main/java/org/thingsboard/server/service/sync/vc/VersionControlTaskRedisCache.java
  14. 4
      application/src/main/java/org/thingsboard/server/service/sync/vc/autocommit/AutoCommitSettingsRedisCache.java
  15. 4
      application/src/main/java/org/thingsboard/server/service/sync/vc/repository/RepositorySettingsRedisCache.java
  16. 76
      application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java
  17. 19
      application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java
  18. 4
      application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java
  19. 2
      application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/AbstractDeviceProcessorTest.java
  20. 5
      application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java
  21. 3
      application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java
  22. 8
      common/cache/pom.xml
  23. 16
      common/cache/src/main/java/org/thingsboard/server/cache/TbJsonRedisSerializer.java
  24. 39
      common/cache/src/main/java/org/thingsboard/server/cache/TbTypedJsonRedisSerializer.java
  25. 23
      common/cache/src/main/java/org/thingsboard/server/cache/device/DeviceRedisCache.java
  26. 4
      common/cache/src/main/java/org/thingsboard/server/cache/resourceInfo/ResourceInfoRedisCache.java
  27. 4
      common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersSessionInvalidationRedisCache.java
  28. 1
      common/data/src/main/java/org/thingsboard/server/common/data/Device.java
  29. 4
      common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java
  30. 10
      common/proto/pom.xml
  31. 583
      common/proto/src/main/java/org/thingsboard/server/common/util/ProtoUtils.java
  32. 203
      common/proto/src/main/proto/queue.proto
  33. 82
      common/proto/src/test/java/org/thingsboard/server/common/util/ProtoUtilsTest.java
  34. 7
      common/queue/src/main/java/org/thingsboard/server/queue/notification/RemoteNotificationRuleProcessor.java
  35. 27
      common/queue/src/main/java/org/thingsboard/server/queue/util/DataDecodingEncodingService.java
  36. 52
      common/queue/src/main/java/org/thingsboard/server/queue/util/JavaDataDecodingEncodingService.java
  37. 16
      common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/ProtoTransportEntityService.java
  38. 6
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportDeviceProfileCache.java
  39. 4
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportTenantProfileCache.java
  40. 40
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportDeviceProfileCache.java
  41. 16
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportResourceCache.java
  42. 91
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java
  43. 51
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportTenantProfileCache.java
  44. 8
      common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java
  45. 18
      common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java
  46. 5
      dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmTypesRedisCache.java
  47. 4
      dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileRedisCache.java
  48. 4
      dao/src/main/java/org/thingsboard/server/dao/asset/AssetRedisCache.java
  49. 4
      dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardTitlesRedisCache.java
  50. 4
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsRedisCache.java
  51. 22
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileRedisCache.java
  52. 4
      dao/src/main/java/org/thingsboard/server/dao/edge/EdgeRedisCache.java
  53. 4
      dao/src/main/java/org/thingsboard/server/dao/entity/count/EntityCountRedisCache.java
  54. 4
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewRedisCache.java
  55. 4
      dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageRedisCache.java
  56. 4
      dao/src/main/java/org/thingsboard/server/dao/relation/RelationRedisCache.java
  57. 4
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantExistsRedisCache.java
  58. 4
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileRedisCache.java
  59. 4
      dao/src/main/java/org/thingsboard/server/dao/tenant/TenantRedisCache.java
  60. 4
      dao/src/main/java/org/thingsboard/server/dao/user/UserSettingsRedisCache.java
  61. 15
      dao/src/test/java/org/thingsboard/server/dao/service/TenantProfileServiceTest.java
  62. 7
      pom.xml

7
application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java

@ -29,7 +29,6 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.service.executors.PubSubRuleNodeExecutorProvider;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.rule.engine.api.NotificationCenter;
import org.thingsboard.rule.engine.api.SmsService;
@ -93,7 +92,6 @@ import org.thingsboard.server.dao.widget.WidgetsBundleService;
import org.thingsboard.server.queue.discovery.DiscoveryService;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
import org.thingsboard.server.service.edge.rpc.EdgeRpcService;
@ -101,6 +99,7 @@ import org.thingsboard.server.service.entitiy.entityview.TbEntityViewService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.executors.ExternalCallExecutorService;
import org.thingsboard.server.service.executors.NotificationExecutorService;
import org.thingsboard.server.service.executors.PubSubRuleNodeExecutorProvider;
import org.thingsboard.server.service.executors.SharedEventLoopGroupService;
import org.thingsboard.server.service.mail.MailExecutorService;
import org.thingsboard.server.service.profile.TbAssetProfileCache;
@ -184,10 +183,6 @@ public class ActorSystemContext {
@Getter
private DiscoveryService discoveryService;
@Autowired
@Getter
private DataDecodingEncodingService encodingService;
@Autowired
@Getter
private DeviceService deviceService;

8
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/device/DeviceMsgConstructorV1.java

@ -27,7 +27,6 @@ import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DeviceProfileUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import java.nio.charset.StandardCharsets;
@ -36,9 +35,6 @@ import java.nio.charset.StandardCharsets;
@TbCoreComponent
public class DeviceMsgConstructorV1 extends BaseDeviceMsgConstructor {
@Autowired
private DataDecodingEncodingService dataDecodingEncodingService;
@Autowired
private ImageService imageService;
@ -73,7 +69,7 @@ public class DeviceMsgConstructorV1 extends BaseDeviceMsgConstructor {
.setSoftwareIdLSB(device.getSoftwareId().getId().getLeastSignificantBits());
}
if (device.getDeviceData() != null) {
builder.setDeviceDataBytes(ByteString.copyFrom(dataDecodingEncodingService.encode(device.getDeviceData())));
builder.setDeviceDataBytes(ByteString.copyFrom(device.getDeviceDataBytes()));
}
return builder.build();
}
@ -103,7 +99,7 @@ public class DeviceMsgConstructorV1 extends BaseDeviceMsgConstructor {
.setName(deviceProfile.getName())
.setDefault(deviceProfile.isDefault())
.setType(deviceProfile.getType().name())
.setProfileDataBytes(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile.getProfileData())));
.setProfileDataBytes(ByteString.copyFrom(deviceProfile.getProfileDataBytes()));
if (deviceProfile.getDefaultQueueName() != null) {
builder.setDefaultQueueName(deviceProfile.getDefaultQueueName());
}

7
application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/tenant/TenantMsgConstructorV1.java

@ -16,7 +16,6 @@
package org.thingsboard.server.service.edge.rpc.constructor.tenant;
import com.google.protobuf.ByteString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Tenant;
@ -25,7 +24,6 @@ import org.thingsboard.server.gen.edge.v1.EdgeVersion;
import org.thingsboard.server.gen.edge.v1.TenantProfileUpdateMsg;
import org.thingsboard.server.gen.edge.v1.TenantUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.edge.rpc.utils.EdgeVersionUtils;
@ -33,9 +31,6 @@ import org.thingsboard.server.service.edge.rpc.utils.EdgeVersionUtils;
@TbCoreComponent
public class TenantMsgConstructorV1 implements TenantMsgConstructor {
@Autowired
private DataDecodingEncodingService dataDecodingEncodingService;
@Override
public TenantUpdateMsg constructTenantUpdateMsg(UpdateMsgType msgType, Tenant tenant) {
TenantUpdateMsg.Builder builder = TenantUpdateMsg.newBuilder()
@ -79,7 +74,7 @@ public class TenantMsgConstructorV1 implements TenantMsgConstructor {
@Override
public TenantProfileUpdateMsg constructTenantProfileUpdateMsg(UpdateMsgType msgType, TenantProfile tenantProfile, EdgeVersion edgeVersion) {
ByteString profileData = EdgeVersionUtils.isEdgeVersionOlderThan(edgeVersion, EdgeVersion.V_3_6_2) ?
ByteString.empty() : ByteString.copyFrom(dataDecodingEncodingService.encode(tenantProfile.getProfileData()));
ByteString.empty() : ByteString.copyFrom(tenantProfile.getProfileDataBytes());
TenantProfileUpdateMsg.Builder builder = TenantProfileUpdateMsg.newBuilder()
.setMsgType(msgType)
.setIdMSB(tenantProfile.getId().getId().getMostSignificantBits())

10
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/DeviceEdgeProcessorV1.java

@ -16,11 +16,9 @@
package org.thingsboard.server.service.edge.rpc.processor.device;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.device.data.DeviceData;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
@ -30,19 +28,14 @@ import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.gen.edge.v1.DeviceCredentialsUpdateMsg;
import org.thingsboard.server.gen.edge.v1.DeviceUpdateMsg;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import java.util.Optional;
import java.util.UUID;
@Component
@TbCoreComponent
public class DeviceEdgeProcessorV1 extends DeviceEdgeProcessor {
@Autowired
private DataDecodingEncodingService dataDecodingEncodingService;
@Override
protected Device constructDeviceFromUpdateMsg(TenantId tenantId, DeviceId deviceId, DeviceUpdateMsg deviceUpdateMsg) {
Device device = new Device();
@ -57,8 +50,7 @@ public class DeviceEdgeProcessorV1 extends DeviceEdgeProcessor {
UUID deviceProfileUUID = safeGetUUID(deviceUpdateMsg.getDeviceProfileIdMSB(), deviceUpdateMsg.getDeviceProfileIdLSB());
device.setDeviceProfileId(deviceProfileUUID != null ? new DeviceProfileId(deviceProfileUUID) : null);
Optional<DeviceData> deviceDataOpt = dataDecodingEncodingService.decode(deviceUpdateMsg.getDeviceDataBytes().toByteArray());
device.setDeviceData(deviceDataOpt.orElse(null));
device.setDeviceDataBytes(deviceUpdateMsg.getDeviceDataBytes().toByteArray());
UUID firmwareUUID = safeGetUUID(deviceUpdateMsg.getFirmwareIdMSB(), deviceUpdateMsg.getFirmwareIdLSB());
device.setFirmwareId(firmwareUUID != null ? new OtaPackageId(firmwareUUID) : null);

11
application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/device/profile/DeviceProfileEdgeProcessorV1.java

@ -16,34 +16,27 @@
package org.thingsboard.server.service.edge.rpc.processor.device.profile;
import com.datastax.oss.driver.api.core.uuid.Uuids;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
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.StringUtils;
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
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.gen.edge.v1.DeviceProfileUpdateMsg;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.UUID;
@Component
@TbCoreComponent
public class DeviceProfileEdgeProcessorV1 extends DeviceProfileEdgeProcessor {
@Autowired
private DataDecodingEncodingService dataDecodingEncodingService;
@Override
protected DeviceProfile constructDeviceProfileFromUpdateMsg(TenantId tenantId, DeviceProfileId deviceProfileId, DeviceProfileUpdateMsg deviceProfileUpdateMsg) {
DeviceProfile deviceProfile = new DeviceProfile();
@ -63,9 +56,7 @@ public class DeviceProfileEdgeProcessorV1 extends DeviceProfileEdgeProcessor {
? deviceProfileUpdateMsg.getProvisionDeviceKey() : null);
deviceProfile.setDefaultQueueName(deviceProfileUpdateMsg.getDefaultQueueName());
Optional<DeviceProfileData> profileDataOpt =
dataDecodingEncodingService.decode(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray());
deviceProfile.setProfileData(profileDataOpt.orElse(null));
deviceProfile.setProfileDataBytes(deviceProfileUpdateMsg.getProfileDataBytes().toByteArray());
String defaultQueueName = StringUtils.isNotBlank(deviceProfileUpdateMsg.getDefaultQueueName())
? deviceProfileUpdateMsg.getDefaultQueueName() : null;

2
application/src/main/java/org/thingsboard/server/service/install/update/DefaultCacheCleanupService.java

@ -97,7 +97,7 @@ public class DefaultCacheCleanupService implements CacheCleanupService {
break;
case "3.6.3":
log.info("Clearing cache to upgrade from version 3.6.3 to 3.7.0");
clearCacheByName(ATTRIBUTES_CACHE);
clearAll();
break;
default:
//Do nothing, since cache cleanup is optional.

11
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbClusterService.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.service.queue;
import com.google.protobuf.ByteString;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -57,6 +56,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.common.msg.rule.engine.DeviceEdgeUpdateMsg;
import org.thingsboard.server.common.msg.rule.engine.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.FromDeviceRPCResponseProto;
import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg;
@ -68,10 +68,9 @@ import org.thingsboard.server.queue.TbQueueCallback;
import org.thingsboard.server.queue.TbQueueProducer;
import org.thingsboard.server.queue.common.MultipleTbQueueCallbackWrapper;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.TopicService;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TopicService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.service.gateway_device.GatewayNotificationsService;
import org.thingsboard.server.service.ota.OtaPackageStateService;
import org.thingsboard.server.service.profile.TbAssetProfileCache;
@ -112,7 +111,6 @@ public class DefaultTbClusterService implements TbClusterService {
private OtaPackageStateService otaPackageStateService;
private final TopicService topicService;
private final DataDecodingEncodingService encodingService;
private final TbDeviceProfileCache deviceProfileCache;
private final TbAssetProfileCache assetProfileCache;
private final GatewayNotificationsService gatewayNotificationsService;
@ -351,10 +349,7 @@ public class DefaultTbClusterService implements TbClusterService {
public <T> void broadcastEntityChangeToTransport(TenantId tenantId, EntityId entityid, T entity, TbQueueCallback callback) {
String entityName = (entity instanceof HasName) ? ((HasName) entity).getName() : entity.getClass().getName();
log.trace("[{}][{}][{}] Processing [{}] change event", tenantId, entityid.getEntityType(), entityid.getId(), entityName);
TransportProtos.EntityUpdateMsg entityUpdateMsg = TransportProtos.EntityUpdateMsg.newBuilder()
.setEntityType(entityid.getEntityType().name())
.setData(ByteString.copyFrom(encodingService.encode(entity))).build();
ToTransportMsg transportMsg = ToTransportMsg.newBuilder().setEntityUpdateMsg(entityUpdateMsg).build();
ToTransportMsg transportMsg = ToTransportMsg.newBuilder().setEntityUpdateMsg(ProtoUtils.toEntityUpdateProto(entity)).build();
broadcast(transportMsg, callback);
}

37
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java

@ -28,6 +28,7 @@ import org.thingsboard.common.util.DonAsynchron;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.common.data.JavaSerDesUtil;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.event.ErrorEvent;
import org.thingsboard.server.common.data.event.Event;
@ -76,7 +77,6 @@ import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent;
import org.thingsboard.server.queue.provider.TbCoreQueueFactory;
import org.thingsboard.server.queue.util.AfterStartUp;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.edge.EdgeNotificationService;
@ -155,7 +155,6 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
DeviceStateService stateService,
TbLocalSubscriptionService localSubscriptionService,
SubscriptionManagerService subscriptionManagerService,
DataDecodingEncodingService encodingService,
TbCoreDeviceRpcService tbCoreDeviceRpcService,
StatsFactory statsFactory,
TbDeviceProfileCache deviceProfileCache,
@ -172,7 +171,7 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
NotificationSchedulerService notificationSchedulerService,
NotificationRuleProcessor notificationRuleProcessor,
TbImageService imageService) {
super(actorContext, encodingService, tenantProfileCache, deviceProfileCache, assetProfileCache, apiUsageStateService, partitionService, eventPublisher, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer(), jwtSettingsService);
super(actorContext, tenantProfileCache, deviceProfileCache, assetProfileCache, apiUsageStateService, partitionService, eventPublisher, tbCoreQueueFactory.createToCoreNotificationsMsgConsumer(), jwtSettingsService);
this.mainConsumer = tbCoreQueueFactory.createToCoreMsgConsumer();
this.usageStatsConsumer = tbCoreQueueFactory.createToUsageStatsServiceMsgConsumer();
this.firmwareStatesConsumer = tbCoreQueueFactory.createToOtaPackageStateServiceMsgConsumer();
@ -285,19 +284,6 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
}
}
callback.onSuccess();
} else if (!toCoreMsg.getToDeviceActorNotificationMsg().isEmpty()) {
// will be removed in 3.6.1 in favour of hasToDeviceActorNotification()
Optional<TbActorMsg> actorMsg = encodingService.decode(toCoreMsg.getToDeviceActorNotificationMsg().toByteArray());
if (actorMsg.isPresent()) {
TbActorMsg tbActorMsg = actorMsg.get();
if (tbActorMsg.getMsgType().equals(MsgType.DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG)) {
tbCoreDeviceRpcService.forwardRpcRequestToDeviceActor((ToDeviceRpcRequestActorMsg) tbActorMsg);
} else {
log.trace("[{}] Forwarding message to App Actor {}", id, actorMsg.get());
actorContext.tell(actorMsg.get());
}
}
callback.onSuccess();
} else if (toCoreMsg.hasNotificationSchedulerServiceMsg()) {
TransportProtos.NotificationSchedulerServiceMsg notificationSchedulerServiceMsg = toCoreMsg.getNotificationSchedulerServiceMsg();
log.trace("[{}] Forwarding message to notification scheduler service {}", id, toCoreMsg.getNotificationSchedulerServiceMsg());
@ -374,28 +360,15 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
} else if (toCoreNotification.hasComponentLifecycle()) {
handleComponentLifecycleMsg(id, ProtoUtils.fromProto(toCoreNotification.getComponentLifecycle()));
callback.onSuccess();
} else if (!toCoreNotification.getComponentLifecycleMsg().isEmpty()) {
//will be removed in 3.6.1 in favour of hasComponentLifecycle()
handleComponentLifecycleMsg(id, toCoreNotification.getComponentLifecycleMsg());
callback.onSuccess();
} else if (toCoreNotification.hasEdgeEventUpdate()) {
forwardToAppActor(id, ProtoUtils.fromProto(toCoreNotification.getEdgeEventUpdate()));
callback.onSuccess();
} else if (!toCoreNotification.getEdgeEventUpdateMsg().isEmpty()) {
//will be removed in 3.6.1 in favour of hasEdgeEventUpdate()
forwardToAppActor(id, encodingService.decode(toCoreNotification.getEdgeEventUpdateMsg().toByteArray()), callback);
} else if (toCoreNotification.hasToEdgeSyncRequest()) {
forwardToAppActor(id, ProtoUtils.fromProto(toCoreNotification.getToEdgeSyncRequest()));
callback.onSuccess();
} else if (!toCoreNotification.getToEdgeSyncRequestMsg().isEmpty()) {
//will be removed in 3.6.1 in favour of hasToEdgeSyncRequest()
forwardToAppActor(id, encodingService.decode(toCoreNotification.getToEdgeSyncRequestMsg().toByteArray()), callback);
} else if (toCoreNotification.hasFromEdgeSyncResponse()) {
forwardToAppActor(id, ProtoUtils.fromProto(toCoreNotification.getFromEdgeSyncResponse()));
callback.onSuccess();
} else if (!toCoreNotification.getFromEdgeSyncResponseMsg().isEmpty()) {
//will be removed in 3.6.1 in favour of hasFromEdgeSyncResponse()
forwardToAppActor(id, encodingService.decode(toCoreNotification.getFromEdgeSyncResponseMsg().toByteArray()), callback);
} else if (toCoreNotification.hasQueueUpdateMsg()) {
TransportProtos.QueueUpdateMsg queue = toCoreNotification.getQueueUpdateMsg();
partitionService.updateQueue(queue);
@ -410,9 +383,9 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService<ToCore
} else if (toCoreNotification.hasToSubscriptionMgrMsg()) {
forwardToSubMgrService(toCoreNotification.getToSubscriptionMgrMsg(), callback);
} else if (toCoreNotification.hasNotificationRuleProcessorMsg()) {
Optional<NotificationRuleTrigger> notificationRuleTrigger = encodingService.decode(toCoreNotification
.getNotificationRuleProcessorMsg().getTrigger().toByteArray());
notificationRuleTrigger.ifPresent(notificationRuleProcessor::process);
NotificationRuleTrigger notificationRuleTrigger =
JavaSerDesUtil.decode(toCoreNotification.getNotificationRuleProcessorMsg().getTrigger().toByteArray());
notificationRuleProcessor.process(notificationRuleTrigger);
callback.onSuccess();
} else if (toCoreNotification.hasResourceCacheInvalidateMsg()) {
forwardToResourceService(toCoreNotification.getResourceCacheInvalidateMsg(), callback);

8
application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java

@ -39,7 +39,6 @@ import org.thingsboard.server.queue.discovery.QueueKey;
import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent;
import org.thingsboard.server.queue.provider.TbRuleEngineQueueFactory;
import org.thingsboard.server.queue.util.AfterStartUp;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbRuleEngineComponent;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.profile.TbAssetProfileCache;
@ -71,7 +70,6 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
public DefaultTbRuleEngineConsumerService(TbRuleEngineConsumerContext ctx,
TbRuleEngineQueueFactory tbRuleEngineQueueFactory,
ActorSystemContext actorContext,
DataDecodingEncodingService encodingService,
TbRuleEngineDeviceRpcService tbDeviceRpcService,
QueueService queueService,
TbDeviceProfileCache deviceProfileCache,
@ -79,7 +77,7 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
TbTenantProfileCache tenantProfileCache,
TbApiUsageStateService apiUsageStateService,
PartitionService partitionService, ApplicationEventPublisher eventPublisher) {
super(actorContext, encodingService, tenantProfileCache, deviceProfileCache, assetProfileCache, apiUsageStateService, partitionService,
super(actorContext, tenantProfileCache, deviceProfileCache, assetProfileCache, apiUsageStateService, partitionService,
eventPublisher, tbRuleEngineQueueFactory.createToRuleEngineNotificationsMsgConsumer(), Optional.empty());
this.ctx = ctx;
this.tbDeviceRpcService = tbDeviceRpcService;
@ -152,10 +150,6 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService<
if (nfMsg.hasComponentLifecycle()) {
handleComponentLifecycleMsg(id, ProtoUtils.fromProto(nfMsg.getComponentLifecycle()));
callback.onSuccess();
} else if (!nfMsg.getComponentLifecycleMsg().isEmpty()) {
//will be removed in 3.6.1 in favour of hasComponentLifecycle()
handleComponentLifecycleMsg(id, nfMsg.getComponentLifecycleMsg());
callback.onSuccess();
} else if (nfMsg.hasFromDeviceRpcResponse()) {
TransportProtos.FromDeviceRPCResponseProto proto = nfMsg.getFromDeviceRpcResponse();
RpcError error = proto.getError() > 0 ? RpcError.values()[proto.getError()] : null;

11
application/src/main/java/org/thingsboard/server/service/queue/TbCoreConsumerStats.java

@ -109,10 +109,9 @@ public class TbCoreConsumerStats {
this.toCoreNfSubscriptionServiceCounter = register(statsFactory.createStatsCounter(statsKey, TO_CORE_NF_SUBSCRIPTION_SERVICE));
this.toCoreNfSubscriptionManagerCounter = register(statsFactory.createStatsCounter(statsKey, TO_CORE_NF_SUBSCRIPTION_MANAGER));
this.toCoreNfVersionControlResponseCounter = register(statsFactory.createStatsCounter(statsKey, TO_CORE_NF_VC_RESPONSE));
}
private StatsCounter register(StatsCounter counter){
private StatsCounter register(StatsCounter counter) {
counters.add(counter);
return counter;
}
@ -170,20 +169,12 @@ public class TbCoreConsumerStats {
toCoreNfDeviceRpcResponseCounter.increment();
} else if (msg.hasComponentLifecycle()) {
toCoreNfComponentLifecycleCounter.increment();
} else if (!msg.getComponentLifecycleMsg().isEmpty()) {
toCoreNfComponentLifecycleCounter.increment();
} else if (msg.hasEdgeEventUpdate()) {
toCoreNfEdgeEventUpdateCounter.increment();
} else if (!msg.getEdgeEventUpdateMsg().isEmpty()) {
toCoreNfEdgeEventUpdateCounter.increment();
} else if (msg.hasToEdgeSyncRequest()) {
toCoreNfEdgeSyncRequestCounter.increment();
} else if (!msg.getToEdgeSyncRequestMsg().isEmpty()) {
toCoreNfEdgeSyncRequestCounter.increment();
} else if (msg.hasFromEdgeSyncResponse()) {
toCoreNfEdgeSyncResponseCounter.increment();
} else if (!msg.getFromEdgeSyncResponseMsg().isEmpty()) {
toCoreNfEdgeSyncResponseCounter.increment();
} else if (msg.hasQueueUpdateMsg()) {
toCoreNfQueueUpdateCounter.increment();
} else if (msg.hasQueueDeleteMsg()) {

29
application/src/main/java/org/thingsboard/server/service/queue/processing/AbstractConsumerService.java

@ -15,7 +15,7 @@
*/
package org.thingsboard.server.service.queue.processing;
import com.google.protobuf.ByteString;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationEventPublisher;
@ -41,7 +41,6 @@ import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbApplicationEventListener;
import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent;
import org.thingsboard.server.queue.util.AfterStartUp;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.profile.TbAssetProfileCache;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
@ -62,13 +61,13 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@RequiredArgsConstructor
public abstract class AbstractConsumerService<N extends com.google.protobuf.GeneratedMessageV3> extends TbApplicationEventListener<PartitionChangeEvent> {
protected volatile ExecutorService notificationsConsumerExecutor;
protected volatile boolean stopped = false;
protected volatile boolean isReady = false;
protected final ActorSystemContext actorContext;
protected final DataDecodingEncodingService encodingService;
protected final TbTenantProfileCache tenantProfileCache;
protected final TbDeviceProfileCache deviceProfileCache;
protected final TbAssetProfileCache assetProfileCache;
@ -79,24 +78,6 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene
protected final TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer;
protected final Optional<JwtSettingsService> jwtSettingsService;
public AbstractConsumerService(ActorSystemContext actorContext, DataDecodingEncodingService encodingService,
TbTenantProfileCache tenantProfileCache, TbDeviceProfileCache deviceProfileCache,
TbAssetProfileCache assetProfileCache, TbApiUsageStateService apiUsageStateService,
PartitionService partitionService, ApplicationEventPublisher eventPublisher,
TbQueueConsumer<TbProtoQueueMsg<N>> nfConsumer, Optional<JwtSettingsService> jwtSettingsService) {
this.actorContext = actorContext;
this.encodingService = encodingService;
this.tenantProfileCache = tenantProfileCache;
this.deviceProfileCache = deviceProfileCache;
this.assetProfileCache = assetProfileCache;
this.apiUsageStateService = apiUsageStateService;
this.partitionService = partitionService;
this.eventPublisher = eventPublisher;
this.nfConsumer = nfConsumer;
this.jwtSettingsService = jwtSettingsService;
}
public void init(String nfConsumerThreadName) {
this.notificationsConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName(nfConsumerThreadName));
}
@ -166,12 +147,6 @@ public abstract class AbstractConsumerService<N extends com.google.protobuf.Gene
});
}
// To be removed in 3.6.1 in favour of handleComponentLifecycleMsg(UUID id, TbActorMsg actorMsg)
protected void handleComponentLifecycleMsg(UUID id, ByteString nfMsg) {
Optional<TbActorMsg> actorMsgOpt = encodingService.decode(nfMsg.toByteArray());
actorMsgOpt.ifPresent(tbActorMsg -> handleComponentLifecycleMsg(id, tbActorMsg));
}
protected void handleComponentLifecycleMsg(UUID id, TbActorMsg actorMsg) {
if (actorMsg instanceof ComponentLifecycleMsg) {
ComponentLifecycleMsg componentLifecycleMsg = (ComponentLifecycleMsg) actorMsg;

8
application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitVersionControlQueueService.java

@ -19,7 +19,6 @@ import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.google.protobuf.ByteString;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@ -45,6 +44,7 @@ import org.thingsboard.server.common.data.sync.vc.VersionCreationResult;
import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo;
import org.thingsboard.server.common.data.sync.vc.request.create.VersionCreateRequest;
import org.thingsboard.server.common.data.util.CollectionsUtil;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.CommitRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.EntitiesContentRequestMsg;
@ -59,7 +59,6 @@ import org.thingsboard.server.queue.TbQueueCallback;
import org.thingsboard.server.queue.TbQueueMsgMetadata;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.scheduler.SchedulerComponent;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.executors.VersionControlExecutor;
import org.thingsboard.server.service.sync.vc.data.ClearRepositoryGitRequest;
@ -97,7 +96,6 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
private final TbServiceInfoProvider serviceInfoProvider;
private final TbClusterService clusterService;
private final DataDecodingEncodingService encodingService;
private final DefaultEntitiesVersionControlService entitiesVersionControlService;
private final SchedulerComponent scheduler;
private final VersionControlExecutor executor;
@ -111,12 +109,10 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
private int msgChunkSize;
public DefaultGitVersionControlQueueService(TbServiceInfoProvider serviceInfoProvider, TbClusterService clusterService,
DataDecodingEncodingService encodingService,
@Lazy DefaultEntitiesVersionControlService entitiesVersionControlService,
SchedulerComponent scheduler, VersionControlExecutor executor) {
this.serviceInfoProvider = serviceInfoProvider;
this.clusterService = clusterService;
this.encodingService = encodingService;
this.entitiesVersionControlService = entitiesVersionControlService;
this.scheduler = scheduler;
this.executor = executor;
@ -556,7 +552,7 @@ public class DefaultGitVersionControlQueueService implements GitVersionControlQu
vcSettings = entitiesVersionControlService.getVersionControlSettings(tenantId);
}
if (vcSettings != null) {
builder.setVcSettings(ByteString.copyFrom(encodingService.encode(vcSettings)));
builder.setVcSettings(ProtoUtils.toProto(vcSettings));
} else if (request.requiresSettings()) {
throw new RuntimeException("No entity version control settings provisioned!");
}

4
application/src/main/java/org/thingsboard/server/service/sync/vc/VersionControlTaskRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import java.util.UUID;
@ -31,6 +31,6 @@ import java.util.UUID;
public class VersionControlTaskRedisCache extends RedisTbTransactionalCache<UUID, VersionControlTaskCacheEntry> {
public VersionControlTaskRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.VERSION_CONTROL_TASK_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.VERSION_CONTROL_TASK_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(VersionControlTaskCacheEntry.class));
}
}

4
application/src/main/java/org/thingsboard/server/service/sync/vc/autocommit/AutoCommitSettingsRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.sync.vc.AutoCommitSettings;
@ -31,6 +31,6 @@ import org.thingsboard.server.common.data.sync.vc.AutoCommitSettings;
public class AutoCommitSettingsRedisCache extends RedisTbTransactionalCache<TenantId, AutoCommitSettings> {
public AutoCommitSettingsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.AUTO_COMMIT_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.AUTO_COMMIT_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(AutoCommitSettings.class));
}
}

4
application/src/main/java/org/thingsboard/server/service/sync/vc/repository/RepositorySettingsRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.sync.vc.RepositorySettings;
@ -31,6 +31,6 @@ import org.thingsboard.server.common.data.sync.vc.RepositorySettings;
public class RepositorySettingsRedisCache extends RedisTbTransactionalCache<TenantId, RepositorySettings> {
public RepositorySettingsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.REPOSITORY_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.REPOSITORY_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(RepositorySettings.class));
}
}

76
application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java

@ -47,10 +47,6 @@ import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData;
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.device.profile.ProvisionDeviceProfileCredentials;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
@ -70,6 +66,7 @@ import org.thingsboard.server.common.msg.EncryptionUtil;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.dao.device.DeviceCredentialsService;
import org.thingsboard.server.dao.device.DeviceProfileService;
import org.thingsboard.server.dao.device.DeviceProvisionService;
@ -85,7 +82,6 @@ import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.resource.ResourceService;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.DeviceInfoProto;
import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceCredentialsRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg;
@ -103,12 +99,10 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MC
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
import org.thingsboard.server.service.resource.TbResourceService;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@ -144,7 +138,6 @@ public class DefaultTransportApiService implements TransportApiService {
private final DeviceCredentialsService deviceCredentialsService;
private final DbCallbackExecutorService dbCallbackExecutorService;
private final TbClusterService tbClusterService;
private final DataDecodingEncodingService dataDecodingEncodingService;
private final DeviceProvisionService deviceProvisionService;
private final ResourceService resourceService;
private final OtaPackageService otaPackageService;
@ -390,10 +383,10 @@ public class DefaultTransportApiService implements TransportApiService {
}
}
GetOrCreateDeviceFromGatewayResponseMsg.Builder builder = GetOrCreateDeviceFromGatewayResponseMsg.newBuilder()
.setDeviceInfo(getDeviceInfoProto(device));
.setDeviceInfo(ProtoUtils.toDeviceInfoProto(device));
DeviceProfile deviceProfile = deviceProfileCache.get(device.getTenantId(), device.getDeviceProfileId());
if (deviceProfile != null) {
builder.setProfileBody(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile)));
builder.setDeviceProfile(ProtoUtils.toProto(deviceProfile));
} else {
log.warn("[{}] Failed to find device profile [{}] for device. ", device.getId(), device.getDeviceProfileId());
}
@ -470,13 +463,13 @@ public class DefaultTransportApiService implements TransportApiService {
if (entityType.equals(EntityType.DEVICE_PROFILE)) {
DeviceProfileId deviceProfileId = new DeviceProfileId(entityUuid);
DeviceProfile deviceProfile = deviceProfileCache.find(deviceProfileId);
builder.setData(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile)));
builder.setDeviceProfile(ProtoUtils.toProto(deviceProfile));
} else if (entityType.equals(EntityType.TENANT)) {
TenantId tenantId = TenantId.fromUUID(entityUuid);
TenantProfile tenantProfile = tenantProfileCache.get(tenantId);
ApiUsageState state = apiUsageStateService.getApiUsageState(tenantId);
builder.setData(ByteString.copyFrom(dataDecodingEncodingService.encode(tenantProfile)));
builder.setApiState(ByteString.copyFrom(dataDecodingEncodingService.encode(state)));
builder.setTenantProfile(ProtoUtils.toProto(tenantProfile));
builder.setApiState(ProtoUtils.toProto(state));
} else {
throw new RuntimeException("Invalid entity profile request: " + entityType);
}
@ -495,7 +488,7 @@ public class DefaultTransportApiService implements TransportApiService {
.setDeviceProfileIdMSB(deviceProfileId.getMostSignificantBits())
.setDeviceProfileIdLSB(deviceProfileId.getLeastSignificantBits())
.setDeviceTransportConfiguration(ByteString.copyFrom(
dataDecodingEncodingService.encode(device.getDeviceData().getTransportConfiguration())
JacksonUtil.writeValueAsBytes(device.getDeviceData().getTransportConfiguration())
)))
.build();
} else {
@ -511,11 +504,10 @@ public class DefaultTransportApiService implements TransportApiService {
return Futures.immediateFuture(TransportApiResponseMsg.newBuilder()
.setDeviceCredentialsResponseMsg(TransportProtos.GetDeviceCredentialsResponseMsg.newBuilder()
.setDeviceCredentialsData(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceCredentials))))
.setDeviceCredentialsData(ProtoUtils.toProto(deviceCredentials)))
.build());
}
private ListenableFuture<TransportApiResponseMsg> handle(GetResourceRequestMsg requestMsg) {
TenantId tenantId = TenantId.fromUUID(new UUID(requestMsg.getTenantIdMSB(), requestMsg.getTenantIdLSB()));
ResourceType resourceType = ResourceType.valueOf(requestMsg.getResourceType());
@ -528,7 +520,7 @@ public class DefaultTransportApiService implements TransportApiService {
}
if (resource != null) {
builder.setResource(ByteString.copyFrom(dataDecodingEncodingService.encode(resource)));
builder.setResource(ProtoUtils.toProto(resource));
}
return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setResourceResponseMsg(builder).build());
@ -558,10 +550,10 @@ public class DefaultTransportApiService implements TransportApiService {
}
try {
ValidateDeviceCredentialsResponseMsg.Builder builder = ValidateDeviceCredentialsResponseMsg.newBuilder();
builder.setDeviceInfo(getDeviceInfoProto(device));
builder.setDeviceInfo(ProtoUtils.toDeviceInfoProto(device));
DeviceProfile deviceProfile = deviceProfileCache.get(device.getTenantId(), device.getDeviceProfileId());
if (deviceProfile != null) {
builder.setProfileBody(ByteString.copyFrom(dataDecodingEncodingService.encode(deviceProfile)));
builder.setDeviceProfile(ProtoUtils.toProto(deviceProfile));
} else {
log.warn("[{}] Failed to find device profile [{}] for device. ", device.getId(), device.getDeviceProfileId());
}
@ -576,45 +568,6 @@ public class DefaultTransportApiService implements TransportApiService {
}
}
private DeviceInfoProto getDeviceInfoProto(Device device) throws JsonProcessingException {
DeviceInfoProto.Builder builder = DeviceInfoProto.newBuilder()
.setTenantIdMSB(device.getTenantId().getId().getMostSignificantBits())
.setTenantIdLSB(device.getTenantId().getId().getLeastSignificantBits())
.setCustomerIdMSB(Optional.ofNullable(device.getCustomerId()).map(customerId -> customerId.getId().getMostSignificantBits()).orElse(0L))
.setCustomerIdLSB(Optional.ofNullable(device.getCustomerId()).map(customerId -> customerId.getId().getLeastSignificantBits()).orElse(0L))
.setDeviceIdMSB(device.getId().getId().getMostSignificantBits())
.setDeviceIdLSB(device.getId().getId().getLeastSignificantBits())
.setDeviceName(device.getName())
.setDeviceType(device.getType())
.setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits())
.setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits())
.setAdditionalInfo(JacksonUtil.toString(device.getAdditionalInfo()));
PowerSavingConfiguration psmConfiguration = null;
switch (device.getDeviceData().getTransportConfiguration().getType()) {
case LWM2M:
psmConfiguration = (Lwm2mDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration();
break;
case COAP:
psmConfiguration = (CoapDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration();
break;
}
if (psmConfiguration != null) {
PowerMode powerMode = psmConfiguration.getPowerMode();
if (powerMode != null) {
builder.setPowerMode(powerMode.name());
if (powerMode.equals(PowerMode.PSM)) {
builder.setPsmActivityTimer(checkLong(psmConfiguration.getPsmActivityTimer()));
} else if (powerMode.equals(PowerMode.E_DRX)) {
builder.setEdrxCycle(checkLong(psmConfiguration.getEdrxCycle()));
builder.setPagingTransmissionWindow(checkLong(psmConfiguration.getPagingTransmissionWindow()));
}
}
}
return builder.build();
}
private ListenableFuture<TransportApiResponseMsg> getEmptyTransportApiResponseFuture() {
return Futures.immediateFuture(getEmptyTransportApiResponse());
}
@ -700,7 +653,7 @@ public class DefaultTransportApiService implements TransportApiService {
}
TransportProtos.LwM2MRegistrationResponseMsg registrationResponseMsg =
TransportProtos.LwM2MRegistrationResponseMsg.newBuilder()
.setDeviceInfo(getDeviceInfoProto(device)).build();
.setDeviceInfo(ProtoUtils.toDeviceInfoProto(device)).build();
TransportProtos.LwM2MResponseMsg responseMsg = TransportProtos.LwM2MResponseMsg.newBuilder().setRegistrationMsg(registrationResponseMsg).build();
return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setLwM2MResponseMsg(responseMsg).build());
} catch (JsonProcessingException e) {
@ -729,11 +682,6 @@ public class DefaultTransportApiService implements TransportApiService {
.build()).collect(Collectors.toList())).build());
}
private Long checkLong(Long l) {
return l != null ? l : 0;
}
private ProvisionRequest createProvisionRequest(String certificateValue) {
return new ProvisionRequest(null, DeviceCredentialsType.X509_CERTIFICATE,
new ProvisionDeviceCredentialsData(null, null, null, null, certificateValue),

19
application/src/test/java/org/thingsboard/server/edge/AbstractEdgeTest.java

@ -95,7 +95,6 @@ import org.thingsboard.server.gen.edge.v1.TenantUpdateMsg;
import org.thingsboard.server.gen.edge.v1.UpdateMsgType;
import org.thingsboard.server.gen.edge.v1.UplinkMsg;
import org.thingsboard.server.gen.edge.v1.UserUpdateMsg;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import java.util.ArrayList;
import java.util.List;
@ -124,9 +123,6 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
@Autowired
protected EdgeEventService edgeEventService;
@Autowired
protected DataDecodingEncodingService dataDecodingEncodingService;
@Autowired
protected TbClusterService clusterService;
@ -165,7 +161,8 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
private RuleChainId getEdgeRootRuleChainId() throws Exception {
List<RuleChain> edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/ruleChains?",
new TypeReference<PageData<RuleChain>>() {}, new PageLink(100)).getData();
new TypeReference<PageData<RuleChain>>() {
}, new PageLink(100)).getData();
for (RuleChain edgeRuleChain : edgeRuleChains) {
if (edgeRuleChain.isRoot()) {
return edgeRuleChain.getId();
@ -182,7 +179,8 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
doDelete("/api/edge/" + edge.getId().toString())
.andExpect(status().isOk());
edgeImitator.disconnect();
} catch (Exception ignored) {}
} catch (Exception ignored) {
}
}
private void installation() throws Exception {
@ -379,7 +377,8 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
Device device = doGet("/api/device/" + deviceUUID, Device.class);
Assert.assertNotNull(device);
List<DeviceInfo> edgeDevices = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/devices?",
new TypeReference<PageData<DeviceInfo>>() {}, new PageLink(100)).getData();
new TypeReference<PageData<DeviceInfo>>() {
}, new PageLink(100)).getData();
Assert.assertTrue(edgeDevices.stream().map(DeviceInfo::getId).anyMatch(id -> id.equals(device.getId())));
testAutoGeneratedCodeByProtobuf(deviceUpdateMsg);
@ -398,7 +397,8 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
Asset asset = doGet("/api/asset/" + assetUUID, Asset.class);
Assert.assertNotNull(asset);
List<Asset> edgeAssets = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/assets?",
new TypeReference<PageData<Asset>>() {}, new PageLink(100)).getData();
new TypeReference<PageData<Asset>>() {
}, new PageLink(100)).getData();
Assert.assertTrue(edgeAssets.contains(asset));
testAutoGeneratedCodeByProtobuf(assetUpdateMsg);
@ -418,7 +418,8 @@ abstract public class AbstractEdgeTest extends AbstractControllerTest {
RuleChain ruleChain = doGet("/api/ruleChain/" + ruleChainUUID, RuleChain.class);
Assert.assertNotNull(ruleChain);
List<RuleChain> edgeRuleChains = doGetTypedWithPageLink("/api/edge/" + edge.getUuidId() + "/ruleChains?",
new TypeReference<PageData<RuleChain>>() {}, new PageLink(100)).getData();
new TypeReference<PageData<RuleChain>>() {
}, new PageLink(100)).getData();
Assert.assertTrue(edgeRuleChains.contains(ruleChain));
testAutoGeneratedCodeByProtobuf(ruleChainUpdateMsg);
}

4
application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/BaseEdgeProcessorTest.java

@ -60,7 +60,6 @@ import org.thingsboard.server.dao.widget.WidgetsBundleService;
import org.thingsboard.server.gen.edge.v1.EdgeVersion;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.service.edge.rpc.constructor.alarm.AlarmMsgConstructorFactory;
import org.thingsboard.server.service.edge.rpc.constructor.alarm.AlarmMsgConstructorV1;
import org.thingsboard.server.service.edge.rpc.constructor.alarm.AlarmMsgConstructorV2;
@ -481,9 +480,6 @@ public abstract class BaseEdgeProcessorTest {
@MockBean
protected DbCallbackExecutorService dbCallbackExecutorService;
@MockBean
protected DataDecodingEncodingService dataDecodingEncodingService;
protected EdgeId edgeId;
protected TenantId tenantId;

2
application/src/test/java/org/thingsboard/server/service/edge/rpc/processor/device/AbstractDeviceProcessorTest.java

@ -74,8 +74,6 @@ public abstract class AbstractDeviceProcessorTest extends BaseEdgeProcessorTest
willReturn(device).given(deviceService).findDeviceById(tenantId, deviceId);
willReturn(deviceProfile).given(deviceProfileService).findDeviceProfileById(tenantId, deviceProfileId);
willReturn(new byte[]{0x00}).given(dataDecodingEncodingService).encode(deviceProfileData);
}
protected void updateDeviceProfileDefaultFields(long expectedDashboardIdMSB, long expectedDashboardIdLSB,

5
application/src/test/java/org/thingsboard/server/service/queue/DefaultTbClusterServiceTest.java

@ -32,10 +32,9 @@ import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.TbQueueProducer;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.TopicService;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TopicService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.service.gateway_device.GatewayNotificationsService;
import org.thingsboard.server.service.profile.TbAssetProfileCache;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
@ -64,8 +63,6 @@ public class DefaultTbClusterServiceTest {
public static final String TRANSPORT = "transport";
@MockBean
protected DataDecodingEncodingService encodingService;
@MockBean
protected TbDeviceProfileCache deviceProfileCache;
@MockBean

3
application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java

@ -47,7 +47,6 @@ import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.resource.ResourceService;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
@ -92,8 +91,6 @@ public class DefaultTransportApiServiceTest {
@MockBean
protected TbClusterService tbClusterService;
@MockBean
protected DataDecodingEncodingService dataDecodingEncodingService;
@MockBean
protected DeviceProvisionService deviceProvisionService;
@MockBean
protected ResourceService resourceService;

8
common/cache/pom.xml

@ -40,6 +40,14 @@
<groupId>org.thingsboard.common</groupId>
<artifactId>data</artifactId>
</dependency>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>util</artifactId>
</dependency>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>proto</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>

16
common/cache/src/main/java/org/thingsboard/server/cache/TbJavaRedisSerializer.java → common/cache/src/main/java/org/thingsboard/server/cache/TbJsonRedisSerializer.java

@ -16,17 +16,23 @@
package org.thingsboard.server.cache;
import org.springframework.data.redis.serializer.SerializationException;
import org.thingsboard.server.common.data.JavaSerDesUtil;
import org.thingsboard.common.util.JacksonUtil;
public class TbJavaRedisSerializer<K, V> implements TbRedisSerializer<K, V> {
public class TbJsonRedisSerializer<K, V> implements TbRedisSerializer<K, V> {
private final Class<V> clazz;
public TbJsonRedisSerializer(Class<V> clazz) {
this.clazz = clazz;
}
@Override
public byte[] serialize(V value) throws SerializationException {
return JavaSerDesUtil.encode(value);
public byte[] serialize(V v) throws SerializationException {
return JacksonUtil.writeValueAsBytes(v);
}
@Override
public V deserialize(K key, byte[] bytes) throws SerializationException {
return JavaSerDesUtil.decode(bytes);
return JacksonUtil.fromBytes(bytes, clazz);
}
}

39
common/cache/src/main/java/org/thingsboard/server/cache/TbTypedJsonRedisSerializer.java

@ -0,0 +1,39 @@
/**
* Copyright © 2016-2023 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.cache;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.data.redis.serializer.SerializationException;
import org.thingsboard.common.util.JacksonUtil;
public class TbTypedJsonRedisSerializer<K, V> implements TbRedisSerializer<K, V> {
private final TypeReference<V> valueTypeRef;
public TbTypedJsonRedisSerializer(TypeReference<V> valueTypeRef) {
this.valueTypeRef = valueTypeRef;
}
@Override
public byte[] serialize(V v) throws SerializationException {
return JacksonUtil.writeValueAsBytes(v);
}
@Override
public V deserialize(K key, byte[] bytes) throws SerializationException {
return JacksonUtil.fromBytes(bytes, valueTypeRef);
}
}

23
common/cache/src/main/java/org/thingsboard/server/cache/device/DeviceRedisCache.java

@ -15,21 +15,40 @@
*/
package org.thingsboard.server.cache.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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.gen.transport.TransportProtos;
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis")
@Service("DeviceCache")
public class DeviceRedisCache extends RedisTbTransactionalCache<DeviceCacheKey, Device> {
public DeviceRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.DEVICE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.DEVICE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbRedisSerializer<>() {
@Override
public byte[] serialize(Device device) throws SerializationException {
return ProtoUtils.toProto(device).toByteArray();
}
@Override
public Device deserialize(DeviceCacheKey key, byte[] bytes) throws SerializationException {
try {
return ProtoUtils.fromProto(TransportProtos.DeviceProto.parseFrom(bytes));
} catch (InvalidProtocolBufferException e) {
throw new SerializationException(e.getMessage());
}
}
});
}
}

4
common/cache/src/main/java/org/thingsboard/server/cache/resourceInfo/ResourceInfoRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.TbResourceInfo;
@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.TbResourceInfo;
public class ResourceInfoRedisCache extends RedisTbTransactionalCache<ResourceInfoCacheKey, TbResourceInfo> {
public ResourceInfoRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.RESOURCE_INFO_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.RESOURCE_INFO_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(TbResourceInfo.class));
}
}

4
common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersSessionInvalidationRedisCache.java

@ -22,7 +22,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis")
@ -31,6 +31,6 @@ public class UsersSessionInvalidationRedisCache extends RedisTbTransactionalCach
@Autowired
public UsersSessionInvalidationRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.USERS_SESSION_INVALIDATION_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.USERS_SESSION_INVALIDATION_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(Long.class));
}
}

1
common/data/src/main/java/org/thingsboard/server/common/data/Device.java

@ -57,6 +57,7 @@ public class Device extends BaseDataWithAdditionalInfo<DeviceId> implements HasL
private DeviceProfileId deviceProfileId;
private transient DeviceData deviceData;
@JsonIgnore
@Getter @Setter
private byte[] deviceDataBytes;
private OtaPackageId firmwareId;

4
common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java

@ -20,6 +20,8 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import io.swagger.v3.oas.annotations.media.Schema;
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;
@ -77,6 +79,8 @@ public class DeviceProfile extends BaseData<DeviceProfileId> implements HasName,
@Valid
private transient DeviceProfileData profileData;
@JsonIgnore
@Getter
@Setter
private byte[] profileDataBytes;
@NoXss
@Schema(description = "Unique provisioning key used by 'Device Provisioning' feature.")

10
common/proto/pom.xml

@ -44,6 +44,10 @@
<groupId>org.thingsboard.common</groupId>
<artifactId>message</artifactId>
</dependency>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>util</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
@ -72,6 +76,12 @@
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-random-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

583
common/proto/src/main/java/org/thingsboard/server/common/util/ProtoUtils.java

@ -15,11 +15,40 @@
*/
package org.thingsboard.server.common.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.ApiUsageStateValue;
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.ResourceType;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
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.ApiUsageStateId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.DeviceCredentialsId;
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.TbResourceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.kv.AttributeKey;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
@ -34,6 +63,8 @@ import org.thingsboard.server.common.data.rpc.RpcError;
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.data.sync.vc.RepositoryAuthMethod;
import org.thingsboard.server.common.data.sync.vc.RepositorySettings;
import org.thingsboard.server.common.msg.ToDeviceActorNotificationMsg;
import org.thingsboard.server.common.msg.edge.EdgeEventUpdateMsg;
import org.thingsboard.server.common.msg.edge.FromEdgeSyncResponse;
@ -56,8 +87,10 @@ 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;
@Slf4j
public class ProtoUtils {
private static final EntityType[] entityTypeByProtoNumber;
@ -496,4 +529,554 @@ public class ProtoUtils {
}
return result;
}
public static TransportProtos.DeviceProto toProto(Device device) {
var builder = TransportProtos.DeviceProto.newBuilder()
.setTenantIdMSB(device.getTenantId().getId().getMostSignificantBits())
.setTenantIdLSB(device.getTenantId().getId().getLeastSignificantBits())
.setDeviceIdMSB(device.getId().getId().getMostSignificantBits())
.setDeviceIdLSB(device.getId().getId().getLeastSignificantBits())
.setCreatedTime(device.getCreatedTime())
.setDeviceName(device.getName())
.setDeviceType(device.getType())
.setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits())
.setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits());
if (isNotNull(device.getCustomerId())) {
builder.setCustomerIdMSB(getMsb(device.getCustomerId()))
.setCustomerIdLSB(getLsb(device.getCustomerId()));
}
if (isNotNull(device.getLabel())) {
builder.setDeviceLabel(device.getLabel());
}
if (isNotNull(device.getAdditionalInfo())) {
builder.setAdditionalInfo(JacksonUtil.toString(device.getAdditionalInfo()));
}
if (isNotNull(device.getFirmwareId())) {
builder.setFirmwareIdMSB(getMsb(device.getFirmwareId()))
.setFirmwareIdLSB(getLsb(device.getFirmwareId()));
}
if (isNotNull(device.getSoftwareId())) {
builder.setSoftwareIdMSB(getMsb(device.getSoftwareId()))
.setSoftwareIdLSB(getLsb(device.getSoftwareId()));
}
if (isNotNull(device.getExternalId())) {
builder.setExternalIdMSB(getMsb(device.getExternalId()))
.setExternalIdLSB(getLsb(device.getExternalId()));
}
if (isNotNull(device.getDeviceDataBytes())) {
builder.setDeviceData(ByteString.copyFrom(device.getDeviceDataBytes()));
}
return builder.build();
}
public static Device fromProto(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.setName(proto.getDeviceName());
device.setType(proto.getDeviceType());
device.setDeviceProfileId(getEntityId(proto.getDeviceProfileIdMSB(), proto.getDeviceProfileIdLSB(), DeviceProfileId::new));
if (proto.hasCustomerIdMSB() && proto.hasCustomerIdLSB()) {
device.setCustomerId(getEntityId(proto.getCustomerIdMSB(), proto.getCustomerIdLSB(), CustomerId::new));
}
if (proto.hasDeviceLabel()) {
device.setLabel(proto.getDeviceLabel());
}
if (proto.hasAdditionalInfo()) {
device.setAdditionalInfo(JacksonUtil.toJsonNode(proto.getAdditionalInfo()));
}
if (proto.hasFirmwareIdMSB() && proto.hasFirmwareIdLSB()) {
device.setFirmwareId(getEntityId(proto.getFirmwareIdMSB(), proto.getFirmwareIdLSB(), OtaPackageId::new));
}
if (proto.hasSoftwareIdMSB() && proto.hasSoftwareIdLSB()) {
device.setSoftwareId(getEntityId(proto.getSoftwareIdMSB(), proto.getSoftwareIdLSB(), OtaPackageId::new));
}
if (proto.hasExternalIdMSB() && proto.hasExternalIdLSB()) {
device.setExternalId(getEntityId(proto.getExternalIdMSB(), proto.getExternalIdLSB(), DeviceId::new));
}
if (proto.hasDeviceData()) {
device.setDeviceDataBytes(proto.getDeviceData().toByteArray());
}
return device;
}
public static TransportProtos.DeviceProfileProto toProto(DeviceProfile deviceProfile) {
var builder = 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());
if (isNotNull(deviceProfile.getProfileDataBytes())) {
builder.setDeviceProfileData(ByteString.copyFrom(deviceProfile.getProfileDataBytes()));
}
if (isNotNull(deviceProfile.getDescription())) {
builder.setDescription(deviceProfile.getDescription());
}
if (isNotNull(deviceProfile.getImage())) {
builder.setImage(deviceProfile.getImage());
}
if (isNotNull(deviceProfile.getDefaultRuleChainId())) {
builder.setDefaultRuleChainIdMSB(getMsb(deviceProfile.getDefaultRuleChainId()))
.setDefaultRuleChainIdLSB(getLsb(deviceProfile.getDefaultRuleChainId()));
}
if (isNotNull(deviceProfile.getDefaultDashboardId())) {
builder.setDefaultDashboardIdMSB(getMsb(deviceProfile.getDefaultDashboardId()))
.setDefaultDashboardIdLSB(getLsb(deviceProfile.getDefaultDashboardId()));
}
if (isNotNull(deviceProfile.getDefaultQueueName())) {
builder.setDefaultQueueName(deviceProfile.getDefaultQueueName());
}
if (isNotNull(deviceProfile.getProvisionDeviceKey())) {
builder.setProvisionDeviceKey(deviceProfile.getProvisionDeviceKey());
}
if (isNotNull(deviceProfile.getFirmwareId())) {
builder.setFirmwareIdMSB(getMsb(deviceProfile.getFirmwareId()))
.setFirmwareIdLSB(getLsb(deviceProfile.getFirmwareId()));
}
if (isNotNull(deviceProfile.getSoftwareId())) {
builder.setSoftwareIdMSB(getMsb(deviceProfile.getSoftwareId()))
.setSoftwareIdLSB(getLsb(deviceProfile.getSoftwareId()));
}
if (isNotNull(deviceProfile.getExternalId())) {
builder.setExternalIdMSB(getMsb(deviceProfile.getExternalId()))
.setExternalIdLSB(getLsb(deviceProfile.getExternalId()));
}
if (isNotNull(deviceProfile.getDefaultEdgeRuleChainId())) {
builder.setDefaultEdgeRuleChainIdMSB(getMsb(deviceProfile.getDefaultEdgeRuleChainId()))
.setDefaultEdgeRuleChainIdLSB(getLsb(deviceProfile.getDefaultEdgeRuleChainId()));
}
return builder.build();
}
public static DeviceProfile fromProto(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()));
if (proto.hasDeviceProfileData()) {
deviceProfile.setProfileDataBytes(proto.getDeviceProfileData().toByteArray());
}
if (proto.hasDescription()) {
deviceProfile.setDescription(proto.getDescription());
}
if (proto.hasImage()) {
deviceProfile.setImage(proto.getImage());
}
if (proto.hasDefaultRuleChainIdMSB() && proto.hasDefaultRuleChainIdLSB()) {
deviceProfile.setDefaultRuleChainId(getEntityId(proto.getDefaultRuleChainIdMSB(), proto.getDefaultRuleChainIdLSB(), RuleChainId::new));
deviceProfile.setDefaultDashboardId(getEntityId(proto.getDefaultDashboardIdMSB(), proto.getDefaultDashboardIdLSB(), DashboardId::new));
}
if (proto.hasDefaultQueueName()) {
deviceProfile.setDefaultQueueName(proto.getDefaultQueueName());
}
if (proto.hasProvisionDeviceKey()) {
deviceProfile.setProvisionDeviceKey(proto.getProvisionDeviceKey());
}
if (proto.hasFirmwareIdMSB() && proto.hasFirmwareIdLSB()) {
deviceProfile.setFirmwareId(getEntityId(proto.getFirmwareIdMSB(), proto.getFirmwareIdLSB(), OtaPackageId::new));
}
if (proto.hasSoftwareIdMSB() && proto.hasSoftwareIdLSB()) {
deviceProfile.setSoftwareId(getEntityId(proto.getSoftwareIdMSB(), proto.getSoftwareIdLSB(), OtaPackageId::new));
}
if (proto.hasExternalIdMSB() && proto.hasExternalIdLSB()) {
deviceProfile.setExternalId(getEntityId(proto.getExternalIdMSB(), proto.getExternalIdLSB(), DeviceProfileId::new));
}
if (proto.hasDefaultEdgeRuleChainIdMSB() && proto.hasDefaultEdgeRuleChainIdLSB()) {
deviceProfile.setDefaultEdgeRuleChainId(getEntityId(proto.getDefaultEdgeRuleChainIdMSB(), proto.getDefaultEdgeRuleChainIdLSB(), RuleChainId::new));
}
return deviceProfile;
}
public static TransportProtos.TenantProto toProto(Tenant tenant) {
var builder = TransportProtos.TenantProto.newBuilder()
.setTenantIdMSB(getMsb(tenant.getTenantId()))
.setTenantIdLSB(getLsb(tenant.getTenantId()))
.setCreatedTime(tenant.getCreatedTime())
.setTenantProfileIdMSB(getMsb(tenant.getTenantProfileId()))
.setTenantProfileIdLSB(getLsb(tenant.getTenantProfileId()))
.setTitle(tenant.getTitle());
if (isNotNull(tenant.getRegion())) {
builder.setRegion(tenant.getRegion());
}
if (isNotNull(tenant.getCountry())) {
builder.setCountry(tenant.getCountry());
}
if (isNotNull(tenant.getState())) {
builder.setState(tenant.getState());
}
if (isNotNull(tenant.getCity())) {
builder.setCity(tenant.getCity());
}
if (isNotNull(tenant.getAddress())) {
builder.setAddress(tenant.getAddress());
}
if (isNotNull(tenant.getAddress2())) {
builder.setAddress2(tenant.getAddress2());
}
if (isNotNull(tenant.getZip())) {
builder.setZip(tenant.getZip());
}
if (isNotNull(tenant.getPhone())) {
builder.setPhone(tenant.getPhone());
}
if (isNotNull(tenant.getEmail())) {
builder.setEmail(tenant.getEmail());
}
if (isNotNull(tenant.getAdditionalInfo())) {
builder.setAdditionalInfo(JacksonUtil.toString(tenant.getAdditionalInfo()));
}
return builder.build();
}
public static Tenant fromProto(TransportProtos.TenantProto proto) {
Tenant tenant = new Tenant(getEntityId(proto.getTenantIdMSB(), proto.getTenantIdLSB(), TenantId::new));
tenant.setCreatedTime(proto.getCreatedTime());
tenant.setTenantProfileId(getEntityId(proto.getTenantProfileIdMSB(), proto.getTenantProfileIdLSB(), TenantProfileId::new));
tenant.setTitle(proto.getTitle());
if (proto.hasRegion()) {
tenant.setRegion(proto.getRegion());
}
if (proto.hasCountry()) {
tenant.setCountry(proto.getCountry());
}
if (proto.hasState()) {
tenant.setState(proto.getState());
}
if (proto.hasCity()) {
tenant.setCity(proto.getCity());
}
if (proto.hasAddress()) {
tenant.setAddress(proto.getAddress());
}
if (proto.hasAddress2()) {
tenant.setAddress2(proto.getAddress2());
}
if (proto.hasZip()) {
tenant.setZip(proto.getZip());
}
if (proto.hasPhone()) {
tenant.setPhone(proto.getPhone());
}
if (proto.hasEmail()) {
tenant.setEmail(proto.getEmail());
}
if (proto.hasAdditionalInfo()) {
tenant.setAdditionalInfo(JacksonUtil.toJsonNode(proto.getAdditionalInfo()));
}
return tenant;
}
public static TransportProtos.TenantProfileProto toProto(TenantProfile tenantProfile) {
var builder = TransportProtos.TenantProfileProto.newBuilder()
.setTenantProfileIdMSB(getMsb(tenantProfile.getId()))
.setTenantProfileIdLSB(getLsb(tenantProfile.getId()))
.setCreatedTime(tenantProfile.getCreatedTime())
.setName(tenantProfile.getName())
.setIsDefault(tenantProfile.isDefault())
.setIsolatedTbRuleEngine(tenantProfile.isIsolatedTbRuleEngine());
if (isNotNull(tenantProfile.getDescription())) {
builder.setDescription(tenantProfile.getDescription());
}
if (isNotNull(tenantProfile.getProfileDataBytes())) {
builder.setProfileData(ByteString.copyFrom(tenantProfile.getProfileDataBytes()));
}
return builder.build();
}
public static TenantProfile fromProto(TransportProtos.TenantProfileProto proto) {
TenantProfile tenantProfile = new TenantProfile(getEntityId(proto.getTenantProfileIdMSB(), proto.getTenantProfileIdLSB(), TenantProfileId::new));
tenantProfile.setCreatedTime(proto.getCreatedTime());
tenantProfile.setName(proto.getName());
tenantProfile.setDefault(proto.getIsDefault());
tenantProfile.setIsolatedTbRuleEngine(proto.getIsolatedTbRuleEngine());
if (proto.hasDescription()) {
tenantProfile.setDescription(proto.getDescription());
}
if (proto.hasProfileData()) {
tenantProfile.setProfileDataBytes(proto.getProfileData().toByteArray());
}
return tenantProfile;
}
public static TransportProtos.TbResourceProto toProto(TbResource resource) {
var builder = TransportProtos.TbResourceProto.newBuilder()
.setTenantIdMSB(getMsb(resource.getTenantId()))
.setTenantIdLSB(getLsb(resource.getTenantId()))
.setResourceIdMSB(getMsb(resource.getId()))
.setResourceIdLSB(getLsb(resource.getId()))
.setCreatedTime(resource.getCreatedTime())
.setTitle(resource.getTitle())
.setResourceType(resource.getResourceType().name())
.setResourceKey(resource.getResourceKey())
.setIsPublic(resource.isPublic())
.setSearchText(resource.getSearchText())
.setFileName(resource.getFileName());
if (isNotNull(resource.getPublicResourceKey())) {
builder.setPublicResourceKey(resource.getPublicResourceKey());
}
if (isNotNull(resource.getEtag())) {
builder.setEtag(resource.getEtag());
}
if (isNotNull(resource.getDescriptor())) {
builder.setResourceDescriptor(JacksonUtil.toString(resource.getDescriptor()));
}
if (isNotNull(resource.getExternalId())) {
builder.setExternalIdMSB(getMsb(resource.getExternalId()))
.setExternalIdLSB(getLsb(resource.getExternalId()));
}
if (isNotNull(resource.getData())) {
builder.setData(ByteString.copyFrom(resource.getData()));
}
if (isNotNull(resource.getPreview())) {
builder.setPreview(ByteString.copyFrom(resource.getPreview()));
}
return builder.build();
}
public static TbResource fromProto(TransportProtos.TbResourceProto proto) {
TbResource resource = new TbResource(getEntityId(proto.getResourceIdMSB(), proto.getResourceIdLSB(), TbResourceId::new));
resource.setTenantId(getEntityId(proto.getTenantIdMSB(), proto.getTenantIdLSB(), TenantId::new));
resource.setCreatedTime(proto.getCreatedTime());
resource.setTitle(proto.getTitle());
resource.setResourceType(ResourceType.valueOf(proto.getResourceType()));
resource.setResourceKey(proto.getResourceKey());
resource.setPublic(proto.getIsPublic());
resource.setSearchText(proto.getSearchText());
resource.setFileName(proto.getFileName());
if (proto.hasPublicResourceKey()) {
resource.setPublicResourceKey(proto.getPublicResourceKey());
}
if (proto.hasEtag()) {
resource.setEtag(proto.getEtag());
}
if (proto.hasResourceDescriptor()) {
resource.setDescriptor(JacksonUtil.toJsonNode(proto.getResourceDescriptor()));
}
if (proto.hasExternalIdMSB() && proto.hasExternalIdLSB()) {
resource.setExternalId(getEntityId(proto.getExternalIdMSB(), proto.getExternalIdLSB(), TbResourceId::new));
}
if (proto.hasData()) {
resource.setData(proto.getData().toByteArray());
}
if (proto.hasPreview()) {
resource.setPreview(proto.getPreview().toByteArray());
}
return resource;
}
public static TransportProtos.ApiUsageStateProto toProto(ApiUsageState apiUsageState) {
return TransportProtos.ApiUsageStateProto.newBuilder()
.setTenantProfileIdMSB(getMsb(apiUsageState.getTenantId()))
.setTenantProfileIdLSB(getLsb(apiUsageState.getTenantId()))
.setApiUsageStateIdMSB(getMsb(apiUsageState.getId()))
.setApiUsageStateIdLSB(getLsb(apiUsageState.getId()))
.setCreatedTime(apiUsageState.getCreatedTime())
.setEntityType(toProto(apiUsageState.getEntityId().getEntityType()))
.setEntityIdMSB(getMsb(apiUsageState.getEntityId()))
.setEntityIdLSB(getLsb(apiUsageState.getEntityId()))
.setTransportState(apiUsageState.getTransportState().name())
.setDbStorageState(apiUsageState.getDbStorageState().name())
.setReExecState(apiUsageState.getReExecState().name())
.setJsExecState(apiUsageState.getJsExecState().name())
.setTbelExecState(apiUsageState.getTbelExecState().name())
.setEmailExecState(apiUsageState.getEmailExecState().name())
.setSmsExecState(apiUsageState.getSmsExecState().name())
.setAlarmExecState(apiUsageState.getAlarmExecState().name()).build();
}
public static ApiUsageState fromProto(TransportProtos.ApiUsageStateProto proto) {
ApiUsageState apiUsageState = new ApiUsageState(getEntityId(proto.getApiUsageStateIdMSB(), proto.getApiUsageStateIdLSB(), ApiUsageStateId::new));
apiUsageState.setTenantId(getEntityId(proto.getTenantProfileIdMSB(), proto.getTenantProfileIdLSB(), TenantId::new));
apiUsageState.setCreatedTime(proto.getCreatedTime());
apiUsageState.setEntityId(EntityIdFactory.getByTypeAndUuid(fromProto(proto.getEntityType()), new UUID(proto.getEntityIdMSB(), proto.getEntityIdLSB())));
apiUsageState.setTransportState(ApiUsageStateValue.valueOf(proto.getTransportState()));
apiUsageState.setDbStorageState(ApiUsageStateValue.valueOf(proto.getDbStorageState()));
apiUsageState.setReExecState(ApiUsageStateValue.valueOf(proto.getReExecState()));
apiUsageState.setJsExecState(ApiUsageStateValue.valueOf(proto.getJsExecState()));
apiUsageState.setTbelExecState(ApiUsageStateValue.valueOf(proto.getTbelExecState()));
apiUsageState.setEmailExecState(ApiUsageStateValue.valueOf(proto.getEmailExecState()));
apiUsageState.setSmsExecState(ApiUsageStateValue.valueOf(proto.getSmsExecState()));
apiUsageState.setAlarmExecState(ApiUsageStateValue.valueOf(proto.getAlarmExecState()));
return apiUsageState;
}
public static TransportProtos.RepositorySettingsProto toProto(RepositorySettings repositorySettings) {
var builder = TransportProtos.RepositorySettingsProto.newBuilder()
.setRepositoryUri(repositorySettings.getRepositoryUri())
.setAuthMethod(repositorySettings.getAuthMethod().name())
.setReadOnly(repositorySettings.isReadOnly())
.setShowMergeCommits(repositorySettings.isShowMergeCommits());
if (isNotNull(repositorySettings.getUsername())) {
builder.setUsername(repositorySettings.getUsername());
}
if (isNotNull(repositorySettings.getPassword())) {
builder.setPassword(repositorySettings.getPassword());
}
if (isNotNull(repositorySettings.getPrivateKeyFileName())) {
builder.setPrivateKeyFileName(repositorySettings.getPrivateKeyFileName());
}
if (isNotNull(repositorySettings.getPrivateKey())) {
builder.setPrivateKey(repositorySettings.getPrivateKey());
}
if (isNotNull(repositorySettings.getPrivateKeyPassword())) {
builder.setPrivateKeyPassword(repositorySettings.getPrivateKeyPassword());
}
if (isNotNull(repositorySettings.getDefaultBranch())) {
builder.setDefaultBranch(repositorySettings.getDefaultBranch());
}
return builder.build();
}
public static RepositorySettings fromProto(TransportProtos.RepositorySettingsProto proto) {
RepositorySettings repositorySettings = new RepositorySettings();
repositorySettings.setRepositoryUri(proto.getRepositoryUri());
repositorySettings.setAuthMethod(RepositoryAuthMethod.valueOf(proto.getAuthMethod()));
repositorySettings.setReadOnly(proto.getReadOnly());
repositorySettings.setShowMergeCommits(proto.getShowMergeCommits());
if (proto.hasUsername()) {
repositorySettings.setUsername(proto.getUsername());
}
if (proto.hasPassword()) {
repositorySettings.setPassword(proto.getPassword());
}
if (proto.hasPrivateKeyFileName()) {
repositorySettings.setPrivateKeyFileName(proto.getPrivateKeyFileName());
}
if (proto.hasPrivateKey()) {
repositorySettings.setPrivateKey(proto.getPrivateKey());
}
if (proto.hasPrivateKeyPassword()) {
repositorySettings.setPrivateKeyPassword(proto.getPrivateKeyPassword());
}
if (proto.hasDefaultBranch()) {
repositorySettings.setDefaultBranch(proto.getDefaultBranch());
}
return repositorySettings;
}
public static TransportProtos.DeviceCredentialsProto toProto(DeviceCredentials deviceCredentials) {
TransportProtos.DeviceCredentialsProto.Builder builder = TransportProtos.DeviceCredentialsProto.newBuilder()
.setCredentialsIdMSB(deviceCredentials.getId().getId().getMostSignificantBits())
.setCredentialsIdLSB(deviceCredentials.getId().getId().getLeastSignificantBits())
.setCreatedTime(deviceCredentials.getCreatedTime())
.setDeviceIdMSB(getMsb(deviceCredentials.getDeviceId()))
.setDeviceIdLSB(getLsb(deviceCredentials.getDeviceId()))
.setCredentialsId(deviceCredentials.getCredentialsId())
.setCredentialsType(TransportProtos.CredentialsType.valueOf(deviceCredentials.getCredentialsType().name()));
if (deviceCredentials.getCredentialsValue() != null) {
builder.setCredentialsValue(deviceCredentials.getCredentialsValue());
}
return builder.build();
}
public static DeviceCredentials fromProto(TransportProtos.DeviceCredentialsProto proto) {
DeviceCredentials deviceCredentials =
new DeviceCredentials(new DeviceCredentialsId(new UUID(proto.getCredentialsIdMSB(), proto.getCredentialsIdLSB())));
deviceCredentials.setCreatedTime(proto.getCreatedTime());
deviceCredentials.setDeviceId(getEntityId(proto.getDeviceIdMSB(), proto.getDeviceIdLSB(), DeviceId::new));
deviceCredentials.setCredentialsId(proto.getCredentialsId());
deviceCredentials.setCredentialsType(DeviceCredentialsType.valueOf(proto.getCredentialsType().name()));
deviceCredentials.setCredentialsValue(proto.hasCredentialsValue() ? proto.getCredentialsValue() : null);
return deviceCredentials;
}
public static <T> TransportProtos.EntityUpdateMsg toEntityUpdateProto(T entity) {
var builder = TransportProtos.EntityUpdateMsg.newBuilder();
if (entity instanceof Device) {
builder.setDevice(toProto((Device) entity));
} else if (entity instanceof DeviceProfile) {
builder.setDeviceProfile(toProto((DeviceProfile) entity));
} else if (entity instanceof Tenant) {
builder.setTenant(toProto((Tenant) entity));
} else if (entity instanceof TenantProfile) {
builder.setTenantProfile(toProto((TenantProfile) entity));
} else if (entity instanceof ApiUsageState) {
builder.setApiUsageState(toProto((ApiUsageState) entity));
} else {
log.warn("[{}] entity does not support toProto serialization .", entity.getClass().getSimpleName());
}
return builder.build();
}
public static TransportProtos.DeviceInfoProto toDeviceInfoProto(Device device) throws JsonProcessingException {
TransportProtos.DeviceInfoProto.Builder builder = TransportProtos.DeviceInfoProto.newBuilder()
.setTenantIdMSB(device.getTenantId().getId().getMostSignificantBits())
.setTenantIdLSB(device.getTenantId().getId().getLeastSignificantBits())
.setCustomerIdMSB(getMsb(device.getCustomerId()))
.setCustomerIdLSB(getLsb(device.getCustomerId()))
.setDeviceIdMSB(device.getId().getId().getMostSignificantBits())
.setDeviceIdLSB(device.getId().getId().getLeastSignificantBits())
.setDeviceName(device.getName())
.setDeviceType(device.getType())
.setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits())
.setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits())
.setAdditionalInfo(JacksonUtil.toString(device.getAdditionalInfo()));
PowerSavingConfiguration psmConfiguration = null;
switch (device.getDeviceData().getTransportConfiguration().getType()) {
case LWM2M:
psmConfiguration = (Lwm2mDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration();
break;
case COAP:
psmConfiguration = (CoapDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration();
break;
}
if (psmConfiguration != null) {
PowerMode powerMode = psmConfiguration.getPowerMode();
if (powerMode != null) {
builder.setPowerMode(powerMode.name());
if (powerMode.equals(PowerMode.PSM)) {
builder.setPsmActivityTimer(checkLong(psmConfiguration.getPsmActivityTimer()));
} else if (powerMode.equals(PowerMode.E_DRX)) {
builder.setEdrxCycle(checkLong(psmConfiguration.getEdrxCycle()));
builder.setPagingTransmissionWindow(checkLong(psmConfiguration.getPagingTransmissionWindow()));
}
}
}
return builder.build();
}
private static boolean isNotNull(Object obj) {
return obj != null;
}
private static <T extends EntityId> T getEntityId(long msb, long lsb, Function<UUID, T> entityId) {
return entityId.apply(new UUID(msb, lsb));
}
private static Long getMsb(EntityId entityId) {
if (isNotNull(entityId)) {
return entityId.getId().getMostSignificantBits();
}
return 0L;
}
private static Long getLsb(EntityId entityId) {
if (isNotNull(entityId)) {
return entityId.getId().getLeastSignificantBits();
}
return 0L;
}
private static Long checkLong(Long l) {
return isNotNull(l) ? l : 0;
}
}

203
common/proto/src/main/proto/queue.proto

@ -183,6 +183,142 @@ message DeviceInfoProto {
int64 pagingTransmissionWindow = 15;
}
message DeviceProto {
int64 tenantIdMSB = 1;
int64 tenantIdLSB = 2;
int64 deviceIdMSB = 3;
int64 deviceIdLSB = 4;
int64 createdTime = 5;
string deviceName = 6;
optional string deviceLabel = 7;
string deviceType = 8;
optional string additionalInfo = 9;
int64 deviceProfileIdMSB = 10;
int64 deviceProfileIdLSB = 11;
optional int64 customerIdMSB = 12;
optional int64 customerIdLSB = 13;
optional bytes deviceData = 14;
optional int64 firmwareIdMSB = 15;
optional int64 firmwareIdLSB = 16;
optional int64 softwareIdMSB = 17;
optional int64 softwareIdLSB = 18;
optional int64 externalIdMSB = 19;
optional int64 externalIdLSB = 20;
}
message DeviceProfileProto {
int64 tenantIdMSB = 1;
int64 tenantIdLSB = 2;
int64 deviceProfileIdMSB = 3;
int64 deviceProfileIdLSB = 4;
int64 createdTime = 5;
string name = 6;
optional string description = 7;
optional string image = 8;
bool isDefault = 9;
string type = 10;
string transportType = 11;
string provisionType = 12;
optional int64 defaultRuleChainIdMSB = 13;
optional int64 defaultRuleChainIdLSB = 14;
optional int64 defaultDashboardIdMSB = 15;
optional int64 defaultDashboardIdLSB = 16;
optional string defaultQueueName = 17;
optional bytes deviceProfileData = 18;
optional string provisionDeviceKey = 19;
optional int64 firmwareIdMSB = 20;
optional int64 firmwareIdLSB = 21;
optional int64 softwareIdMSB = 22;
optional int64 softwareIdLSB = 23;
optional int64 defaultEdgeRuleChainIdMSB = 24;
optional int64 defaultEdgeRuleChainIdLSB = 25;
optional int64 externalIdMSB = 26;
optional int64 externalIdLSB = 27;
}
message TenantProto {
int64 tenantIdMSB = 1;
int64 tenantIdLSB = 2;
int64 createdTime = 3;
string title = 4;
optional string region = 5;
int64 tenantProfileIdMSB = 6;
int64 tenantProfileIdLSB = 7;
optional string country = 8;
optional string state = 9;
optional string city = 10;
optional string address = 11;
optional string address2 = 12;
optional string zip = 13;
optional string phone = 14;
optional string email = 15;
optional string additionalInfo = 16;
}
message TenantProfileProto {
int64 tenantProfileIdMSB = 1;
int64 tenantProfileIdLSB = 2;
int64 createdTime = 3;
string name = 4;
optional string description = 5;
bool isDefault = 6;
bool isolatedTbRuleEngine = 7;
optional bytes profileData = 8;
}
message TbResourceProto {
int64 tenantIdMSB = 1;
int64 tenantIdLSB = 2;
int64 resourceIdMSB = 3;
int64 resourceIdLSB = 4;
int64 createdTime = 5;
string title = 6;
string resourceType = 7;
string resourceKey = 8;
bool isPublic = 9;
optional string publicResourceKey = 10;
string searchText = 11;
optional string etag = 12;
string fileName = 13;
optional string resourceDescriptor = 14;
optional int64 externalIdMSB = 15;
optional int64 externalIdLSB = 16;
optional bytes data = 17;
optional bytes preview = 18;
}
message ApiUsageStateProto {
int64 tenantProfileIdMSB = 1;
int64 tenantProfileIdLSB = 2;
int64 apiUsageStateIdMSB = 3;
int64 apiUsageStateIdLSB = 4;
int64 createdTime = 5;
EntityTypeProto entityType = 6;
int64 entityIdMSB = 7;
int64 entityIdLSB = 8;
string transportState = 9;
string dbStorageState = 10;
string reExecState = 11;
string jsExecState = 12;
string tbelExecState = 13;
string emailExecState = 14;
string smsExecState = 15;
string alarmExecState = 16;
}
message RepositorySettingsProto {
string repositoryUri = 1;
string authMethod = 2;
optional string username = 3;
optional string password = 4;
optional string privateKeyFileName = 5;
optional string privateKey = 6;
optional string privateKeyPassword = 7;
optional string defaultBranch = 8;
bool readOnly = 9;
bool showMergeCommits = 10;
}
/**
* Transport Service Messages;
*/
@ -242,7 +378,7 @@ message ValidateBasicMqttCredRequestMsg {
message ValidateDeviceCredentialsResponseMsg {
DeviceInfoProto deviceInfo = 1;
string credentialsBody = 2;
bytes profileBody = 3;
DeviceProfileProto deviceProfile = 3;
}
message GetOrCreateDeviceFromGatewayRequestMsg {
@ -254,7 +390,7 @@ message GetOrCreateDeviceFromGatewayRequestMsg {
message GetOrCreateDeviceFromGatewayResponseMsg {
DeviceInfoProto deviceInfo = 1;
bytes profileBody = 2;
DeviceProfileProto deviceProfile = 2;
TransportApiRequestErrorCode error = 3;
}
@ -342,7 +478,7 @@ message GetResourceRequestMsg {
}
message GetResourceResponseMsg {
bytes resource = 1;
TbResourceProto resource = 1;
}
message ValidateDeviceLwM2MCredentialsRequestMsg {
@ -370,8 +506,11 @@ message GetDeviceProfileRequestMsg {
message GetEntityProfileResponseMsg {
string entityType = 1;
bytes data = 2;
bytes apiState = 3;
oneof data {
TenantProfileProto tenantProfile = 2;
DeviceProfileProto deviceProfile = 3;
}
ApiUsageStateProto apiState = 4;
}
message GetDeviceRequestMsg {
@ -382,6 +521,7 @@ message GetDeviceRequestMsg {
message GetDeviceResponseMsg {
int64 deviceProfileIdMSB = 1;
int64 deviceProfileIdLSB = 2;
//Json
bytes deviceTransportConfiguration = 3;
}
@ -391,7 +531,7 @@ message GetDeviceCredentialsRequestMsg {
}
message GetDeviceCredentialsResponseMsg {
bytes deviceCredentialsData = 1;
DeviceCredentialsProto deviceCredentialsData = 1;
}
message GetSnmpDevicesRequestMsg {
@ -405,8 +545,13 @@ message GetSnmpDevicesResponseMsg {
}
message EntityUpdateMsg {
string entityType = 1;
bytes data = 2;
oneof entityUpdate {
TenantProto tenant = 1;
TenantProfileProto tenantProfile = 2;
DeviceProto device = 3;
DeviceProfileProto deviceProfile = 4;
ApiUsageStateProto apiUsageState = 5;
}
}
message EntityDeleteMsg {
@ -494,11 +639,14 @@ message ClaimDeviceMsg {
}
message DeviceCredentialsProto {
int64 deviceIdMSB = 1;
int64 deviceIdLSB = 2;
CredentialsType credentialsType = 3;
string credentialsId = 4;
optional string credentialsValue = 5;
int64 credentialsIdMSB = 1;
int64 credentialsIdLSB = 2;
int64 createdTime = 3;
int64 deviceIdMSB = 4;
int64 deviceIdLSB = 5;
CredentialsType credentialsType = 6;
string credentialsId = 7;
optional string credentialsValue = 8;
}
message CredentialsDataProto {
@ -1194,7 +1342,7 @@ message ToVersionControlServiceMsg {
int64 tenantIdLSB = 3;
int64 requestIdMSB = 4;
int64 requestIdLSB = 5;
bytes vcSettings = 6;
RepositorySettingsProto vcSettings = 6;
GenericRepositoryRequestMsg initRepositoryRequest = 7;
GenericRepositoryRequestMsg testRepositoryRequest = 8;
GenericRepositoryRequestMsg clearRepositoryRequest = 9;
@ -1278,21 +1426,17 @@ message ToCoreMsg {
message ToCoreNotificationMsg {
LocalSubscriptionServiceMsgProto toLocalSubscriptionServiceMsg = 1;
FromDeviceRPCResponseProto fromDeviceRpcResponse = 2;
bytes componentLifecycleMsg = 3 [deprecated = true];
bytes edgeEventUpdateMsg = 4 [deprecated = true];
QueueUpdateMsg queueUpdateMsg = 5;
QueueDeleteMsg queueDeleteMsg = 6;
VersionControlResponseMsg vcResponseMsg = 7;
bytes toEdgeSyncRequestMsg = 8 [deprecated = true];
bytes fromEdgeSyncResponseMsg = 9 [deprecated = true];
SubscriptionMgrMsgProto toSubscriptionMgrMsg = 10;
NotificationRuleProcessorMsg notificationRuleProcessorMsg = 11;
ComponentLifecycleMsgProto componentLifecycle = 12;
CoreStartupMsg coreStartupMsg = 13;
EdgeEventUpdateMsgProto edgeEventUpdate = 14;
ToEdgeSyncRequestMsgProto toEdgeSyncRequest = 15;
FromEdgeSyncResponseMsgProto fromEdgeSyncResponse = 16;
ResourceCacheInvalidateMsg resourceCacheInvalidateMsg = 17;
QueueUpdateMsg queueUpdateMsg = 3;
QueueDeleteMsg queueDeleteMsg = 4;
VersionControlResponseMsg vcResponseMsg = 5;
SubscriptionMgrMsgProto toSubscriptionMgrMsg = 6;
NotificationRuleProcessorMsg notificationRuleProcessorMsg = 7;
ComponentLifecycleMsgProto componentLifecycle = 8;
CoreStartupMsg coreStartupMsg = 9;
EdgeEventUpdateMsgProto edgeEventUpdate = 10;
ToEdgeSyncRequestMsgProto toEdgeSyncRequest = 11;
FromEdgeSyncResponseMsgProto fromEdgeSyncResponse = 12;
ResourceCacheInvalidateMsg resourceCacheInvalidateMsg = 13;
}
/* Messages that are handled by ThingsBoard RuleEngine Service */
@ -1305,7 +1449,6 @@ message ToRuleEngineMsg {
}
message ToRuleEngineNotificationMsg {
bytes componentLifecycleMsg = 1 [deprecated = true];
FromDeviceRPCResponseProto fromDeviceRpcResponse = 2;
QueueUpdateMsg queueUpdateMsg = 3;
QueueDeleteMsg queueDeleteMsg = 4;

82
common/proto/src/test/java/org/thingsboard/server/common/util/ProtoUtilsTest.java

@ -15,9 +15,25 @@
*/
package org.thingsboard.server.common.util;
import com.fasterxml.jackson.databind.JsonNode;
import org.jeasy.random.EasyRandom;
import org.jeasy.random.EasyRandomParameters;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.ApiUsageState;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration;
import org.thingsboard.server.common.data.device.data.DefaultDeviceTransportConfiguration;
import org.thingsboard.server.common.data.device.data.DeviceConfiguration;
import org.thingsboard.server.common.data.device.data.DeviceTransportConfiguration;
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
@ -34,6 +50,9 @@ import org.thingsboard.server.common.data.rpc.RpcError;
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.data.sync.vc.RepositorySettings;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileConfiguration;
import org.thingsboard.server.common.msg.edge.EdgeEventUpdateMsg;
import org.thingsboard.server.common.msg.edge.FromEdgeSyncResponse;
import org.thingsboard.server.common.msg.edge.ToEdgeSyncRequest;
@ -62,6 +81,19 @@ class ProtoUtilsTest {
DeviceId deviceId = new DeviceId(UUID.fromString("ceebb9e5-4239-437c-a507-dc5f71f1232d"));
EdgeId edgeId = new EdgeId(UUID.fromString("364be452-2183-459b-af93-1ddb325feac1"));
UUID id = UUID.fromString("31a07d85-6ed5-46f8-83c0-6715cb0a8782");
static EasyRandom easyRandom;
@BeforeAll
static void init() {
EasyRandomParameters parameters = new EasyRandomParameters()
.randomize(DeviceConfiguration.class, DefaultDeviceConfiguration::new)
.randomize(DeviceTransportConfiguration.class, DefaultDeviceTransportConfiguration::new)
.randomize(JsonNode.class, JacksonUtil::newObjectNode)
.randomize(DeviceProfileData.class, DeviceProfileData::new)
.randomize(TenantProfileConfiguration.class, DefaultTenantProfileConfiguration::new)
.randomize(EntityId.class, () -> new DeviceId(UUID.randomUUID()));
easyRandom = new EasyRandom(parameters);
}
@Test
void protoComponentLifecycleSerialization() {
@ -179,4 +211,54 @@ class ProtoUtilsTest {
Assertions.assertNotNull(serializedMsg);
assertThat(ProtoUtils.fromProto(serializedMsg)).as("deserialized").isEqualTo(msg);
}
private static final String description = "Failed to deserialize %s, because found some new fields which absent in %sProto!!!";
@Test
void protoSerializationDeserializationEntities() {
Device expectedDevice = easyRandom.nextObject(Device.class);
TransportProtos.DeviceProto deviceProto = ProtoUtils.toProto(expectedDevice);
Device actualDevice = ProtoUtils.fromProto(deviceProto);
assertEqualDeserializedEntity(expectedDevice, actualDevice, "Device");
DeviceCredentials expectedCredentials = easyRandom.nextObject(DeviceCredentials.class);
TransportProtos.DeviceCredentialsProto credentialsProto = ProtoUtils.toProto(expectedCredentials);
DeviceCredentials actualCredentials = ProtoUtils.fromProto(credentialsProto);
assertEqualDeserializedEntity(expectedCredentials, actualCredentials, "DeviceCredentials");
DeviceProfile expectedDeviceProfile = easyRandom.nextObject(DeviceProfile.class);
TransportProtos.DeviceProfileProto deviceProfileProto = ProtoUtils.toProto(expectedDeviceProfile);
DeviceProfile actualDeviceProfile = ProtoUtils.fromProto(deviceProfileProto);
assertEqualDeserializedEntity(expectedDeviceProfile, actualDeviceProfile, "DeviceProfile");
Tenant expectedTenant = easyRandom.nextObject(Tenant.class);
TransportProtos.TenantProto tenantProto = ProtoUtils.toProto(expectedTenant);
Tenant actualTenant = ProtoUtils.fromProto(tenantProto);
assertEqualDeserializedEntity(expectedTenant, actualTenant, "Tenant");
TenantProfile expectedTenantProfile = easyRandom.nextObject(TenantProfile.class);
TransportProtos.TenantProfileProto tenantProfileProto = ProtoUtils.toProto(expectedTenantProfile);
TenantProfile actualTenantProfile = ProtoUtils.fromProto(tenantProfileProto);
assertEqualDeserializedEntity(expectedTenantProfile, actualTenantProfile, "TenantProfile");
TbResource expectedResource = easyRandom.nextObject(TbResource.class);
TransportProtos.TbResourceProto resourceProto = ProtoUtils.toProto(expectedResource);
TbResource actualResource = ProtoUtils.fromProto(resourceProto);
assertEqualDeserializedEntity(expectedResource, actualResource, "TbResource");
ApiUsageState expectedState = easyRandom.nextObject(ApiUsageState.class);
TransportProtos.ApiUsageStateProto stateProto = ProtoUtils.toProto(expectedState);
ApiUsageState actualState = ProtoUtils.fromProto(stateProto);
assertEqualDeserializedEntity(expectedState, actualState, "ApiUsageState");
RepositorySettings expectedSettings = easyRandom.nextObject(RepositorySettings.class);
TransportProtos.RepositorySettingsProto settingsProto = ProtoUtils.toProto(expectedSettings);
RepositorySettings actualSettings = ProtoUtils.fromProto(settingsProto);
assertEqualDeserializedEntity(expectedSettings, actualSettings, "RepositorySettings");
}
private void assertEqualDeserializedEntity(Object expected, Object actual, String entityName) {
assertThat(actual).as(String.format(description, entityName, entityName)).isEqualTo(expected);
}
}

7
common/queue/src/main/java/org/thingsboard/server/queue/notification/RemoteNotificationRuleProcessor.java

@ -20,16 +20,16 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.JavaSerDesUtil;
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTrigger;
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.TopicService;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TopicService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import java.util.UUID;
@ -43,7 +43,6 @@ public class RemoteNotificationRuleProcessor implements NotificationRuleProcesso
private final TbQueueProducerProvider producerProvider;
private final TopicService topicService;
private final PartitionService partitionService;
private final DataDecodingEncodingService encodingService;
@Override
public void process(NotificationRuleTrigger trigger) {
@ -54,7 +53,7 @@ public class RemoteNotificationRuleProcessor implements NotificationRuleProcesso
log.debug("Submitting notification rule trigger: {}", trigger);
TransportProtos.NotificationRuleProcessorMsg.Builder msg = TransportProtos.NotificationRuleProcessorMsg.newBuilder()
.setTrigger(ByteString.copyFrom(encodingService.encode(trigger)));
.setTrigger(ByteString.copyFrom(JavaSerDesUtil.encode(trigger)));
partitionService.getAllServiceIds(ServiceType.TB_CORE).stream().findAny().ifPresent(serviceId -> {
TopicPartitionInfo tpi = topicService.getNotificationsTopic(ServiceType.TB_CORE, serviceId);

27
common/queue/src/main/java/org/thingsboard/server/queue/util/DataDecodingEncodingService.java

@ -1,27 +0,0 @@
/**
* Copyright © 2016-2023 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.queue.util;
import java.util.Optional;
public interface DataDecodingEncodingService {
<T> Optional<T> decode(byte[] byteArray);
<T> byte[] encode(T msq);
}

52
common/queue/src/main/java/org/thingsboard/server/queue/util/JavaDataDecodingEncodingService.java

@ -1,52 +0,0 @@
/**
* Copyright © 2016-2023 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.queue.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.FstStatsService;
import org.thingsboard.server.common.data.JavaSerDesUtil;
import java.util.Optional;
@Slf4j
@Service
public class JavaDataDecodingEncodingService implements DataDecodingEncodingService {
@Autowired
private FstStatsService fstStatsService;
@Override
public <T> Optional<T> decode(byte[] byteArray) {
long startTime = System.nanoTime();
Optional<T> optional = Optional.ofNullable(JavaSerDesUtil.decode(byteArray));
optional.ifPresent(obj -> {
fstStatsService.recordDecodeTime(obj.getClass(), startTime);
fstStatsService.incrementDecode(obj.getClass());
});
return optional;
}
@Override
public <T> byte[] encode(T msq) {
long startTime = System.nanoTime();
var bytes = JavaSerDesUtil.encode(msq);
fstStatsService.recordEncodeTime(msq.getClass(), startTime);
fstStatsService.incrementEncode(msq.getClass());
return bytes;
}
}

16
common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/ProtoTransportEntityService.java

@ -17,6 +17,7 @@ package org.thingsboard.server.transport.snmp.service;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.device.data.DeviceData;
import org.thingsboard.server.common.data.device.data.DeviceTransportConfiguration;
@ -24,8 +25,8 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbSnmpTransportComponent;
import java.util.UUID;
@ -35,7 +36,6 @@ import java.util.UUID;
@RequiredArgsConstructor
public class ProtoTransportEntityService {
private final TransportService transportService;
private final DataDecodingEncodingService dataDecodingEncodingService;
public Device getDeviceById(DeviceId id) {
TransportProtos.GetDeviceResponseMsg deviceProto = transportService.getDevice(TransportProtos.GetDeviceRequestMsg.newBuilder()
@ -55,9 +55,8 @@ public class ProtoTransportEntityService {
device.setId(id);
device.setDeviceProfileId(deviceProfileId);
DeviceTransportConfiguration deviceTransportConfiguration = (DeviceTransportConfiguration) dataDecodingEncodingService.decode(
deviceProto.getDeviceTransportConfiguration().toByteArray()
).orElseThrow(() -> new IllegalStateException("Can't find device transport configuration"));
DeviceTransportConfiguration deviceTransportConfiguration = JacksonUtil.fromBytes(
deviceProto.getDeviceTransportConfiguration().toByteArray(), DeviceTransportConfiguration.class);
DeviceData deviceData = new DeviceData();
deviceData.setTransportConfiguration(deviceTransportConfiguration);
@ -74,8 +73,11 @@ public class ProtoTransportEntityService {
.build()
);
return (DeviceCredentials) dataDecodingEncodingService.decode(deviceCredentialsResponse.getDeviceCredentialsData().toByteArray())
.orElseThrow(() -> new IllegalArgumentException("Device credentials not found"));
if (deviceCredentialsResponse.hasDeviceCredentialsData()) {
return ProtoUtils.fromProto(deviceCredentialsResponse.getDeviceCredentialsData());
} else {
throw new IllegalArgumentException("Device credentials not found");
}
}
public TransportProtos.GetSnmpDevicesResponseMsg getSnmpDevicesIds(int page, int pageSize) {

6
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportDeviceProfileCache.java

@ -15,19 +15,19 @@
*/
package org.thingsboard.server.common.transport;
import com.google.protobuf.ByteString;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.gen.transport.TransportProtos;
public interface TransportDeviceProfileCache {
DeviceProfile getOrCreate(DeviceProfileId id, ByteString profileBody);
DeviceProfile getOrCreate(DeviceProfileId id, TransportProtos.DeviceProfileProto proto);
DeviceProfile get(DeviceProfileId id);
void put(DeviceProfile profile);
DeviceProfile put(ByteString profileBody);
DeviceProfile put(TransportProtos.DeviceProfileProto proto);
void evict(DeviceProfileId id);

4
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportTenantProfileCache.java

@ -15,11 +15,11 @@
*/
package org.thingsboard.server.common.transport;
import com.google.protobuf.ByteString;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.transport.profile.TenantProfileUpdateResult;
import org.thingsboard.server.gen.transport.TransportProtos;
import java.util.Set;
@ -27,7 +27,7 @@ public interface TransportTenantProfileCache {
TenantProfile get(TenantId tenantId);
TenantProfileUpdateResult put(ByteString profileBody);
TenantProfileUpdateResult put(TransportProtos.TenantProfileProto proto);
boolean put(TenantId tenantId, TenantProfileId profileId);

40
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportDeviceProfileCache.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.common.transport.service;
import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@ -25,11 +24,10 @@ import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.transport.TransportDeviceProfileCache;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbTransportComponent;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
@ -42,7 +40,6 @@ public class DefaultTransportDeviceProfileCache implements TransportDeviceProfil
private final Lock deviceProfileFetchLock = new ReentrantLock();
private final ConcurrentMap<DeviceProfileId, DeviceProfile> deviceProfiles = new ConcurrentHashMap<>();
private final DataDecodingEncodingService dataDecodingEncodingService;
private TransportService transportService;
@ -52,19 +49,12 @@ public class DefaultTransportDeviceProfileCache implements TransportDeviceProfil
this.transportService = transportService;
}
public DefaultTransportDeviceProfileCache(DataDecodingEncodingService dataDecodingEncodingService) {
this.dataDecodingEncodingService = dataDecodingEncodingService;
}
@Override
public DeviceProfile getOrCreate(DeviceProfileId id, ByteString profileBody) {
public DeviceProfile getOrCreate(DeviceProfileId id, TransportProtos.DeviceProfileProto proto) {
DeviceProfile profile = deviceProfiles.get(id);
if (profile == null) {
Optional<DeviceProfile> deviceProfile = dataDecodingEncodingService.decode(profileBody.toByteArray());
if (deviceProfile.isPresent()) {
profile = deviceProfile.get();
deviceProfiles.put(id, profile);
}
profile = ProtoUtils.fromProto(proto);
deviceProfiles.put(id, profile);
}
return profile;
}
@ -80,14 +70,10 @@ public class DefaultTransportDeviceProfileCache implements TransportDeviceProfil
}
@Override
public DeviceProfile put(ByteString profileBody) {
Optional<DeviceProfile> deviceProfile = dataDecodingEncodingService.decode(profileBody.toByteArray());
if (deviceProfile.isPresent()) {
put(deviceProfile.get());
return deviceProfile.get();
} else {
return null;
}
public DeviceProfile put(TransportProtos.DeviceProfileProto proto) {
DeviceProfile deviceProfile = ProtoUtils.fromProto(proto);
put(deviceProfile);
return deviceProfile;
}
@Override
@ -107,14 +93,8 @@ public class DefaultTransportDeviceProfileCache implements TransportDeviceProfil
.setEntityIdLSB(id.getId().getLeastSignificantBits())
.build();
TransportProtos.GetEntityProfileResponseMsg entityProfileMsg = transportService.getEntityProfile(msg);
Optional<DeviceProfile> profileOpt = dataDecodingEncodingService.decode(entityProfileMsg.getData().toByteArray());
if (profileOpt.isPresent()) {
profile = profileOpt.get();
this.put(profile);
} else {
log.warn("[{}] Can't find device profile: {}", id, entityProfileMsg.getData());
throw new RuntimeException("Can't find device profile!");
}
profile = ProtoUtils.fromProto(entityProfileMsg.getDeviceProfile());
this.put(profile);
} finally {
deviceProfileFetchLock.unlock();
}

16
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportResourceCache.java

@ -16,6 +16,7 @@
package org.thingsboard.server.common.transport.service;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@ -24,8 +25,8 @@ import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.transport.TransportResourceCache;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbTransportComponent;
import java.util.Optional;
@ -39,19 +40,15 @@ import java.util.concurrent.locks.ReentrantLock;
@Slf4j
@Component
@TbTransportComponent
@RequiredArgsConstructor
public class DefaultTransportResourceCache implements TransportResourceCache {
private final Lock resourceFetchLock = new ReentrantLock();
private final ConcurrentMap<ResourceCompositeKey, TbResource> resources = new ConcurrentHashMap<>();
private final Set<ResourceCompositeKey> keys = ConcurrentHashMap.newKeySet();
private final DataDecodingEncodingService dataDecodingEncodingService;
@Lazy
private final TransportService transportService;
public DefaultTransportResourceCache(DataDecodingEncodingService dataDecodingEncodingService, @Lazy TransportService transportService) {
this.dataDecodingEncodingService = dataDecodingEncodingService;
this.transportService = transportService;
}
@Override
public Optional<TbResource> get(TenantId tenantId, ResourceType resourceType, String resourceKey) {
ResourceCompositeKey compositeKey = new ResourceCompositeKey(tenantId, resourceType, resourceKey);
@ -92,9 +89,8 @@ public class DefaultTransportResourceCache implements TransportResourceCache {
.setResourceKey(compositeKey.resourceKey);
TransportProtos.GetResourceResponseMsg responseMsg = transportService.getResource(builder.build());
Optional<TbResource> optionalResource = dataDecodingEncodingService.decode(responseMsg.getResource().toByteArray());
if (optionalResource.isPresent()) {
TbResource resource = optionalResource.get();
if (responseMsg.hasResource()) {
TbResource resource = ProtoUtils.fromProto(responseMsg.getResource());
resources.put(new ResourceCompositeKey(resource.getTenantId(), resource.getResourceType(), resource.getResourceKey()), resource);
return resource;
}

91
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java

@ -20,7 +20,6 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -50,9 +49,9 @@ import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.TenantProfileId;
import org.thingsboard.server.common.data.limit.LimitedApi;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.notification.rule.trigger.RateLimitsTrigger;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.msg.TbMsgType;
import org.thingsboard.server.common.data.rpc.RpcStatus;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -80,6 +79,7 @@ import org.thingsboard.server.common.transport.limits.EntityLimitKey;
import org.thingsboard.server.common.transport.limits.EntityLimitsCache;
import org.thingsboard.server.common.transport.limits.TransportRateLimitService;
import org.thingsboard.server.common.transport.util.JsonUtils;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg;
@ -96,14 +96,13 @@ import org.thingsboard.server.queue.TbQueueProducer;
import org.thingsboard.server.queue.TbQueueRequestTemplate;
import org.thingsboard.server.queue.common.AsyncCallbackTemplate;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.TopicService;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.discovery.TopicService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.provider.TbTransportQueueFactory;
import org.thingsboard.server.queue.scheduler.SchedulerComponent;
import org.thingsboard.server.queue.util.AfterStartUp;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbTransportComponent;
import jakarta.annotation.PostConstruct;
@ -163,7 +162,6 @@ public class DefaultTransportService implements TransportService {
@Value("${transport.stats.enabled:false}")
private boolean statsEnabled;
@Autowired
@Lazy
private TbApiUsageReportClient apiUsageClient;
@ -181,7 +179,6 @@ public class DefaultTransportService implements TransportService {
private final TransportTenantProfileCache tenantProfileCache;
private final TransportRateLimitService rateLimitService;
private final DataDecodingEncodingService dataDecodingEncodingService;
private final SchedulerComponent scheduler;
private final ApplicationEventPublisher eventPublisher;
private final TransportResourceCache transportResourceCache;
@ -216,7 +213,7 @@ public class DefaultTransportService implements TransportService {
TransportDeviceProfileCache deviceProfileCache,
TransportTenantProfileCache tenantProfileCache,
TransportRateLimitService rateLimitService,
DataDecodingEncodingService dataDecodingEncodingService, SchedulerComponent scheduler, TransportResourceCache transportResourceCache,
SchedulerComponent scheduler, TransportResourceCache transportResourceCache,
ApplicationEventPublisher eventPublisher, NotificationRuleProcessor notificationRuleProcessor,
EntityLimitsCache entityLimitsCache) {
this.partitionService = partitionService;
@ -228,7 +225,6 @@ public class DefaultTransportService implements TransportService {
this.deviceProfileCache = deviceProfileCache;
this.tenantProfileCache = tenantProfileCache;
this.rateLimitService = rateLimitService;
this.dataDecodingEncodingService = dataDecodingEncodingService;
this.scheduler = scheduler;
this.transportResourceCache = transportResourceCache;
this.eventPublisher = eventPublisher;
@ -430,9 +426,8 @@ public class DefaultTransportService implements TransportService {
result.credentials(msg.getCredentialsBody());
TransportDeviceInfo tdi = getTransportDeviceInfo(msg.getDeviceInfo());
result.deviceInfo(tdi);
ByteString profileBody = msg.getProfileBody();
if (!profileBody.isEmpty()) {
DeviceProfile profile = deviceProfileCache.getOrCreate(tdi.getDeviceProfileId(), profileBody);
if (msg.hasDeviceProfile()) {
DeviceProfile profile = deviceProfileCache.getOrCreate(tdi.getDeviceProfileId(), msg.getDeviceProfile());
result.deviceProfile(profile);
}
}
@ -464,9 +459,8 @@ public class DefaultTransportService implements TransportService {
result.credentials(msg.getCredentialsBody());
TransportDeviceInfo tdi = getTransportDeviceInfo(msg.getDeviceInfo());
result.deviceInfo(tdi);
ByteString profileBody = msg.getProfileBody();
if (!profileBody.isEmpty()) {
DeviceProfile profile = deviceProfileCache.getOrCreate(tdi.getDeviceProfileId(), profileBody);
if (msg.hasDeviceProfile()) {
DeviceProfile profile = deviceProfileCache.getOrCreate(tdi.getDeviceProfileId(), msg.getDeviceProfile());
if (transportType != DeviceTransportType.DEFAULT
&& profile != null && profile.getTransportType() != DeviceTransportType.DEFAULT && profile.getTransportType() != transportType) {
log.debug("[{}] Device profile [{}] has different transport type: {}, expected: {}", tdi.getDeviceId(), tdi.getDeviceProfileId(), profile.getTransportType(), transportType);
@ -480,7 +474,6 @@ public class DefaultTransportService implements TransportService {
AsyncCallbackTemplate.withCallback(response, callback::onSuccess, callback::onError, transportCallbackExecutor);
}
@Override
public void process(TenantId tenantId, TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg requestMsg, TransportServiceCallback<GetOrCreateDeviceFromGatewayResponse> callback) {
TbProtoQueueMsg<TransportApiRequestMsg> protoMsg = new TbProtoQueueMsg<>(UUID.randomUUID(), TransportApiRequestMsg.newBuilder().setGetOrCreateDeviceRequestMsg(requestMsg).build());
@ -495,9 +488,8 @@ public class DefaultTransportService implements TransportService {
if (msg.hasDeviceInfo()) {
TransportDeviceInfo tdi = getTransportDeviceInfo(msg.getDeviceInfo());
result.deviceInfo(tdi);
ByteString profileBody = msg.getProfileBody();
if (!profileBody.isEmpty()) {
result.deviceProfile(deviceProfileCache.getOrCreate(tdi.getDeviceProfileId(), profileBody));
if (msg.hasDeviceProfile()) {
result.deviceProfile(deviceProfileCache.getOrCreate(tdi.getDeviceProfileId(), msg.getDeviceProfile()));
}
} else if (TransportProtos.TransportApiRequestErrorCode.ENTITY_LIMIT.equals(msg.getError())) {
entityLimitsCache.put(key, true);
@ -987,37 +979,7 @@ public class DefaultTransportService implements TransportService {
} else {
log.trace("Processing broadcast notification: {}", toSessionMsg);
if (toSessionMsg.hasEntityUpdateMsg()) {
TransportProtos.EntityUpdateMsg msg = toSessionMsg.getEntityUpdateMsg();
EntityType entityType = EntityType.valueOf(msg.getEntityType());
if (EntityType.DEVICE_PROFILE.equals(entityType)) {
DeviceProfile deviceProfile = deviceProfileCache.put(msg.getData());
if (deviceProfile != null) {
log.debug("On device profile update: {}", deviceProfile);
onProfileUpdate(deviceProfile);
}
} else if (EntityType.TENANT_PROFILE.equals(entityType)) {
rateLimitService.update(tenantProfileCache.put(msg.getData()));
} else if (EntityType.TENANT.equals(entityType)) {
Optional<Tenant> profileOpt = dataDecodingEncodingService.decode(msg.getData().toByteArray());
if (profileOpt.isPresent()) {
Tenant tenant = profileOpt.get();
partitionService.removeTenant(tenant.getId());
boolean updated = tenantProfileCache.put(tenant.getId(), tenant.getTenantProfileId());
if (updated) {
rateLimitService.update(tenant.getId());
}
}
} else if (EntityType.API_USAGE_STATE.equals(entityType)) {
Optional<ApiUsageState> stateOpt = dataDecodingEncodingService.decode(msg.getData().toByteArray());
if (stateOpt.isPresent()) {
ApiUsageState apiUsageState = stateOpt.get();
rateLimitService.update(apiUsageState.getTenantId(), apiUsageState.isTransportEnabled());
//TODO: if transport is disabled, we should close all sessions and not to check credentials.
}
} else if (EntityType.DEVICE.equals(entityType)) {
Optional<Device> deviceOpt = dataDecodingEncodingService.decode(msg.getData().toByteArray());
deviceOpt.ifPresent(this::onDeviceUpdate);
}
onEntityUpdate(toSessionMsg.getEntityUpdateMsg());
} else if (toSessionMsg.hasEntityDeleteMsg()) {
TransportProtos.EntityDeleteMsg msg = toSessionMsg.getEntityDeleteMsg();
EntityType entityType = EntityType.valueOf(msg.getEntityType());
@ -1086,6 +1048,37 @@ public class DefaultTransportService implements TransportService {
eventPublisher.publishEvent(new DeviceProfileUpdatedEvent(deviceProfile));
}
private void onEntityUpdate(TransportProtos.EntityUpdateMsg msg) {
switch (msg.getEntityUpdateCase()) {
case DEVICEPROFILE:
DeviceProfile deviceProfile = deviceProfileCache.put(msg.getDeviceProfile());
log.debug("On device profile update: {}", deviceProfile);
onProfileUpdate(deviceProfile);
break;
case TENANTPROFILE:
rateLimitService.update(tenantProfileCache.put(msg.getTenantProfile()));
break;
case TENANT:
Tenant tenant = ProtoUtils.fromProto(msg.getTenant());
partitionService.removeTenant(tenant.getId());
boolean updated = tenantProfileCache.put(tenant.getId(), tenant.getTenantProfileId());
if (updated) {
rateLimitService.update(tenant.getId());
}
break;
case APIUSAGESTATE:
ApiUsageState apiUsageState = ProtoUtils.fromProto(msg.getApiUsageState());
rateLimitService.update(apiUsageState.getTenantId(), apiUsageState.isTransportEnabled());
//TODO: if transport is disabled, we should close all sessions and not to check credentials.
break;
case DEVICE:
onDeviceUpdate(ProtoUtils.fromProto(msg.getDevice()));
break;
default:
log.warn("UNKNOWN entity update type: [{}]", msg.getEntityUpdateCase());
}
}
private void onDeviceUpdate(Device device) {
long deviceIdMSB = device.getId().getId().getMostSignificantBits();
long deviceIdLSB = device.getId().getId().getLeastSignificantBits();

51
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportTenantProfileCache.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.common.transport.service;
import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@ -29,12 +28,11 @@ import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.TransportTenantProfileCache;
import org.thingsboard.server.common.transport.limits.TransportRateLimitService;
import org.thingsboard.server.common.transport.profile.TenantProfileUpdateResult;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbTransportComponent;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -50,7 +48,6 @@ public class DefaultTransportTenantProfileCache implements TransportTenantProfil
private final ConcurrentMap<TenantProfileId, TenantProfile> profiles = new ConcurrentHashMap<>();
private final ConcurrentMap<TenantId, TenantProfileId> tenantIds = new ConcurrentHashMap<>();
private final ConcurrentMap<TenantProfileId, Set<TenantId>> tenantProfileIds = new ConcurrentHashMap<>();
private final DataDecodingEncodingService dataDecodingEncodingService;
private TransportRateLimitService rateLimitService;
private TransportService transportService;
@ -67,28 +64,18 @@ public class DefaultTransportTenantProfileCache implements TransportTenantProfil
this.transportService = transportService;
}
public DefaultTransportTenantProfileCache(DataDecodingEncodingService dataDecodingEncodingService) {
this.dataDecodingEncodingService = dataDecodingEncodingService;
}
@Override
public TenantProfile get(TenantId tenantId) {
return getTenantProfile(tenantId);
}
@Override
public TenantProfileUpdateResult put(ByteString profileBody) {
Optional<TenantProfile> profileOpt = dataDecodingEncodingService.decode(profileBody.toByteArray());
if (profileOpt.isPresent()) {
TenantProfile newProfile = profileOpt.get();
log.trace("[{}] put: {}", newProfile.getId(), newProfile);
profiles.put(newProfile.getId(), newProfile);
Set<TenantId> affectedTenants = tenantProfileIds.get(newProfile.getId());
return new TenantProfileUpdateResult(newProfile, affectedTenants != null ? affectedTenants : Collections.emptySet());
} else {
log.warn("Failed to decode profile: {}", profileBody.toString());
return new TenantProfileUpdateResult(null, Collections.emptySet());
}
public TenantProfileUpdateResult put(TransportProtos.TenantProfileProto proto) {
TenantProfile profile = ProtoUtils.fromProto(proto);
log.trace("[{}] put: {}", profile.getId(), profile);
profiles.put(profile.getId(), profile);
Set<TenantId> affectedTenants = tenantProfileIds.get(profile.getId());
return new TenantProfileUpdateResult(profile, affectedTenants != null ? affectedTenants : Collections.emptySet());
}
@Override
@ -135,23 +122,17 @@ public class DefaultTransportTenantProfileCache implements TransportTenantProfil
.setEntityIdLSB(tenantId.getId().getLeastSignificantBits())
.build();
TransportProtos.GetEntityProfileResponseMsg entityProfileMsg = transportService.getEntityProfile(msg);
Optional<TenantProfile> profileOpt = dataDecodingEncodingService.decode(entityProfileMsg.getData().toByteArray());
if (profileOpt.isPresent()) {
profile = profileOpt.get();
TenantProfile existingProfile = profiles.get(profile.getId());
if (existingProfile != null) {
profile = existingProfile;
} else {
profiles.put(profile.getId(), profile);
}
tenantProfileIds.computeIfAbsent(profile.getId(), id -> ConcurrentHashMap.newKeySet()).add(tenantId);
tenantIds.put(tenantId, profile.getId());
profile = ProtoUtils.fromProto(entityProfileMsg.getTenantProfile());
TenantProfile existingProfile = profiles.get(profile.getId());
if (existingProfile != null) {
profile = existingProfile;
} else {
log.warn("[{}] Can't decode tenant profile: {}", tenantId, entityProfileMsg.getData());
throw new RuntimeException("Can't decode tenant profile!");
profiles.put(profile.getId(), profile);
}
Optional<ApiUsageState> apiStateOpt = dataDecodingEncodingService.decode(entityProfileMsg.getApiState().toByteArray());
apiStateOpt.ifPresent(apiUsageState -> rateLimitService.update(tenantId, apiUsageState.isTransportEnabled()));
tenantProfileIds.computeIfAbsent(profile.getId(), id -> ConcurrentHashMap.newKeySet()).add(tenantId);
tenantIds.put(tenantId, profile.getId());
ApiUsageState apiUsageState = ProtoUtils.fromProto(entityProfileMsg.getApiState());
rateLimitService.update(tenantId, apiUsageState.isTransportEnabled());
}
} finally {
tenantProfileFetchLock.unlock();

8
common/util/src/main/java/org/thingsboard/common/util/JacksonUtil.java

@ -126,6 +126,14 @@ public class JacksonUtil {
}
}
public static <T> T fromBytes(byte[] bytes, TypeReference<T> valueTypeRef) {
try {
return bytes != null ? OBJECT_MAPPER.readValue(bytes, valueTypeRef) : null;
} catch (IOException e) {
throw new IllegalArgumentException("The given string value cannot be transformed to Json object: " + Arrays.toString(bytes), e);
}
}
public static JsonNode fromBytes(byte[] bytes) {
try {
return OBJECT_MAPPER.readTree(bytes);

18
common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java

@ -37,12 +37,12 @@ import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.SortOrder;
import org.thingsboard.server.common.data.sync.vc.RepositorySettings;
import org.thingsboard.server.common.data.sync.vc.VersionCreationResult;
import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo;
import org.thingsboard.server.common.data.util.CollectionsUtil;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.AddMsg;
import org.thingsboard.server.gen.transport.TransportProtos.BranchInfoProto;
@ -68,13 +68,12 @@ import org.thingsboard.server.gen.transport.TransportProtos.VersionedEntityInfoP
import org.thingsboard.server.queue.TbQueueConsumer;
import org.thingsboard.server.queue.TbQueueProducer;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.TopicService;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbApplicationEventListener;
import org.thingsboard.server.queue.discovery.TopicService;
import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.provider.TbVersionControlQueueFactory;
import org.thingsboard.server.queue.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbVersionControlComponent;
import jakarta.annotation.PostConstruct;
@ -109,7 +108,6 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
private final PartitionService partitionService;
private final TbQueueProducerProvider producerProvider;
private final TbVersionControlQueueFactory queueFactory;
private final DataDecodingEncodingService encodingService;
private final GitRepositoryService vcService;
private final TopicService topicService;
@ -197,7 +195,7 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
}
for (TbProtoQueueMsg<ToVersionControlServiceMsg> msgWrapper : msgs) {
ToVersionControlServiceMsg msg = msgWrapper.getValue();
var ctx = new VersionControlRequestCtx(msg, msg.hasClearRepositoryRequest() ? null : getEntitiesVersionControlSettings(msg));
var ctx = new VersionControlRequestCtx(msg, msg.hasClearRepositoryRequest() ? null : ProtoUtils.fromProto(msg.getVcSettings()));
long startTs = System.currentTimeMillis();
log.trace("[{}][{}] RECEIVED task: {}", ctx.getTenantId(), ctx.getRequestId(), msg);
int threadIdx = Math.abs(ctx.getTenantId().hashCode() % ioPoolSize);
@ -553,16 +551,6 @@ public class DefaultClusterVersionControlService extends TbApplicationEventListe
producer.send(tpi, new TbProtoQueueMsg<>(UUID.randomUUID(), msg), null);
}
private RepositorySettings getEntitiesVersionControlSettings(ToVersionControlServiceMsg msg) {
Optional<RepositorySettings> settingsOpt = encodingService.decode(msg.getVcSettings().toByteArray());
if (settingsOpt.isPresent()) {
return settingsOpt.get();
} else {
log.warn("Failed to parse VC settings: {}", msg.getVcSettings());
throw new RuntimeException("Failed to parse vc settings!");
}
}
private String getRelativePath(EntityType entityType, String entityId) {
String path = entityType.name().toLowerCase();
if (entityId != null) {

5
dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmTypesRedisCache.java

@ -15,13 +15,14 @@
*/
package org.thingsboard.server.dao.alarm;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.connection.RedisConnectionFactory;
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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbTypedJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.id.TenantId;
@ -32,6 +33,6 @@ import org.thingsboard.server.common.data.page.PageData;
public class AlarmTypesRedisCache extends RedisTbTransactionalCache<TenantId, PageData<EntitySubtype>> {
public AlarmTypesRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.ALARM_TYPES_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.ALARM_TYPES_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbTypedJsonRedisSerializer<>(new TypeReference<>() {}));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.asset.AssetProfile;
@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.asset.AssetProfile;
public class AssetProfileRedisCache extends RedisTbTransactionalCache<AssetProfileCacheKey, AssetProfile> {
public AssetProfileRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.ASSET_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.ASSET_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(AssetProfile.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/asset/AssetRedisCache.java

@ -21,15 +21,15 @@ 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.common.data.CacheConstants;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.cache.TbJavaRedisSerializer;
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis")
@Service("AssetCache")
public class AssetRedisCache extends RedisTbTransactionalCache<AssetCacheKey, Asset> {
public AssetRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.ASSET_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.ASSET_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(Asset.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardTitlesRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.id.DashboardId;
@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.id.DashboardId;
public class DashboardTitlesRedisCache extends RedisTbTransactionalCache<DashboardId, String> {
public DashboardTitlesRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.DASHBOARD_TITLES_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.DASHBOARD_TITLES_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(String.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.security.DeviceCredentials;
@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.security.DeviceCredentials;
public class DeviceCredentialsRedisCache extends RedisTbTransactionalCache<String, DeviceCredentials> {
public DeviceCredentialsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.DEVICE_CREDENTIALS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.DEVICE_CREDENTIALS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(DeviceCredentials.class));
}
}

22
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.TbJavaRedisSerializer;
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<DeviceProfileCacheKey, DeviceProfile> {
public DeviceProfileRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.DEVICE_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.DEVICE_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbRedisSerializer<DeviceProfileCacheKey, DeviceProfile>() {
@Override
public byte[] serialize(DeviceProfile deviceProfile) throws SerializationException {
return ProtoUtils.toProto(deviceProfile).toByteArray();
}
@Override
public DeviceProfile deserialize(DeviceProfileCacheKey key, byte[] bytes) throws SerializationException {
try {
return ProtoUtils.fromProto(TransportProtos.DeviceProfileProto.parseFrom(bytes));
} catch (InvalidProtocolBufferException e) {
throw new SerializationException(e.getMessage());
}
}
});
}
}

4
dao/src/main/java/org/thingsboard/server/dao/edge/EdgeRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.edge.Edge;
@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.edge.Edge;
public class EdgeRedisCache extends RedisTbTransactionalCache<EdgeCacheKey, Edge> {
public EdgeRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.EDGE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.EDGE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(Edge.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/entity/count/EntityCountRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.dao.entity.EntityCountCacheKey;
@ -30,6 +30,6 @@ import org.thingsboard.server.dao.entity.EntityCountCacheKey;
public class EntityCountRedisCache extends RedisTbTransactionalCache<EntityCountCacheKey, Long> {
public EntityCountRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.ENTITY_COUNT_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.ENTITY_COUNT_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(Long.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis")
@ -29,6 +29,6 @@ import org.thingsboard.server.common.data.CacheConstants;
public class EntityViewRedisCache extends RedisTbTransactionalCache<EntityViewCacheKey, EntityViewCacheValue> {
public EntityViewRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.ENTITY_VIEW_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.ENTITY_VIEW_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(EntityViewCacheValue.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.OtaPackageInfo;
@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.OtaPackageInfo;
public class OtaPackageRedisCache extends RedisTbTransactionalCache<OtaPackageCacheKey, OtaPackageInfo> {
public OtaPackageRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.OTA_PACKAGE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.OTA_PACKAGE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(OtaPackageInfo.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/relation/RelationRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis")
@ -29,6 +29,6 @@ import org.thingsboard.server.common.data.CacheConstants;
public class RelationRedisCache extends RedisTbTransactionalCache<RelationCacheKey, RelationCacheValue> {
public RelationRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.RELATIONS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.RELATIONS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(RelationCacheValue.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantExistsRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.id.TenantId;
@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.id.TenantId;
public class TenantExistsRedisCache extends RedisTbTransactionalCache<TenantId, Boolean> {
public TenantExistsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.TENANTS_EXIST_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.TENANTS_EXIST_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(Boolean.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.TenantProfile;
@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.TenantProfile;
public class TenantProfileRedisCache extends RedisTbTransactionalCache<TenantProfileCacheKey, TenantProfile> {
public TenantProfileRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.TENANT_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.TENANT_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(TenantProfile.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/tenant/TenantRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.TenantId;
@ -31,6 +31,6 @@ import org.thingsboard.server.common.data.id.TenantId;
public class TenantRedisCache extends RedisTbTransactionalCache<TenantId, Tenant> {
public TenantRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.TENANTS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.TENANTS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(Tenant.class));
}
}

4
dao/src/main/java/org/thingsboard/server/dao/user/UserSettingsRedisCache.java

@ -21,7 +21,7 @@ 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.TbJavaRedisSerializer;
import org.thingsboard.server.cache.TbJsonRedisSerializer;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.settings.UserSettings;
import org.thingsboard.server.common.data.settings.UserSettingsCompositeKey;
@ -31,6 +31,6 @@ import org.thingsboard.server.common.data.settings.UserSettingsCompositeKey;
public class UserSettingsRedisCache extends RedisTbTransactionalCache<UserSettingsCompositeKey, UserSettings> {
public UserSettingsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) {
super(CacheConstants.USER_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>());
super(CacheConstants.USER_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJsonRedisSerializer<>(UserSettings.class));
}
}

15
dao/src/test/java/org/thingsboard/server/dao/service/TenantProfileServiceTest.java

@ -24,7 +24,6 @@ import org.junit.jupiter.api.Assertions;
import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityInfo;
import org.thingsboard.server.common.data.JavaSerDesUtil;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.TenantProfile;
import org.thingsboard.server.common.data.id.TenantId;
@ -38,12 +37,15 @@ import org.thingsboard.server.common.data.queue.SubmitStrategyType;
import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
import org.thingsboard.server.common.data.tenant.profile.TenantProfileQueueConfiguration;
import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.tenant.TenantProfileService;
import org.thingsboard.server.gen.transport.TransportProtos;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
@ -300,19 +302,18 @@ public class TenantProfileServiceTest extends AbstractServiceTest {
}
@Test
public void testTenantProfileSerialization_fst() {
public void testTenantProfileSerialization_proto() {
TenantProfile tenantProfile = new TenantProfile();
tenantProfile.setId(new TenantProfileId(UUID.randomUUID()));
tenantProfile.setName("testProfile");
TenantProfileData profileData = new TenantProfileData();
tenantProfile.setProfileData(profileData);
profileData.setConfiguration(new DefaultTenantProfileConfiguration());
addMainQueueConfig(tenantProfile);
byte[] serialized = assertDoesNotThrow(() -> JavaSerDesUtil.encode(tenantProfile));
assertDoesNotThrow(() -> {
JavaSerDesUtil.encode(profileData);
});
byte[] serialized = assertDoesNotThrow(() -> ProtoUtils.toProto(tenantProfile).toByteArray());
TenantProfile deserialized = assertDoesNotThrow(() -> JavaSerDesUtil.decode(serialized));
TenantProfile deserialized = assertDoesNotThrow(() -> ProtoUtils.fromProto(TransportProtos.TenantProfileProto.parseFrom(serialized)));
assertThat(deserialized).isEqualTo(tenantProfile);
assertThat(deserialized.getProfileData()).isNotNull();
assertThat(deserialized.getProfileData().getQueueConfiguration()).isNotEmpty();

7
pom.xml

@ -139,6 +139,7 @@
<mock-server.version>5.15.0</mock-server.version>
<spring-test-dbunit.version>1.3.0</spring-test-dbunit.version> <!-- 2016 -->
<takari-cpsuite.version>1.2.7</takari-cpsuite.version> <!-- 2015 -->
<jeasy.version>5.0.0</jeasy.version>
<!-- BLACKBOX TEST SCOPE -->
<testng.version>7.6.1</testng.version>
<assertj.version>3.23.1</assertj.version>
@ -2036,6 +2037,12 @@
<version>${mock-server.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-random-core</artifactId>
<version>${jeasy.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.opensmpp</groupId>
<artifactId>opensmpp-core</artifactId>

Loading…
Cancel
Save